From: jkauttio Date: Fri, 14 Feb 2014 13:12:38 +0000 (+0000) Subject: development branch for vensim import X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=5832060bc3a3d679796ecda1af5ea451d4ab4670;p=simantics%2Fsysdyn.git development branch for vensim import refs #2924 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/branches@28849 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/.classpath b/dev-jkauttio/fi.semantum.sysdyn.solver/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/.project b/dev-jkauttio/fi.semantum.sysdyn.solver/.project new file mode 100644 index 00000000..f2296ceb --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/.project @@ -0,0 +1,28 @@ + + + fi.semantum.sysdyn.solver + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/fi.semantum.sysdyn.solver/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..f287d53c --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/META-INF/MANIFEST.MF b/dev-jkauttio/fi.semantum.sysdyn.solver/META-INF/MANIFEST.MF new file mode 100644 index 00000000..7f8fe97d --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Solver +Bundle-SymbolicName: fi.semantum.sysdyn.solver +Bundle-Version: 0.1.0.qualifier +Bundle-Activator: fi.semantum.sysdyn.solver.Activator +Bundle-Vendor: Semantum Oy +Require-Bundle: org.eclipse.core.runtime, + org.simantics.utils;bundle-version="1.1.0", + org.simantics.databoard;bundle-version="0.6.5" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: fi.semantum.sysdyn.solver diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/build.properties b/dev-jkauttio/fi.semantum.sysdyn.solver/build.properties new file mode 100644 index 00000000..4bc054f9 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/build.properties @@ -0,0 +1,14 @@ +############################################################################### +# Copyright (c) 2013 Semantum Oy. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Semantum Oy - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Activator.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Activator.java new file mode 100644 index 00000000..e7847139 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Activator.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Addition.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Addition.java new file mode 100644 index 00000000..abf31cb4 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Addition.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class Addition implements IExpression { + + public IExpression exp1; + public IExpression exp2; + + public Addition(IExpression exp1, IExpression exp2) { + this.exp1 = exp1; + this.exp2 = exp2; + } + + @Override + public String toString() { + return exp1 + " + " + exp2; + } + + @Override + public Object evaluate(IEnvironment environment) { + Double d1 = (Double)exp1.evaluate(environment); + Double d2 = (Double)exp2.evaluate(environment); + return d1 + d2; + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/And.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/And.java new file mode 100644 index 00000000..0ed114b9 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/And.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +import java.util.ArrayList; + +public class And implements IExpression { + + public ArrayList exps; + + public And(ArrayList exps) { + this.exps = exps; + } + + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append(exps.get(0)); + for(int i=1;i elements = new ArrayList(); + + public Array() { + + } + + public void addElement(Object element) { + if(element instanceof Constant) addElement(((Constant)element).value); + else elements.add(element); + } + + public void setElement(int index, Object element) { + elements.set(index, element); + } + + @Override + public Object evaluate(IEnvironment environment) { + return evaluated(environment); + } + + public Array evaluated(IEnvironment environment) { + Array result = new Array(); + for(Object o : elements) { + if(o instanceof Array) { + result.addElement(((Array)o).evaluated(environment)); + } else { + if(o instanceof IExpression) { + IExpression exp = (IExpression)o; + result.addElement(exp.evaluate(environment)); + } else { + result.addElement(o); + } + } + } + return result; + } + + @Override + public String toString() { + return elements.toString(); + } + + public int size(int col) { + return elements.size(); + } + + public Object element(int index) { + return elements.get(index); + } + + public Collection elements() { + return elements; + } + + public void ensureIndex(int index, boolean subArray) { + int needed = (index+1-elements.size()); + for(int i=0;i> history = new HashMap>(); + + public Environment(Model model, double step, double start) { + this.model = model; + this.step = step; + this.time = start; + + model.functions.put("size", new Fn1() { + + @Override + public Object evaluate(IEnvironment environment, int argc) { + Array array = (Array)environment.getValue(0); + Double col = (Double)environment.getValue(1); + return Double.valueOf(array.size(col.intValue())); + } + + }); + model.functions.put("zidz", new Fn1() { + + @Override + public Object evaluate(IEnvironment environment, int argc) { + Double p1 = (Double)environment.getValue(0); + Double p2 = (Double)environment.getValue(1); + if(Math.abs(p2) < 1e-12) return 0.0; + else return p1 / p2; + } + + }); + model.functions.put("xidz", new Fn1() { + + @Override + public Object evaluate(IEnvironment environment, int argc) { + Double p1 = (Double)environment.getValue(0); + Double p2 = (Double)environment.getValue(1); + Double x = (Double)environment.getValue(2); + if(Math.abs(p2) < 1e-12) return x; + else return p1 / p2; + } + + }); + model.functions.put("availabilityExternal", new Fn1() { + + @Override + public Object evaluate(IEnvironment environment, int argc) { + Double numberOfDays = (Double)environment.getValue(0); + Double numberOfDesigners = (Double)environment.getValue(1); + Double rseed = (Double)environment.getValue(2); + Array availability = (Array)environment.getValue(3); + Array result = new Array(); + for(int i=0;i result) result = d; + } + return result; + } + + }); + model.functions.put("integer", new Fn1() { + + @Override + public Object evaluate(IEnvironment environment, int argc) { + Object value = environment.getValue(0); + Double result = (Double)value; + double res = result.intValue(); + return res; + } + + }); + model.functions.put("delay", new Fn1() { + + @Override + public Object evaluate(IEnvironment _environment, int argc) { + + String ident = (String)_environment.getValue(0); + Double value = (Double)_environment.getValue(1); + Double p1 = (Double)_environment.getValue(2); + Double p2 = (Double)_environment.getValue(3); + + ISystem system = _environment.getSystem(); + + TreeMap history = system.getHistory(ident); + double time = system.time(); + + history.put(time, value); + + Double key = history.ceilingKey(time-p1); + + return history.get(key); + + } + + }); + } + + public TreeMap getHistory(String ident) { + TreeMap result = history.get(ident); + if(result == null) { + result = new TreeMap(); + history.put(ident, result); + } + return result; + } + + @Override + public Object getValue(int key) { + return valueTable[key]; + } + + @Override + public void put(int key, Object value) { + valueTable[key] = value; + } + + @Override + public int offset() { + return model.names.size(); + } + + @Override + public ISystem getSystem() { + return this; + } + + @Override + public boolean initial() { + return initial; + } + + public Object evaluateFunction(IEnvironment environment, String name, ArgumentList args) { + return model.evaluateFunction(environment, name, args); + } + + @Override + public double time() { + return time; + } + + // TODO: this is probably not smart at all, figure out a better way to obtain results + public HashMap getValueMap() { + HashMap values = new HashMap(); + + for (int i = 0; i < model.assignmentArray.length; i++) { + Variable v = model.assignmentArray[i].target; + values.put(v.toString(), (Double)getValue(v.index(this))); + } + + for (int i = 0; i < model.derivativeArray.length; i++) { + Variable v = model.derivativeArray[i].target; + values.put(v.toString(), (Double)getValue(v.index(this))); + } + + // NOTE: there is room for optimization as parameter values that do not + // change should only be obtained once (and parameter values that do + // change are (possibly) included in assignments or derivatives) + for (ParameterDeclaration p : model.parameters) { + Variable v = p.variable; + values.put(v.toString(), (Double)getValue(v.index(this))); + } + + return values; + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Equals.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Equals.java new file mode 100644 index 00000000..a27a8136 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Equals.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class Equals implements IExpression { + + public IExpression exp1; + public IExpression exp2; + + public Equals(IExpression exp1, IExpression exp2) { + this.exp1 = exp1; + this.exp2 = exp2; + } + + @Override + public String toString() { + return exp1 + " == " + exp2; + } + + @Override + public Object evaluate(IEnvironment environment) { + return ((Double)exp1.evaluate(environment)) == ((Double)exp2.evaluate(environment)); + } + + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForIndex.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForIndex.java new file mode 100644 index 00000000..d4a14eb1 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForIndex.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class ForIndex { + + public VariableBase base; + public IExpression expression; + + public ForIndex(Function function, String name, IExpression expression) { + this.expression = expression; + this.base = function.addIndex(name, this); + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForStatement.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForStatement.java new file mode 100644 index 00000000..5dedd79e --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForStatement.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +import java.util.ArrayList; + +public class ForStatement implements IStatement { + + public ArrayList indices; + public IStatement statement; + + public ForStatement(ArrayList indices, IStatement statement) { + this.indices = indices; + this.statement = statement; + } + + @Override + public String toString() { + return "for " + indices + " loop "+ statement + " end for"; + } + + private void loop(IEnvironment environment, int i) { + if(i == indices.size()) { + statement.evaluate(environment); + return; + } else { + ForIndex index = indices.get(i); + Array array = (Array)index.expression.evaluate(environment); + for(Object element : array.elements()) { + environment.put(index.base.index, element); + loop(environment, i+1); + } + } + } + + @Override + public void evaluate(IEnvironment environment) { + loop(environment, 0); + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Frame.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Frame.java new file mode 100644 index 00000000..a3b15785 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Frame.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class Frame implements IEnvironment { + + final public IEnvironment parent; + final private int offset; + + public Frame(IEnvironment parent, int offset) { + this.parent = parent; + this.offset = offset; + } + + @Override + public int offset() { + return offset; + } + + @Override + public void put(int index, Object value) { + parent.put(parent.offset() + index, value); + } + + @Override + public Object getValue(int index) { + return parent.getValue(parent.offset() + index); + } + + @Override + public ISystem getSystem() { + return parent.getSystem(); + } + +} + \ No newline at end of file diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Function.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Function.java new file mode 100644 index 00000000..925a192f --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Function.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class Function implements Fn, IFrame { + + public static final boolean PRINT = false; + + final public String name; + final public IStatement statement; + + public ArrayList inputs = new ArrayList(); + public ArrayList outputs = new ArrayList(); + public ArrayList internals = new ArrayList(); + + public Variable[] parameters; + + public ArrayList indices = new ArrayList(); + + public Function(String name, IStatement statement) { + this.name = name; + this.statement = statement; + } + + public Object evaluate(IEnvironment environment, int argc) { + statement.evaluate(environment); + VariableDeclaration out = outputs.get(0); + return environment.getValue(out.variable.base.index); + } + + @Override + public void setLocals(IEnvironment environment) { + for(int i=0;i names = new HashMap(); + + public VariableBase getBase(String name) { + VariableBase base = names.get(name); + if(base == null) { + base = new VariableBase(name); + names.put(name, base); + } + return base; + } + + public void prepare() { + int nextIndex = 0; + if(PRINT) + System.err.println("Preparing function '" + name + "':"); + for(Map.Entry entry : names.entrySet()) { + VariableBase base = entry.getValue(); + base.index = nextIndex; + if(PRINT) + System.err.println("Variable: " + entry.getKey() + ", index=" + base.index + ", size=" + base.dimension()); + nextIndex += base.dimension(); + } + parameters = new Variable[inputs.size()]; + for(int i=0;i= " + exp2; + } + + @Override + public Object evaluate(IEnvironment environment) { + return ((Double)exp1.evaluate(environment)) >= ((Double)exp2.evaluate(environment)); + } + + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterThan.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterThan.java new file mode 100644 index 00000000..19554716 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterThan.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class GreaterThan implements IExpression { + + public IExpression exp1; + public IExpression exp2; + + public GreaterThan(IExpression exp1, IExpression exp2) { + this.exp1 = exp1; + this.exp2 = exp2; + } + + @Override + public String toString() { + return exp1 + " > " + exp2; + } + + @Override + public Object evaluate(IEnvironment environment) { + return ((Double)exp1.evaluate(environment)) > ((Double)exp2.evaluate(environment)); + } + + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IEnvironment.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IEnvironment.java new file mode 100644 index 00000000..71b6b738 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IEnvironment.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public interface IEnvironment { + +// Object getValue(String key); + Object getValue(int index); +// void put(String key, Object value); + void put(int index, Object value); +// Object evaluateFunction(IEnvironment parent, String name, ArgumentList args); + + int offset(); + + ISystem getSystem(); + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IExpression.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IExpression.java new file mode 100644 index 00000000..e03d07ca --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IExpression.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public interface IExpression { + + public Object evaluate(IEnvironment environment); + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IFrame.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IFrame.java new file mode 100644 index 00000000..7edb1414 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IFrame.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public interface IFrame { + public VariableBase getBase(String name); +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IStatement.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IStatement.java new file mode 100644 index 00000000..e50a09bc --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IStatement.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public interface IStatement { + + public void evaluate(IEnvironment environment); + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ISystem.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ISystem.java new file mode 100644 index 00000000..8f01d105 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ISystem.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +import java.util.TreeMap; + +public interface ISystem { + + boolean initial(); + public Object evaluateFunction(IEnvironment environment, String name, ArgumentList args); + + TreeMap getHistory(String ident); + double time(); + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfStatement.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfStatement.java new file mode 100644 index 00000000..37dc2af2 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfStatement.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class IfStatement implements IStatement { + + public IExpression exp; + public IStatement t; + public IStatement e; + + public IfStatement(IExpression exp, IStatement t, IStatement e) { + this.exp = exp; + this.t = t; + this.e = e; + } + + @Override + public String toString() { + return "if " + exp + " then " + t + " else "+ e; + } + + @Override + public void evaluate(IEnvironment environment) { + if((Boolean)exp.evaluate(environment)) { + t.evaluate(environment); + } else { + e.evaluate(environment); + } + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfThenElse.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfThenElse.java new file mode 100644 index 00000000..72aafc65 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfThenElse.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class IfThenElse implements IExpression { + + public IExpression exp; + public IExpression t; + public IExpression e; + + public IfThenElse(IExpression exp, IExpression t, IExpression e) { + this.exp = exp; + this.t = t; + this.e = e; + } + + @Override + public String toString() { + return "if " + exp + " then " + t + " else "+ e; + } + + @Override + public Object evaluate(IEnvironment environment) { + if((Boolean)exp.evaluate(environment)) { + return t.evaluate(environment); + } else { + return e.evaluate(environment); + } + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessOrEqualThan.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessOrEqualThan.java new file mode 100644 index 00000000..33295cd1 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessOrEqualThan.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class LessOrEqualThan implements IExpression { + + public IExpression exp1; + public IExpression exp2; + + public LessOrEqualThan(IExpression exp1, IExpression exp2) { + this.exp1 = exp1; + this.exp2 = exp2; + } + + @Override + public String toString() { + return exp1 + " <= " + exp2; + } + + @Override + public Object evaluate(IEnvironment environment) { + Double d1 = (Double)exp1.evaluate(environment); + Double d2 = (Double)exp2.evaluate(environment); + return d1 <= d2; + } + + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessThan.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessThan.java new file mode 100644 index 00000000..6a3aea88 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessThan.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class LessThan implements IExpression { + + public IExpression exp1; + public IExpression exp2; + + public LessThan(IExpression exp1, IExpression exp2) { + this.exp1 = exp1; + this.exp2 = exp2; + } + + @Override + public String toString() { + return exp1 + " < " + exp2; + } + + @Override + public Object evaluate(IEnvironment environment) { + Object left = exp1.evaluate(environment); + Object right = exp2.evaluate(environment); + return ((Double)left) < ((Double)right); + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LineReader.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LineReader.java new file mode 100644 index 00000000..1dc522fd --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LineReader.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +import java.io.StringReader; + +import fi.semantum.sysdyn.solver.parser.ModelParser; +import fi.semantum.sysdyn.solver.parser.Node; +import fi.semantum.sysdyn.solver.parser.SimpleNode; + +public class LineReader { + + public static final boolean PRINT = false; + + enum State { + FUNCTIONS,PARAMETERS,INITIALS,EQUATIONS,STOP + } + + private State state = State.FUNCTIONS; + + StringBuilder functions = new StringBuilder(); + + int startPos = 0; + int pos = 0; + final char[] chars; + final NodeCache cache; + final Model model; + final Parser parser; + + public LineReader(String input, NodeCache cache) { + chars = input.toCharArray(); + this.cache = cache; + model = new Model(); + parser = new Parser(); + } + + public void parseFunctions(String line) throws Exception { + + if(line.startsWith("class")) { + + String text = functions.toString(); + + Node node = cache.getNode(text); + if(node == null) { + StringReader reader = new StringReader(functions.toString()); + ModelParser modelParser = new ModelParser(reader); + node = modelParser.parse(); + cache.store(text, (SimpleNode)node); + } + + parser.walk((SimpleNode)node, 0, model); + + state = State.PARAMETERS; + return; + } + + functions.append(line); + functions.append("\n"); + + } + + public void parseParameters(String line) throws Exception { + + if("initial equation".equals(line)) { + state = State.INITIALS; + return; + } + + if("equation".equals(line)) { + state = State.EQUATIONS; + return; + } + + if(PRINT) System.err.println("parameter: '" + line + "'"); + + Node node = cache.getNode(line); + if(node == null) { + StringReader reader = new StringReader(line); + ModelParser modelParser = new ModelParser(reader); + node = modelParser.element(); + cache.store(line, (SimpleNode)node); + } + + parser.currentFrame = model; + parser.walk((SimpleNode)node, 0, model); + + } + + public void parseInitials(String line) throws Exception { + + if(line.startsWith("equation")) { + state = State.EQUATIONS; + return; + } + + if(line.startsWith("end")) { + state = State.STOP; + return; + } + + model.initial = true; + + if(PRINT) System.err.println("initial: '" + line + "'"); + + Node node = cache.getNode(line); + if(node == null) { + StringReader reader = new StringReader(line); + ModelParser modelParser = new ModelParser(reader); + node = modelParser.equation(); + cache.store(line, (SimpleNode)node); + } + + parser.currentFrame = model; + parser.walk((SimpleNode)node, 0, model); + + } + + public void parseEquations(String line) throws Exception { + + if(line.startsWith("end")) { + state = State.STOP; + return; + } + + if(PRINT) System.err.println("equation: '" + line + "'"); + + model.initial = false; + + Node node = cache.getNode(line); + if(node == null) { + StringReader reader = new StringReader(line); + ModelParser modelParser = new ModelParser(reader); + node = modelParser.equation(); + cache.store(line, (SimpleNode)node); + } + + parser.currentFrame = model; + parser.walk((SimpleNode)node, 0, model); + + } + + public void parseLine(String line) throws Exception { + //System.err.println("PARSE "+line); + switch(state) { + case FUNCTIONS: + parseFunctions(line); + break; + case PARAMETERS: + parseParameters(line); + break; + case INITIALS: + parseInitials(line); + break; + case EQUATIONS: + parseEquations(line); + break; + case STOP: + break; + } + } + + public void parse() throws Exception { + + long start = System.nanoTime(); + + for(;pos initials = new ArrayList(); + public ArrayList assignments = new ArrayList(); + public ArrayList derivatives = new ArrayList(); + public ArrayList parameters = new ArrayList(); + public ArrayList variables = new ArrayList(); + public Map functions = new HashMap(); + + public Assignment[] assignmentArray; + public Assignment[] derivativeArray; + + public Fn getFunction(String name) { + return functions.get(name); + } + + public HashMap names = new HashMap(); + + public VariableBase getBase(String name) { + VariableBase base = names.get(name); + if(base == null) { + base = new VariableBase(name); + names.put(name, base); + } + return base; + } + + public Object evaluateFunction(IEnvironment environment, String name, ArgumentList args) { + Fn fn = getFunction(name); + if(fn == null) { + fn = functions.get(name); + if(fn == null) throw new RuntimeException("Undefined function '" + name + "'"); + } + // knife! + if("delay".equals(name)) { + + Frame frame = new Frame(environment, fn.offset()); + + ArrayList argh = new ArrayList(); + argh.add(args.args.get(0).modification.toString()); + for(int i=0;i argh = new ArrayList(); + for(int i=0;i entry : names.entrySet()) { + VariableBase base = entry.getValue(); + base.index = nextIndex; + if(PRINT) + System.err.println("Variable: " + entry.getKey() + " " + base.index + " " + Arrays.toString(base.dimensions)); + nextIndex += base.dimension(); + } + + if(PRINT) + System.err.println("=================="); + + return nextIndex; + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Multiplication.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Multiplication.java new file mode 100644 index 00000000..8721c27d --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Multiplication.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class Multiplication implements IExpression { + + public IExpression exp1; + public IExpression exp2; + + public Multiplication(IExpression exp1, IExpression exp2) { + this.exp1 = exp1; + this.exp2 = exp2; + } + + @Override + public String toString() { + return exp1 + " * " + exp2; + } + + private Array arrayMul(Array a, Double d) { + return a; + } + + @Override + public Object evaluate(IEnvironment environment) { + Object left = exp1.evaluate(environment); + Object right = exp2.evaluate(environment); + if(left instanceof Double && right instanceof Double) return ((Double)left)*((Double)right); + else if (left instanceof Array && right instanceof Double) return arrayMul((Array)left, (Double)right); + else if (left instanceof Double && right instanceof Array) return arrayMul((Array)right, (Double)left); + else throw new UnsupportedOperationException(); + } +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Negation.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Negation.java new file mode 100644 index 00000000..d20354dd --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Negation.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class Negation implements IExpression { + + public IExpression exp; + + public Negation(IExpression exp) { + this.exp = exp; + } + + @Override + public String toString() { + return "-" + exp; + } + + @Override + public Object evaluate(IEnvironment environment) { + return -((Double)exp.evaluate(environment)); + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeCache.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeCache.java new file mode 100644 index 00000000..3a49e98b --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeCache.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +import java.util.HashMap; +import java.util.Map; + +import fi.semantum.sysdyn.solver.parser.SimpleNode; + +public class NodeCache { + + Map cache = new HashMap(); + + public SimpleNode getNode(String line) { + return cache.get(line); + } + + public void store(String line, SimpleNode node) { + cache.put(line, node); + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeClass.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeClass.java new file mode 100644 index 00000000..2d8c909a --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeClass.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public enum NodeClass { + + assignment, + equation_section, + composition, + for_index, + for_indices, + for_statement, + if_statement, + while_statement, + statement, + name, + element_list, + element_modification, + function_arguments, + argument_list, + type_prefix, + algorithm_section, + subscript, + subscript_2, + component_clause, + component_declaration, + array_subscripts, + declaration, + class_definition, + array, + primary, + component_reference, + relation, + simple_expression, + logical_expression, + logical_term, + arithmetic_expression, + term, + if_expression, + add_op, + mul_op, + rel_op, + der_initial; + + private NodeClass() { + Parser.nodeNameMap.put(toString(), this); + } + + public static NodeClass of(String name) { + return Parser.nodeNameMap.get(name); + } + +} \ No newline at end of file diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NotEquals.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NotEquals.java new file mode 100644 index 00000000..e5bee880 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NotEquals.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class NotEquals implements IExpression { + + public IExpression exp1; + public IExpression exp2; + + public NotEquals(IExpression exp1, IExpression exp2) { + this.exp1 = exp1; + this.exp2 = exp2; + } + + @Override + public String toString() { + return exp1 + " <> " + exp2; + } + + @Override + public Object evaluate(IEnvironment environment) { + return ((Double)exp1.evaluate(environment)) != ((Double)exp2.evaluate(environment)); + } + + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Or.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Or.java new file mode 100644 index 00000000..1e72912a --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Or.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +import java.util.ArrayList; + +public class Or implements IExpression { + + public ArrayList exps; + + public Or(ArrayList exps) { + this.exps = exps; + } + + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append(exps.get(0)); + for(int i=1;i nodeNameMap = new HashMap(); + + public Object walk_(SimpleNode n, int indent, Model model) { + + // TODO: most of this should probably be implemented in the parser + + NodeClass nc = NodeClass.of(n.toString()); + + if (nc == null) { + if(n.jjtGetNumChildren() == 1) return walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + // not sure if this is ever called + for(int i=0;i comps = new ArrayList(); + for(int i=0;i indices = new ArrayList(); + for(int i=0;i indices2 = (ArrayList)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + ArrayList stms = new ArrayList(); + for(int i=1;i thens = new ArrayList(); + ArrayList elses = new ArrayList(); + for(int i=1;i whiles = new ArrayList(); + for(int i=1;i elements = new ArrayList(); + for(int i=0;i args = new ArrayList(); + for(int i=0;i statements = new ArrayList(); + for(int i=0;i clauses = new ArrayList(); + for(int i=declarationStart;i())); + if(currentFrame == model) model.variables.add(vd); + clauses.add(vd); + } + } + } + return clauses; + case component_declaration: + return (Declaration)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + case array_subscripts: + IExpression[] subs = new IExpression[n.jjtGetNumChildren()]; + for(int i=0;i stms2 = new ArrayList(); + Function function = new Function(functionName, new StatementList(stms2)); + currentFrame = function; + ArrayList composition = (ArrayList)walk(child, indent+2, model); + for(int i=1;i declarations = (ArrayList)composition.get(i); + for(Object os_ : declarations) { + ArrayList os = (ArrayList)os_; + for(Object o : os) { + VariableDeclaration decl = (VariableDeclaration)o; + function.internals.add(decl); + } + } + } + } + ArrayList declarations = (ArrayList)composition.get(0); + for(Object os_ : declarations) { + ArrayList os = (ArrayList)os_; + for(Object o : os) { + VariableDeclaration decl = (VariableDeclaration)o; + if("input".equals(decl.direction)) function.inputs.add(decl); + else if ("output".equals(decl.direction)) function.outputs.add(decl); + else throw new IllegalStateException(); + } + } + model.functions.put(functionName, function); + currentFrame = model; + return function; + } + break; + case array: + Array array = new Array(); + if(n.jjtGetNumChildren() == 1) { + ArgumentList al = (ArgumentList)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + for(Argument arg : al.args) array.addElement(arg.modification); + } + return array; + case primary: + if(n.op != null) { + return Utils.parsePrimitive(n.op); + } else { + return walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + } + case component_reference: + if(n.jjtGetNumChildren() == 1) { + return new Variable(currentFrame, n.op, (IExpression[])walk((SimpleNode)n.jjtGetChild(0), indent+2, model)); + } else { + if ("time".equals(n.op)) { + return new TimeVariable(); + } + return new Variable(currentFrame, n.op, null); + } + case relation: + if(n.jjtGetNumChildren() == 3) { + IExpression exp1 = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + String op = (String)walk((SimpleNode)n.jjtGetChild(1), indent+2, model); + IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(2), indent+2, model); + String trimmed = op != null ? op.trim() : null; + if("<".equals(trimmed)) { + return new LessThan(exp1, exp2); + } else if(">".equals(trimmed)) { + return new GreaterThan(exp1, exp2); + } else if(">=".equals(trimmed)) { + return new GreaterOrEqualThan(exp1, exp2); + } else if("<=".equals(trimmed)) { + return new LessOrEqualThan(exp1, exp2); + } else if("==".equals(trimmed)) { + return new Equals(exp1, exp2); + } else if("<>".equals(trimmed)) { + return new NotEquals(exp1, exp2); + } + else return null; + } else { + return walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + } + case simple_expression: + if(n.jjtGetNumChildren() == 1) return walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + else if(n.jjtGetNumChildren() == 2) { + IExpression start = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + IExpression end = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model); + return new ArraySliceExpression(start, end); + } else { + throw new UnsupportedOperationException(); + } + case logical_expression: + if(n.jjtGetNumChildren() > 1) { + ArrayList logs = new ArrayList(); + for(int i=0;i 1) { + ArrayList terms = new ArrayList(); + for(int i=0;i 1) { + IExpression left = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + for(int i=1;i 1) { + IExpression term = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + for(int i=1;i 0) { + + koss = 0; + + for(ParameterDeclaration pd : model.parameters) { + try { + if(!pd.assigned) { + pd.variable.assign(env, pd.modification.evaluate(env)); + pd.assigned = true; + } + } catch (Exception e) { + koss++; + if(PRINT_EXCEPTIONS) { + e.printStackTrace(); + System.err.println("failed to assign " + pd.variable.toString()); + } + } + } + + ArrayList assignments = new ArrayList(); + assignments.addAll(model.assignments); + assignments.addAll(model.initials); + + for(VariableDeclaration vd : model.variables) { + try { + if(!vd.assigned) { + for(Argument arg : vd.modification.args) { + if("start".equals(arg.name)) { + Object value = arg.modification.evaluate(env); + vd.variable.assign(env, value); + // make sure the variable is not initialized + // twice, this is probably not the most + // efficient way + for (Assignment a : assignments) { + if (vd.variable.base.equals(a.target.base)) { + a.assigned = true; + } + } + } + } + vd.assigned = true; + } + } catch (Exception e) { + koss++; + if(PRINT_EXCEPTIONS) { + e.printStackTrace(); + System.err.println("failed to assign " + vd.variable.toString()); + } + } + } + + for(Assignment ass : assignments) { + try { + if(!ass.assigned) { + Object value = ass.expression.evaluate(env); + ass.target.assign(env, value); + ass.assigned = true; + } + } catch (Exception e) { + koss++; + if(PRINT_EXCEPTIONS) { + e.printStackTrace(); + System.err.println("failed to assign " + ass.target.toString()); + } + } + } + } + + env.initial = false; + + ready = true; + } + + public HashMap values() { + return env.getValueMap(); + } + + public void step() { + // TODO: do something more sensible if the solver is not ready + if (!ready) return; + + Assignment[] assignments = model.assignmentArray; + Assignment[] derivatives = model.derivativeArray; + + // should probably be wrapped inside a method or something + env.time += env.step; + + // Solve algebraic equations + for(int i=0;i 2) variables + private String subscriptString() { + if (subscripts == null || subscripts.length < 1) { + return ""; + } + + StringBuilder str = new StringBuilder(); + str.append('['); + for (int i = 0; i < subscripts.length; i++) { + if (i > 0) { + str.append(", "); + } + // is the expression inside subscript always a constant? + str.append(((Double)((Constant)subscripts[i]).value).intValue()); + } + str.append(']'); + return str.toString(); + } + + public int assignArray(IEnvironment env, int index, Array value, int asd) { + for(int i=0;i dimensions[i]) dimensions[i] = index; + } + } + } + public int dimension() { + if(dimensions == null) return 1; + int result = 1; + for(int d : dimensions) result *= d; + return result; + } + public boolean isStoredAsArray() { + if(dimensions == null) return false; + for(int d : dimensions) if(d == -1) return true; + return false; + } +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableDeclaration.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableDeclaration.java new file mode 100644 index 00000000..02043c75 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableDeclaration.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + + +public class VariableDeclaration implements IExpression { + + public Variable variable; + public String direction; + public String type; + public ArgumentList modification; + public boolean assigned = false; + + public VariableDeclaration(Variable variable, String direction, String type, ArgumentList modification) { + this.variable = variable; + this.direction = direction; + this.type = type; + this.modification = modification; + } + + @Override + public String toString() { + return direction + " " + type + " " + variable + " " + modification; + } + + @Override + public Object evaluate(IEnvironment environment) { + throw new UnsupportedOperationException(); + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/While.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/While.java new file mode 100644 index 00000000..47e94c86 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/While.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class While implements IStatement { + + public IExpression expression; + public IStatement statement; + + public While(IExpression expression, IStatement statement) { + this.expression = expression; + this.statement = statement; + } + + @Override + public String toString() { + return "while " + expression + " then "+ statement + " end"; + } + + @Override + public void evaluate(IEnvironment environment) { + while ((Boolean)expression.evaluate(environment)) + statement.evaluate(environment); + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/JJTModelParserState.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/JJTModelParserState.java new file mode 100644 index 00000000..6d43b87a --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/JJTModelParserState.java @@ -0,0 +1,123 @@ +/* Generated By:JavaCC: Do not edit this line. JJTModelParserState.java Version 5.0 */ +package fi.semantum.sysdyn.solver.parser; + +public class JJTModelParserState { + private java.util.List nodes; + private java.util.List marks; + + private int sp; // number of nodes on stack + private int mk; // current mark + private boolean node_created; + + public JJTModelParserState() { + nodes = new java.util.ArrayList(); + marks = new java.util.ArrayList(); + sp = 0; + mk = 0; + } + + /* Determines whether the current node was actually closed and + pushed. This should only be called in the final user action of a + node scope. */ + public boolean nodeCreated() { + return node_created; + } + + /* Call this to reinitialize the node stack. It is called + automatically by the parser's ReInit() method. */ + public void reset() { + nodes.clear(); + marks.clear(); + sp = 0; + mk = 0; + } + + /* Returns the root node of the AST. It only makes sense to call + this after a successful parse. */ + public Node rootNode() { + return nodes.get(0); + } + + /* Pushes a node on to the stack. */ + public void pushNode(Node n) { + nodes.add(n); + ++sp; + } + + /* Returns the node on the top of the stack, and remove it from the + stack. */ + public Node popNode() { + if (--sp < mk) { + mk = marks.remove(marks.size()-1); + } + return nodes.remove(nodes.size()-1); + } + + /* Returns the node currently on the top of the stack. */ + public Node peekNode() { + return nodes.get(nodes.size()-1); + } + + /* Returns the number of children on the stack in the current node + scope. */ + public int nodeArity() { + return sp - mk; + } + + + public void clearNodeScope(Node n) { + while (sp > mk) { + popNode(); + } + mk = marks.remove(marks.size()-1); + } + + + public void openNodeScope(Node n) { + marks.add(mk); + mk = sp; + n.jjtOpen(); + } + + + /* A definite node is constructed from a specified number of + children. That number of nodes are popped from the stack and + made the children of the definite node. Then the definite node + is pushed on to the stack. */ + public void closeNodeScope(Node n, int num) { + mk = marks.remove(marks.size()-1); + while (num-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, num); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } + + + /* A conditional node is constructed if its condition is true. All + the nodes that have been pushed since the node was opened are + made children of the conditional node, which is then pushed + on to the stack. If the condition is false the node is not + constructed and they are left on the stack. */ + public void closeNodeScope(Node n, boolean condition) { + if (condition) { + int a = nodeArity(); + mk = marks.remove(marks.size()-1); + while (a-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, a); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } else { + mk = marks.remove(marks.size()-1); + node_created = false; + } + } +} +/* JavaCC - OriginalChecksum=6281595a71622ddc7d1a230278358c63 (do not edit this line) */ diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParser.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParser.java new file mode 100644 index 00000000..828459b9 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParser.java @@ -0,0 +1,5980 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. ModelParser.java */ +package fi.semantum.sysdyn.solver.parser; + +import java.util.ArrayList; + +public class ModelParser/*@bgen(jjtree)*/implements ModelParserTreeConstants, ModelParserConstants {/*@bgen(jjtree)*/ + protected JJTModelParserState jjtree = new JJTModelParserState(); + private ArrayList inputs = new ArrayList(); + private ArrayList outputs = new ArrayList(); + + private enum InterfaceVariableType + { + INPUT, OUTPUT, OTHER + } + + public class Parameter + { + public String name; + public boolean optional; + public String description; + public String type; + + public Parameter() + { + name = new String(""); + optional = false; + description = null; + type = null; + } + } + + public ArrayList getInputs() + { + return inputs; + } + + public ArrayList getOutputs() + { + return outputs; + } + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + final public Node parse() throws ParseException { + /*@bgen(jjtree) parse */ + SimpleNode jjtn000 = new SimpleNode(JJTPARSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + stored_definition(); + jj_consume_token(0); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return jjtn000;} + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + +/*** Stored Definition - Within ************************************/ + final public Node stored_definition() throws ParseException { + /*@bgen(jjtree) STORED */ + SimpleNode jjtn000 = new SimpleNode(JJTSTORED); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 53: + jj_consume_token(53); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + name(); + break; + default: + jj_la1[0] = jj_gen; + ; + } + jj_consume_token(70); + break; + default: + jj_la1[1] = jj_gen; + ; + } + label_1: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 11: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + ; + break; + default: + jj_la1[2] = jj_gen; + break label_1; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 11: + jj_consume_token(11); + break; + default: + jj_la1[3] = jj_gen; + ; + } + class_definition(); + jj_consume_token(70); + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return jjtn000;} + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + +/*** Class Definition **********************************************/ + final public void class_definition() throws ParseException { + /*@bgen(jjtree) class_definition */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASS_DEFINITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 30: + jj_consume_token(30); + break; + default: + jj_la1[4] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 47: + jj_consume_token(47); + break; + default: + jj_la1[5] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 34: + jj_consume_token(34); + break; + case 7: + jj_consume_token(7); + break; + case 61: + jj_consume_token(61); + break; + case 24: + jj_consume_token(24); + break; + case 44: + case 50: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 50: + jj_consume_token(50); + break; + default: + jj_la1[6] = jj_gen; + ; + } + jj_consume_token(44); + break; + case 38: + jj_consume_token(38); + break; + case 37: + jj_consume_token(37); + break; + case 26: + jj_consume_token(26); + jjtn000.op = "function"; + break; + case 17: + jj_consume_token(17); + break; + case 94: + jj_consume_token(94); + break; + case 95: + jj_consume_token(95); + break; + default: + jj_la1[7] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + class_specifier(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void class_specifier() throws ParseException { + /*@bgen(jjtree) class_specifier */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASS_SPECIFIER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);Token t; + try { + if (jj_2_1(2)) { + t = jj_consume_token(IDENT); + jjtn000.op = t.image; + string_comment(); + composition(); + jj_consume_token(35); + jj_consume_token(IDENT); + } else if (jj_2_2(2)) { + jj_consume_token(IDENT); + jj_consume_token(88); + base_prefix(); + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[8] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + break; + default: + jj_la1[9] = jj_gen; + ; + } + comment(); + } else if (jj_2_3(3)) { + jj_consume_token(IDENT); + jj_consume_token(88); + jj_consume_token(40); + jj_consume_token(62); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + enum_list(); + break; + default: + jj_la1[10] = jj_gen; + ; + } + jj_consume_token(63); + comment(); + } else if (jj_2_4(3)) { + jj_consume_token(IDENT); + jj_consume_token(88); + jj_consume_token(58); + jj_consume_token(62); + name(); + jj_consume_token(71); + jj_consume_token(IDENT); + label_2: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[11] = jj_gen; + break label_2; + } + jj_consume_token(71); + jj_consume_token(IDENT); + } + jj_consume_token(63); + comment(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 55: + jj_consume_token(55); + jj_consume_token(IDENT); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + break; + default: + jj_la1[12] = jj_gen; + ; + } + string_comment(); + composition(); + jj_consume_token(35); + jj_consume_token(IDENT); + break; + default: + jj_la1[13] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void base_prefix() throws ParseException { + /*@bgen(jjtree) base_prefix */ + SimpleNode jjtn000 = new SimpleNode(JJTBASE_PREFIX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + type_prefix(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void enum_list() throws ParseException { + /*@bgen(jjtree) enum_list */ + SimpleNode jjtn000 = new SimpleNode(JJTENUM_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + enumeration_literal(); + label_3: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[14] = jj_gen; + break label_3; + } + jj_consume_token(71); + enumeration_literal(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void enumeration_literal() throws ParseException { + /*@bgen(jjtree) enumeration_literal */ + SimpleNode jjtn000 = new SimpleNode(JJTENUMERATION_LITERAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(IDENT); + comment(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void parse_composition() throws ParseException { + /*@bgen(jjtree) parse_composition */ + SimpleNode jjtn000 = new SimpleNode(JJTPARSE_COMPOSITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + composition(); + jj_consume_token(0); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void composition() throws ParseException { + /*@bgen(jjtree) composition */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPOSITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + element_list(); + label_4: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 4: + case 45: + case 46: + case 52: + case 57: + ; + break; + default: + jj_la1[15] = jj_gen; + break label_4; + } + if (jj_2_5(2)) { + jj_consume_token(57); + element_list(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 52: + jj_consume_token(52); + element_list(); + break; + case 45: + case 46: + equation_section(); + break; + case 4: + algorithm_section(); + break; + default: + jj_la1[16] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 59: + jj_consume_token(59); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case STRING: + language_specification(); + break; + default: + jj_la1[17] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + external_function_call(); + break; + default: + jj_la1[18] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 14: + annotation(); + break; + default: + jj_la1[19] = jj_gen; + ; + } + jj_consume_token(70); + break; + default: + jj_la1[20] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 14: + annotation(); + jj_consume_token(70); + break; + default: + jj_la1[21] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void language_specification() throws ParseException { + /*@bgen(jjtree) language_specification */ + SimpleNode jjtn000 = new SimpleNode(JJTLANGUAGE_SPECIFICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(STRING); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void external_function_call() throws ParseException { + /*@bgen(jjtree) external_function_call */ + SimpleNode jjtn000 = new SimpleNode(JJTEXTERNAL_FUNCTION_CALL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + component_reference(); + jj_consume_token(88); + break; + default: + jj_la1[22] = jj_gen; + ; + } + jj_consume_token(IDENT); + jj_consume_token(62); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression_list(); + break; + default: + jj_la1[23] = jj_gen; + ; + } + jj_consume_token(63); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void element_list() throws ParseException { + /*@bgen(jjtree) element_list */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + label_5: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + case 7: + case 8: + case 11: + case 13: + case 16: + case 17: + case 23: + case 24: + case 26: + case 27: + case 30: + case 32: + case 34: + case 36: + case 37: + case 38: + case 42: + case 44: + case 47: + case 49: + case 50: + case 51: + case 55: + case 56: + case 61: + case 68: + case IDENT: + case 94: + case 95: + ; + break; + default: + jj_la1[24] = jj_gen; + break label_5; + } + element(); + jj_consume_token(70); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public Node element() throws ParseException { + /*@bgen(jjtree) element */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 36: + import_clause(); + break; + case 55: + extends_clause(); + break; + case 5: + case 7: + case 8: + case 11: + case 13: + case 16: + case 17: + case 23: + case 24: + case 26: + case 27: + case 30: + case 32: + case 34: + case 37: + case 38: + case 42: + case 44: + case 47: + case 49: + case 50: + case 51: + case 56: + case 61: + case 68: + case IDENT: + case 94: + case 95: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 8: + jj_consume_token(8); + break; + default: + jj_la1[25] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 11: + jj_consume_token(11); + break; + default: + jj_la1[26] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 51: + jj_consume_token(51); + break; + default: + jj_la1[27] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 27: + jj_consume_token(27); + break; + default: + jj_la1[28] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + case 7: + case 16: + case 17: + case 23: + case 24: + case 26: + case 30: + case 32: + case 34: + case 37: + case 38: + case 42: + case 44: + case 47: + case 49: + case 50: + case 56: + case 61: + case 68: + case IDENT: + case 94: + case 95: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + class_definition(); + break; + case 5: + case 16: + case 23: + case 32: + case 42: + case 49: + case 56: + case 68: + case IDENT: + component_clause(); + break; + default: + jj_la1[29] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + case 13: + jj_consume_token(13); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + class_definition(); + break; + case 5: + case 16: + case 23: + case 32: + case 42: + case 49: + case 56: + case 68: + case IDENT: + component_clause(); + break; + default: + jj_la1[30] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 54: + constraining_clause(); + comment(); + break; + default: + jj_la1[31] = jj_gen; + ; + } + break; + default: + jj_la1[32] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return jjtn000;} + break; + default: + jj_la1[33] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + + final public void import_clause() throws ParseException { + /*@bgen(jjtree) import_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTIMPORT_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(36); + if (jj_2_6(2)) { + jj_consume_token(IDENT); + jj_consume_token(88); + name(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + jj_consume_token(68); + jj_consume_token(82); + break; + default: + jj_la1[34] = jj_gen; + ; + } + break; + default: + jj_la1[35] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + comment(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + +/*** Extends *******************************************************/ + final public void extends_clause() throws ParseException { + /*@bgen(jjtree) extends_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTEXTENDS_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(55); + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + break; + default: + jj_la1[36] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 14: + annotation(); + break; + default: + jj_la1[37] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void constraining_clause() throws ParseException { + /*@bgen(jjtree) constraining_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTCONSTRAINING_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(54); + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + break; + default: + jj_la1[38] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + +/*** Component Clause **********************************************/ + final public void component_clause() throws ParseException { + /*@bgen(jjtree) component_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);InterfaceVariableType ioType = InterfaceVariableType.OTHER; + String typeSpecifier = ""; + //String arraySubscripts = null; + ArrayList componentList = new ArrayList(); + try { + ioType = type_prefix(); + typeSpecifier = type_specifier(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[39] = jj_gen; + ; + } + componentList = component_list(); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + if (ioType == InterfaceVariableType.INPUT) { + for (Parameter input : componentList) { + input.type = typeSpecifier; + inputs.add(input); + } + } else if (ioType == InterfaceVariableType.OUTPUT) { + for (Parameter output : componentList) { + output.type = typeSpecifier; + outputs.add(output); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public InterfaceVariableType type_prefix() throws ParseException { + /*@bgen(jjtree) type_prefix */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPE_PREFIX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);InterfaceVariableType type = InterfaceVariableType.OTHER; + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 16: + case 23: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 16: + jj_consume_token(16); + break; + case 23: + jj_consume_token(23); + break; + default: + jj_la1[40] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[41] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + case 42: + case 49: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + jj_consume_token(5); + jjtn000.op = "discrete"; + break; + case 42: + jj_consume_token(42); + jjtn000.op = "parameter"; + break; + case 49: + jj_consume_token(49); + jjtn000.op = "constant"; + break; + default: + jj_la1[42] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[43] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 32: + case 56: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 32: + jj_consume_token(32); + type = InterfaceVariableType.OUTPUT; jjtn000.op = "output"; + break; + case 56: + jj_consume_token(56); + type = InterfaceVariableType.INPUT; jjtn000.op = "input"; + break; + default: + jj_la1[44] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[45] = jj_gen; + ; + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return type;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + + final public String type_specifier() throws ParseException { + /*@bgen(jjtree) type_specifier */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPE_SPECIFIER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);String ret = new String(""); + try { + ret = name(); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = ret; + {if (true) return ret;} + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + + final public ArrayList component_list() throws ParseException { + /*@bgen(jjtree) component_list */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);ArrayList ret = new ArrayList(); + Parameter temp; + try { + // component_declaration { "," component_declaration } + temp = component_declaration(); + ret.add(temp); + label_6: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[46] = jj_gen; + break label_6; + } + jj_consume_token(71); + temp = component_declaration(); + ret.add(temp); + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return ret;} + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + + final public Parameter component_declaration() throws ParseException { + /*@bgen(jjtree) component_declaration */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_DECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);Parameter ret; + String temp = ""; + try { + // declaration [ conditional_attribute ] comment + ret = declaration(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 31: + conditional_attribute(); + break; + default: + jj_la1[47] = jj_gen; + ; + } + ret.description = comment(); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return ret;} + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + + final public void conditional_attribute() throws ParseException { + /*@bgen(jjtree) conditional_attribute */ + SimpleNode jjtn000 = new SimpleNode(JJTCONDITIONAL_ATTRIBUTE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(31); + expression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public Parameter declaration() throws ParseException { + /*@bgen(jjtree) declaration */ + SimpleNode jjtn000 = new SimpleNode(JJTDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);Token t; + // Parameter here without comment yet. + Parameter ret = new Parameter(); + try { + jj_consume_token(IDENT); + ret.name = new String(token.image); jjtn000.op = token.image; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[48] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + case 88: + case 89: + ret.optional = modification(); + break; + default: + jj_la1[49] = jj_gen; + ; + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return ret;} + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + +/*** Modification **********************************************/ + final public boolean modification() throws ParseException { + /*@bgen(jjtree) modification */ + SimpleNode jjtn000 = new SimpleNode(JJTMODIFICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);boolean optional = false; + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 88: + jj_consume_token(88); + expression(); + break; + default: + jj_la1[50] = jj_gen; + ; + } + break; + case 88: + jj_consume_token(88); + expression(); + optional = true; + break; + case 89: + jj_consume_token(89); + expression(); + optional = true; + break; + default: + jj_la1[51] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return optional;} + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + + final public void class_modification() throws ParseException { + /*@bgen(jjtree) class_modification */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASS_MODIFICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(62); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 8: + case 10: + case 11: + case 13: + case 68: + case IDENT: + argument_list(); + break; + default: + jj_la1[52] = jj_gen; + ; + } + jj_consume_token(63); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void argument_list() throws ParseException { + /*@bgen(jjtree) argument_list */ + SimpleNode jjtn000 = new SimpleNode(JJTARGUMENT_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + argument(); + label_7: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[53] = jj_gen; + break label_7; + } + jj_consume_token(71); + argument(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void argument() throws ParseException { + /*@bgen(jjtree) argument */ + SimpleNode jjtn000 = new SimpleNode(JJTARGUMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 10: + case 11: + case 13: + case 68: + case IDENT: + element_modification_or_replaceable(); + break; + case 8: + element_redeclaration(); + break; + default: + jj_la1[54] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void element_modification_or_replaceable() throws ParseException { + /*@bgen(jjtree) element_modification_or_replaceable */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_MODIFICATION_OR_REPLACEABLE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 10: + jj_consume_token(10); + break; + default: + jj_la1[55] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 11: + jj_consume_token(11); + break; + default: + jj_la1[56] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + element_modification(); + break; + case 13: + element_replaceable(); + break; + default: + jj_la1[57] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void element_modification() throws ParseException { + /*@bgen(jjtree) element_modification */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_MODIFICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + case 88: + case 89: + modification(); + break; + default: + jj_la1[58] = jj_gen; + ; + } + string_comment(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void element_redeclaration() throws ParseException { + /*@bgen(jjtree) element_redeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_REDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(8); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 10: + jj_consume_token(10); + break; + default: + jj_la1[59] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 11: + jj_consume_token(11); + break; + default: + jj_la1[60] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + case 7: + case 16: + case 17: + case 23: + case 24: + case 26: + case 30: + case 32: + case 34: + case 37: + case 38: + case 42: + case 44: + case 47: + case 49: + case 50: + case 56: + case 61: + case 68: + case IDENT: + case 94: + case 95: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + class_definition(); + break; + case 5: + case 16: + case 23: + case 32: + case 42: + case 49: + case 56: + case 68: + case IDENT: + component_clause1(); + break; + default: + jj_la1[61] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + case 13: + element_replaceable(); + break; + default: + jj_la1[62] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void element_replaceable() throws ParseException { + /*@bgen(jjtree) element_replaceable */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_REPLACEABLE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(13); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + class_definition(); + break; + case 5: + case 16: + case 23: + case 32: + case 42: + case 49: + case 56: + case 68: + case IDENT: + component_clause1(); + break; + default: + jj_la1[63] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 54: + constraining_clause(); + break; + default: + jj_la1[64] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void component_clause1() throws ParseException { + /*@bgen(jjtree) component_clause1 */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_CLAUSE1); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + type_prefix(); + type_specifier(); + component_declaration1(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void component_declaration1() throws ParseException { + /*@bgen(jjtree) component_declaration1 */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_DECLARATION1); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + declaration(); + comment(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + +/*** Equations *************************************************/ + final public void equation_section() throws ParseException { + /*@bgen(jjtree) equation_section */ + SimpleNode jjtn000 = new SimpleNode(JJTEQUATION_SECTION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 46: + jj_consume_token(46); + jjtn000.op = "initial"; + break; + default: + jj_la1[65] = jj_gen; + ; + } + jj_consume_token(45); + label_8: + while (true) { + if (jj_2_7(2)) { + ; + } else { + break label_8; + } + equation(); + jj_consume_token(70); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void algorithm_section() throws ParseException { + /*@bgen(jjtree) algorithm_section */ + SimpleNode jjtn000 = new SimpleNode(JJTALGORITHM_SECTION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 46: + jj_consume_token(46); + break; + default: + jj_la1[66] = jj_gen; + ; + } + jj_consume_token(4); + label_9: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[67] = jj_gen; + break label_9; + } + statement(); + jj_consume_token(70); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void assignment() throws ParseException { + /*@bgen(jjtree) assignment */ + SimpleNode jjtn000 = new SimpleNode(JJTASSIGNMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + simple_expression(); + jj_consume_token(88); + expression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public Node equation() throws ParseException { + /*@bgen(jjtree) equation */ + SimpleNode jjtn000 = new SimpleNode(JJTEQUATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + if (jj_2_8(3)) { + assignment(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 31: + if_equation(); + break; + case 21: + for_equation(); + break; + case 39: + connect_clause(); + break; + case 43: + when_equation(); + break; + case IDENT: + jj_consume_token(IDENT); + function_call_args(); + break; + default: + jj_la1[68] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + comment(); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return jjtn000;} + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + + final public void statement() throws ParseException { + /*@bgen(jjtree) statement */ + SimpleNode jjtn000 = new SimpleNode(JJTSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + component_reference(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 89: + jj_consume_token(89); + expression(); + break; + case 62: + function_call_args(); + break; + default: + jj_la1[69] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + case 62: + jj_consume_token(62); + output_expression_list(); + jj_consume_token(63); + jj_consume_token(89); + component_reference(); + function_call_args(); + break; + case 29: + jj_consume_token(29); + break; + case 18: + jj_consume_token(18); + break; + case 31: + if_statement(); + break; + case 21: + for_statement(); + break; + case 48: + while_statement(); + break; + case 43: + when_statement(); + break; + default: + jj_la1[70] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + comment(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void if_equation() throws ParseException { + /*@bgen(jjtree) if_equation */ + SimpleNode jjtn000 = new SimpleNode(JJTIF_EQUATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(31); + expression(); + jj_consume_token(28); + label_10: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[71] = jj_gen; + break label_10; + } + equation(); + jj_consume_token(70); + } + label_11: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[72] = jj_gen; + break label_11; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + label_12: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[73] = jj_gen; + break label_12; + } + equation(); + jj_consume_token(70); + } + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 15: + jj_consume_token(15); + label_13: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[74] = jj_gen; + break label_13; + } + equation(); + jj_consume_token(70); + } + break; + default: + jj_la1[75] = jj_gen; + ; + } + jj_consume_token(35); + jj_consume_token(31); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void then_statement() throws ParseException { + /*@bgen(jjtree) then_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTTHEN_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + statement(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void elseif_statement() throws ParseException { + /*@bgen(jjtree) elseif_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTELSEIF_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + statement(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void else_statement() throws ParseException { + /*@bgen(jjtree) else_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTELSE_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + statement(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void if_statement() throws ParseException { + /*@bgen(jjtree) if_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTIF_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(31); + expression(); + jj_consume_token(28); + label_14: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[76] = jj_gen; + break label_14; + } + then_statement(); + jj_consume_token(70); + } + label_15: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[77] = jj_gen; + break label_15; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + label_16: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[78] = jj_gen; + break label_16; + } + elseif_statement(); + jj_consume_token(70); + } + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 15: + jj_consume_token(15); + label_17: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[79] = jj_gen; + break label_17; + } + else_statement(); + jj_consume_token(70); + } + break; + default: + jj_la1[80] = jj_gen; + ; + } + jj_consume_token(35); + jj_consume_token(31); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void for_equation() throws ParseException { + /*@bgen(jjtree) for_equation */ + SimpleNode jjtn000 = new SimpleNode(JJTFOR_EQUATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(21); + for_indices(); + jj_consume_token(60); + label_18: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[81] = jj_gen; + break label_18; + } + equation(); + jj_consume_token(70); + } + jj_consume_token(35); + jj_consume_token(21); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void for_statement() throws ParseException { + /*@bgen(jjtree) for_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTFOR_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(21); + for_indices(); + jj_consume_token(60); + label_19: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[82] = jj_gen; + break label_19; + } + statement(); + jj_consume_token(70); + } + jj_consume_token(35); + jj_consume_token(21); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void for_indices() throws ParseException { + /*@bgen(jjtree) for_indices */ + SimpleNode jjtn000 = new SimpleNode(JJTFOR_INDICES); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + for_index(); + label_20: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[83] = jj_gen; + break label_20; + } + jj_consume_token(71); + for_index(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void for_index() throws ParseException { + /*@bgen(jjtree) for_index */ + SimpleNode jjtn000 = new SimpleNode(JJTFOR_INDEX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);Token t; + try { + //IDENT [ in expression ] + t = jj_consume_token(IDENT); + jjtn000.op = t.image; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 41: + jj_consume_token(41); + expression(); + break; + default: + jj_la1[84] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void while_statement() throws ParseException { + /*@bgen(jjtree) while_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTWHILE_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(48); + expression(); + jj_consume_token(60); + label_21: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[85] = jj_gen; + break label_21; + } + statement(); + jj_consume_token(70); + } + jj_consume_token(35); + jj_consume_token(48); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void when_equation() throws ParseException { + /*@bgen(jjtree) when_equation */ + SimpleNode jjtn000 = new SimpleNode(JJTWHEN_EQUATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(43); + expression(); + jj_consume_token(28); + label_22: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[86] = jj_gen; + break label_22; + } + equation(); + jj_consume_token(70); + } + label_23: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 25: + ; + break; + default: + jj_la1[87] = jj_gen; + break label_23; + } + jj_consume_token(25); + expression(); + jj_consume_token(28); + label_24: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[88] = jj_gen; + break label_24; + } + equation(); + jj_consume_token(70); + } + } + jj_consume_token(35); + jj_consume_token(43); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void when_statement() throws ParseException { + /*@bgen(jjtree) when_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTWHEN_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(43); + expression(); + jj_consume_token(28); + label_25: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[89] = jj_gen; + break label_25; + } + statement(); + jj_consume_token(70); + } + label_26: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 25: + ; + break; + default: + jj_la1[90] = jj_gen; + break label_26; + } + jj_consume_token(25); + expression(); + jj_consume_token(28); + label_27: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[91] = jj_gen; + break label_27; + } + statement(); + jj_consume_token(70); + } + } + jj_consume_token(35); + jj_consume_token(43); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void connect_clause() throws ParseException { + /*@bgen(jjtree) connect_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTCONNECT_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(39); + jj_consume_token(62); + component_reference(); + jj_consume_token(71); + component_reference(); + jj_consume_token(63); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + +/*** Expressions ***************************************************/ + final public void expr() throws ParseException { + /*@bgen(jjtree) expr */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + simple_expression(); + jj_consume_token(0); + break; + case 31: + jj_consume_token(31); + expression(); + jj_consume_token(28); + expression(); + label_28: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[92] = jj_gen; + break label_28; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + expression(); + } + jj_consume_token(15); + expression(); + jj_consume_token(0); + break; + default: + jj_la1[93] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void if_expression() throws ParseException { + /*@bgen(jjtree) if_expression */ + SimpleNode jjtn000 = new SimpleNode(JJTIF_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(31); + expression(); + jj_consume_token(28); + expression(); + label_29: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[94] = jj_gen; + break label_29; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + expression(); + } + jj_consume_token(15); + expression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void expression() throws ParseException { + /*@bgen(jjtree) expression */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + simple_expression(); + break; + case 31: + if_expression(); + break; + default: + jj_la1[95] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void simple_expression() throws ParseException { + /*@bgen(jjtree) simple_expression */ + SimpleNode jjtn000 = new SimpleNode(JJTSIMPLE_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + logical_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + logical_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + logical_expression(); + break; + default: + jj_la1[96] = jj_gen; + ; + } + break; + default: + jj_la1[97] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void logical_expression() throws ParseException { + /*@bgen(jjtree) logical_expression */ + SimpleNode jjtn000 = new SimpleNode(JJTLOGICAL_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + logical_term(); + label_30: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 22: + ; + break; + default: + jj_la1[98] = jj_gen; + break label_30; + } + jj_consume_token(22); + logical_term(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void logical_term() throws ParseException { + /*@bgen(jjtree) logical_term */ + SimpleNode jjtn000 = new SimpleNode(JJTLOGICAL_TERM); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + logical_factor(); + label_31: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 9: + ; + break; + default: + jj_la1[99] = jj_gen; + break label_31; + } + jj_consume_token(9); + logical_factor(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void logical_factor() throws ParseException { + /*@bgen(jjtree) logical_factor */ + SimpleNode jjtn000 = new SimpleNode(JJTLOGICAL_FACTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 12: + jj_consume_token(12); + break; + default: + jj_la1[100] = jj_gen; + ; + } + relation(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void relation() throws ParseException { + /*@bgen(jjtree) relation */ + SimpleNode jjtn000 = new SimpleNode(JJTRELATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + arithmetic_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + rel_op(); + arithmetic_expression(); + break; + default: + jj_la1[101] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void rel_op() throws ParseException { + /*@bgen(jjtree) rel_op */ + SimpleNode jjtn000 = new SimpleNode(JJTREL_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 72: + jj_consume_token(72); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = "< "; + break; + case 73: + jj_consume_token(73); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = "<="; + break; + case 74: + jj_consume_token(74); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = " >"; + break; + case 75: + jj_consume_token(75); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = " >="; + break; + case 76: + jj_consume_token(76); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = "=="; + break; + case 77: + jj_consume_token(77); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = "<>"; + break; + default: + jj_la1[102] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void arithmetic_expression() throws ParseException { + /*@bgen(jjtree) arithmetic_expression */ + SimpleNode jjtn000 = new SimpleNode(JJTARITHMETIC_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 78: + case 79: + case 80: + case 81: + add_op(); + break; + default: + jj_la1[103] = jj_gen; + ; + } + term(); + label_32: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 78: + case 79: + case 80: + case 81: + ; + break; + default: + jj_la1[104] = jj_gen; + break label_32; + } + add_op(); + term(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void add_op() throws ParseException { + /*@bgen(jjtree) add_op */ + SimpleNode jjtn000 = new SimpleNode(JJTADD_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 78: + jj_consume_token(78); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = "+"; + break; + case 79: + jj_consume_token(79); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = "-"; + break; + case 80: + jj_consume_token(80); + break; + case 81: + jj_consume_token(81); + break; + default: + jj_la1[105] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void term() throws ParseException { + /*@bgen(jjtree) term */ + SimpleNode jjtn000 = new SimpleNode(JJTTERM); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + factor(); + label_33: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 82: + case 83: + case 84: + case 85: + ; + break; + default: + jj_la1[106] = jj_gen; + break label_33; + } + mul_op(); + factor(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void mul_op() throws ParseException { + /*@bgen(jjtree) mul_op */ + SimpleNode jjtn000 = new SimpleNode(JJTMUL_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 82: + jj_consume_token(82); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = "*"; + break; + case 83: + jj_consume_token(83); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = "/"; + break; + case 84: + jj_consume_token(84); + break; + case 85: + jj_consume_token(85); + break; + default: + jj_la1[107] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void factor() throws ParseException { + /*@bgen(jjtree) factor */ + SimpleNode jjtn000 = new SimpleNode(JJTFACTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + primary(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 86: + case 87: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 86: + jj_consume_token(86); + break; + case 87: + jj_consume_token(87); + primary(); + break; + default: + jj_la1[108] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[109] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void der_initial() throws ParseException { + /*@bgen(jjtree) der_initial */ + SimpleNode jjtn000 = new SimpleNode(JJTDER_INITIAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + name(); + jjtn000.op = "application"; + break; + case 58: + jj_consume_token(58); + jjtn000.op = "der"; + break; + case 46: + jj_consume_token(46); + jjtn000.op = "initial"; + break; + default: + jj_la1[110] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + function_call_args(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void subscript_2() throws ParseException { + /*@bgen(jjtree) subscript_2 */ + SimpleNode jjtn000 = new SimpleNode(JJTSUBSCRIPT_2); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + expression_list(); + label_34: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 70: + ; + break; + default: + jj_la1[111] = jj_gen; + break label_34; + } + jj_consume_token(70); + expression_list(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void array() throws ParseException { + /*@bgen(jjtree) array */ + SimpleNode jjtn000 = new SimpleNode(JJTARRAY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(64); + function_arguments(); + jj_consume_token(65); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void primary() throws ParseException { + /*@bgen(jjtree) primary */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMARY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);Token t; + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case UNSIGNED_NUMBER: + t = jj_consume_token(UNSIGNED_NUMBER); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = token.image; + break; + case UNSIGNED_INTEGER: + t = jj_consume_token(UNSIGNED_INTEGER); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = token.image; + break; + case STRING: + t = jj_consume_token(STRING); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = token.image; + break; + case 6: + t = jj_consume_token(6); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = token.image; + break; + case 33: + t = jj_consume_token(33); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = token.image; + break; + default: + jj_la1[112] = jj_gen; + if (jj_2_9(2147483647)) { + der_initial(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + component_reference(); + break; + case 62: + jj_consume_token(62); + expression(); + jj_consume_token(63); + break; + case 66: + jj_consume_token(66); + subscript_2(); + jj_consume_token(67); + break; + case 64: + array(); + break; + case 35: + jj_consume_token(35); + break; + default: + jj_la1[113] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public String name() throws ParseException { + /*@bgen(jjtree) name */ + SimpleNode jjtn000 = new SimpleNode(JJTNAME); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);String ret = new String(""); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + jj_consume_token(68); + ret += "."; + break; + default: + jj_la1[114] = jj_gen; + ; + } + jj_consume_token(IDENT); + ret += token.image; jjtn000.op = token.image; + label_35: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + ; + break; + default: + jj_la1[115] = jj_gen; + break label_35; + } + jj_consume_token(68); + ret += "."; + jj_consume_token(IDENT); + ret += token.image; jjtn000.op = token.image; + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + {if (true) return ret;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + throw new Error("Missing return statement in function"); + } + + final public void component_reference() throws ParseException { + /*@bgen(jjtree) component_reference */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_REFERENCE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000);Token t; + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + jj_consume_token(68); + break; + default: + jj_la1[116] = jj_gen; + ; + } + t = jj_consume_token(IDENT); + jjtn000.op = t.image; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[117] = jj_gen; + ; + } + label_36: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + ; + break; + default: + jj_la1[118] = jj_gen; + break label_36; + } + jj_consume_token(68); + jj_consume_token(IDENT); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[119] = jj_gen; + ; + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void function_call_args() throws ParseException { + /*@bgen(jjtree) function_call_args */ + SimpleNode jjtn000 = new SimpleNode(JJTFUNCTION_CALL_ARGS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(62); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + function_arguments(); + break; + default: + jj_la1[120] = jj_gen; + ; + } + jj_consume_token(63); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void function_arguments() throws ParseException { + /*@bgen(jjtree) function_arguments */ + SimpleNode jjtn000 = new SimpleNode(JJTFUNCTION_ARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + if (jj_2_10(2)) { + expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 21: + case 71: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + jj_consume_token(71); + function_arguments(); + break; + case 21: + jj_consume_token(21); + for_indices(); + break; + default: + jj_la1[121] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[122] = jj_gen; + ; + } + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + named_arguments(); + break; + default: + jj_la1[123] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void named_arguments() throws ParseException { + /*@bgen(jjtree) named_arguments */ + SimpleNode jjtn000 = new SimpleNode(JJTNAMED_ARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + named_argument(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + jj_consume_token(71); + named_arguments(); + break; + default: + jj_la1[124] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void named_argument() throws ParseException { + /*@bgen(jjtree) named_argument */ + SimpleNode jjtn000 = new SimpleNode(JJTNAMED_ARGUMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(IDENT); + jj_consume_token(88); + expression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void output_expression_list() throws ParseException { + /*@bgen(jjtree) output_expression_list */ + SimpleNode jjtn000 = new SimpleNode(JJTOUTPUT_EXPRESSION_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[125] = jj_gen; + ; + } + label_37: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[126] = jj_gen; + break label_37; + } + jj_consume_token(71); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[127] = jj_gen; + ; + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void expression_list() throws ParseException { + /*@bgen(jjtree) expression_list */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPRESSION_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + expression(); + label_38: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[128] = jj_gen; + break label_38; + } + jj_consume_token(71); + expression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void array_subscripts() throws ParseException { + /*@bgen(jjtree) array_subscripts */ + SimpleNode jjtn000 = new SimpleNode(JJTARRAY_SUBSCRIPTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(66); + subscript(); + label_39: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[129] = jj_gen; + break label_39; + } + jj_consume_token(71); + subscript(); + } + jj_consume_token(67); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public void subscript() throws ParseException { + /*@bgen(jjtree) subscript */ + SimpleNode jjtn000 = new SimpleNode(JJTSUBSCRIPT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.op = "all"; + break; + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[130] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + final public String comment() throws ParseException { + String ret; + // string_comment [ annotation ] + ret = string_comment(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 14: + annotation(); + break; + default: + jj_la1[131] = jj_gen; + ; + } + {if (true) return ret;} + throw new Error("Missing return statement in function"); + } + + final public String string_comment() throws ParseException { + String ret = null; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case STRING: + jj_consume_token(STRING); + ret = new String(token.image); + label_40: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 78: + ; + break; + default: + jj_la1[132] = jj_gen; + break label_40; + } + jj_consume_token(78); + ret += "+"; + jj_consume_token(STRING); + ret += token.image; + } + break; + default: + jj_la1[133] = jj_gen; + ; + } + {if (true) return ret;} + throw new Error("Missing return statement in function"); + } + + final public void annotation() throws ParseException { + /*@bgen(jjtree) annotation */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + try { + jj_consume_token(14); + class_modification(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } + } + + private boolean jj_2_1(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_1(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(0, xla); } + } + + private boolean jj_2_2(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_2(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(1, xla); } + } + + private boolean jj_2_3(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_3(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(2, xla); } + } + + private boolean jj_2_4(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_4(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(3, xla); } + } + + private boolean jj_2_5(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_5(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(4, xla); } + } + + private boolean jj_2_6(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_6(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(5, xla); } + } + + private boolean jj_2_7(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_7(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(6, xla); } + } + + private boolean jj_2_8(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_8(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(7, xla); } + } + + private boolean jj_2_9(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_9(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(8, xla); } + } + + private boolean jj_2_10(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_10(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(9, xla); } + } + + private boolean jj_3_10() { + if (jj_3R_47()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_48()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_158() { + if (jj_3R_157()) return true; + return false; + } + + private boolean jj_3R_157() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_10()) { + jj_scanpos = xsp; + if (jj_3R_161()) return true; + } + return false; + } + + private boolean jj_3R_85() { + if (jj_3R_93()) return true; + return false; + } + + private boolean jj_3R_120() { + if (jj_scan_token(75)) return true; + return false; + } + + private boolean jj_3R_125() { + if (jj_scan_token(49)) return true; + return false; + } + + private boolean jj_3R_74() { + if (jj_scan_token(62)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_158()) jj_scanpos = xsp; + if (jj_scan_token(63)) return true; + return false; + } + + private boolean jj_3R_42() { + if (jj_3R_43()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_50()) { jj_scanpos = xsp; break; } + } + xsp = jj_scanpos; + if (jj_3R_51()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_52()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_103() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(50)) jj_scanpos = xsp; + if (jj_scan_token(44)) return true; + return false; + } + + private boolean jj_3R_147() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(68)) jj_scanpos = xsp; + if (jj_scan_token(IDENT)) return true; + xsp = jj_scanpos; + if (jj_3R_153()) jj_scanpos = xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_154()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_78() { + if (jj_scan_token(68)) return true; + if (jj_scan_token(IDENT)) return true; + return false; + } + + private boolean jj_3R_151() { + if (jj_scan_token(58)) return true; + return false; + } + + private boolean jj_3R_71() { + if (jj_scan_token(21)) return true; + if (jj_3R_85()) return true; + return false; + } + + private boolean jj_3R_77() { + if (jj_scan_token(68)) return true; + return false; + } + + private boolean jj_3R_60() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_77()) jj_scanpos = xsp; + if (jj_scan_token(IDENT)) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_78()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_46() { + if (jj_3R_60()) return true; + return false; + } + + private boolean jj_3_9() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_46()) { + jj_scanpos = xsp; + if (jj_scan_token(58)) { + jj_scanpos = xsp; + if (jj_scan_token(46)) return true; + } + } + if (jj_scan_token(62)) return true; + return false; + } + + private boolean jj_3R_119() { + if (jj_scan_token(74)) return true; + return false; + } + + private boolean jj_3_4() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + if (jj_scan_token(58)) return true; + return false; + } + + private boolean jj_3_3() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + if (jj_scan_token(40)) return true; + return false; + } + + private boolean jj_3_2() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + return false; + } + + private boolean jj_3R_156() { + if (jj_scan_token(70)) return true; + return false; + } + + private boolean jj_3R_142() { + if (jj_3R_149()) return true; + return false; + } + + private boolean jj_3_1() { + if (jj_scan_token(IDENT)) return true; + if (jj_3R_41()) return true; + if (jj_3R_42()) return true; + if (jj_scan_token(35)) return true; + return false; + } + + private boolean jj_3R_141() { + if (jj_scan_token(66)) return true; + if (jj_3R_148()) return true; + if (jj_scan_token(67)) return true; + return false; + } + + private boolean jj_3R_140() { + if (jj_scan_token(62)) return true; + if (jj_3R_47()) return true; + if (jj_scan_token(63)) return true; + return false; + } + + private boolean jj_3R_138() { + if (jj_3R_146()) return true; + return false; + } + + private boolean jj_3R_104() { + if (jj_scan_token(26)) return true; + return false; + } + + private boolean jj_3R_139() { + if (jj_3R_147()) return true; + return false; + } + + private boolean jj_3R_137() { + if (jj_scan_token(33)) return true; + return false; + } + + private boolean jj_3R_133() { + if (jj_scan_token(UNSIGNED_NUMBER)) return true; + return false; + } + + private boolean jj_3R_130() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_133()) { + jj_scanpos = xsp; + if (jj_3R_134()) { + jj_scanpos = xsp; + if (jj_3R_135()) { + jj_scanpos = xsp; + if (jj_3R_136()) { + jj_scanpos = xsp; + if (jj_3R_137()) { + jj_scanpos = xsp; + if (jj_3R_138()) { + jj_scanpos = xsp; + if (jj_3R_139()) { + jj_scanpos = xsp; + if (jj_3R_140()) { + jj_scanpos = xsp; + if (jj_3R_141()) { + jj_scanpos = xsp; + if (jj_3R_142()) { + jj_scanpos = xsp; + if (jj_scan_token(35)) return true; + } + } + } + } + } + } + } + } + } + } + return false; + } + + private boolean jj_3R_136() { + if (jj_scan_token(6)) return true; + return false; + } + + private boolean jj_3R_145() { + if (jj_scan_token(83)) return true; + return false; + } + + private boolean jj_3R_143() { + if (jj_scan_token(87)) return true; + if (jj_3R_130()) return true; + return false; + } + + private boolean jj_3R_135() { + if (jj_scan_token(STRING)) return true; + return false; + } + + private boolean jj_3R_134() { + if (jj_scan_token(UNSIGNED_INTEGER)) return true; + return false; + } + + private boolean jj_3R_124() { + if (jj_scan_token(42)) return true; + return false; + } + + private boolean jj_3R_131() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(86)) { + jj_scanpos = xsp; + if (jj_3R_143()) return true; + } + return false; + } + + private boolean jj_3R_149() { + if (jj_scan_token(64)) return true; + if (jj_3R_157()) return true; + if (jj_scan_token(65)) return true; + return false; + } + + private boolean jj_3R_129() { + if (jj_scan_token(79)) return true; + return false; + } + + private boolean jj_3R_148() { + if (jj_3R_155()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_156()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_150() { + if (jj_3R_60()) return true; + return false; + } + + private boolean jj_3R_118() { + if (jj_scan_token(73)) return true; + return false; + } + + private boolean jj_3R_99() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(30)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(47)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(34)) { + jj_scanpos = xsp; + if (jj_scan_token(7)) { + jj_scanpos = xsp; + if (jj_scan_token(61)) { + jj_scanpos = xsp; + if (jj_scan_token(24)) { + jj_scanpos = xsp; + if (jj_3R_103()) { + jj_scanpos = xsp; + if (jj_scan_token(38)) { + jj_scanpos = xsp; + if (jj_scan_token(37)) { + jj_scanpos = xsp; + if (jj_3R_104()) { + jj_scanpos = xsp; + if (jj_scan_token(17)) { + jj_scanpos = xsp; + if (jj_scan_token(94)) { + jj_scanpos = xsp; + if (jj_scan_token(95)) return true; + } + } + } + } + } + } + } + } + } + } + return false; + } + + private boolean jj_3R_115() { + if (jj_3R_130()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_131()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_146() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_150()) { + jj_scanpos = xsp; + if (jj_3R_151()) { + jj_scanpos = xsp; + if (jj_3R_152()) return true; + } + } + if (jj_3R_74()) return true; + return false; + } + + private boolean jj_3R_116() { + if (jj_3R_132()) return true; + if (jj_3R_115()) return true; + return false; + } + + private boolean jj_3R_109() { + if (jj_3R_114()) return true; + if (jj_3R_108()) return true; + return false; + } + + private boolean jj_3R_102() { + if (jj_3R_110()) return true; + if (jj_3R_101()) return true; + return false; + } + + private boolean jj_3R_144() { + if (jj_scan_token(82)) return true; + return false; + } + + private boolean jj_3R_132() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_144()) { + jj_scanpos = xsp; + if (jj_3R_145()) { + jj_scanpos = xsp; + if (jj_scan_token(84)) { + jj_scanpos = xsp; + if (jj_scan_token(85)) return true; + } + } + } + return false; + } + + private boolean jj_3R_106() { + if (jj_3R_60()) return true; + return false; + } + + private boolean jj_3R_108() { + if (jj_3R_115()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_116()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_70() { + if (jj_scan_token(31)) return true; + if (jj_3R_47()) return true; + return false; + } + + private boolean jj_3R_128() { + if (jj_scan_token(78)) return true; + return false; + } + + private boolean jj_3R_127() { + if (jj_scan_token(56)) return true; + return false; + } + + private boolean jj_3R_114() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_128()) { + jj_scanpos = xsp; + if (jj_3R_129()) { + jj_scanpos = xsp; + if (jj_scan_token(80)) { + jj_scanpos = xsp; + if (jj_scan_token(81)) return true; + } + } + } + return false; + } + + private boolean jj_3_7() { + if (jj_3R_44()) return true; + return false; + } + + private boolean jj_3R_95() { + if (jj_scan_token(9)) return true; + if (jj_3R_94()) return true; + return false; + } + + private boolean jj_3R_107() { + if (jj_3R_114()) return true; + return false; + } + + private boolean jj_3R_126() { + if (jj_scan_token(32)) return true; + return false; + } + + private boolean jj_3R_113() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_126()) { + jj_scanpos = xsp; + if (jj_3R_127()) return true; + } + return false; + } + + private boolean jj_3R_101() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_107()) jj_scanpos = xsp; + if (jj_3R_108()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_109()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_123() { + if (jj_scan_token(5)) return true; + return false; + } + + private boolean jj_3R_117() { + if (jj_scan_token(72)) return true; + return false; + } + + private boolean jj_3R_112() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_123()) { + jj_scanpos = xsp; + if (jj_3R_124()) { + jj_scanpos = xsp; + if (jj_3R_125()) return true; + } + } + return false; + } + + private boolean jj_3R_110() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_117()) { + jj_scanpos = xsp; + if (jj_3R_118()) { + jj_scanpos = xsp; + if (jj_3R_119()) { + jj_scanpos = xsp; + if (jj_3R_120()) { + jj_scanpos = xsp; + if (jj_3R_121()) { + jj_scanpos = xsp; + if (jj_3R_122()) return true; + } + } + } + } + } + return false; + } + + private boolean jj_3R_111() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(16)) { + jj_scanpos = xsp; + if (jj_scan_token(23)) return true; + } + return false; + } + + private boolean jj_3R_76() { + if (jj_scan_token(69)) return true; + if (jj_3R_75()) return true; + return false; + } + + private boolean jj_3R_87() { + if (jj_scan_token(22)) return true; + if (jj_3R_86()) return true; + return false; + } + + private boolean jj_3R_105() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_111()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_112()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_113()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_98() { + if (jj_3R_101()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_102()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_67() { + if (jj_3R_81()) return true; + return false; + } + + private boolean jj_3R_62() { + if (jj_3R_79()) return true; + return false; + } + + private boolean jj_3R_94() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(12)) jj_scanpos = xsp; + if (jj_3R_98()) return true; + return false; + } + + private boolean jj_3R_58() { + if (jj_scan_token(IDENT)) return true; + if (jj_3R_74()) return true; + return false; + } + + private boolean jj_3R_57() { + if (jj_3R_73()) return true; + return false; + } + + private boolean jj_3R_56() { + if (jj_3R_72()) return true; + return false; + } + + private boolean jj_3R_55() { + if (jj_3R_71()) return true; + return false; + } + + private boolean jj_3R_86() { + if (jj_3R_94()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_95()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_54() { + if (jj_3R_70()) return true; + return false; + } + + private boolean jj_3R_75() { + if (jj_3R_86()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_87()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3_8() { + if (jj_3R_45()) return true; + return false; + } + + private boolean jj_3R_59() { + if (jj_3R_75()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_76()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_66() { + if (jj_3R_80()) return true; + return false; + } + + private boolean jj_3R_100() { + if (jj_3R_105()) return true; + if (jj_3R_106()) return true; + return false; + } + + private boolean jj_3R_61() { + if (jj_3R_59()) return true; + return false; + } + + private boolean jj_3R_47() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_61()) { + jj_scanpos = xsp; + if (jj_3R_62()) return true; + } + return false; + } + + private boolean jj_3R_165() { + if (jj_3R_47()) return true; + return false; + } + + private boolean jj_3R_44() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_8()) { + jj_scanpos = xsp; + if (jj_3R_54()) { + jj_scanpos = xsp; + if (jj_3R_55()) { + jj_scanpos = xsp; + if (jj_3R_56()) { + jj_scanpos = xsp; + if (jj_3R_57()) { + jj_scanpos = xsp; + if (jj_3R_58()) return true; + } + } + } + } + } + return false; + } + + private boolean jj_3R_68() { + if (jj_scan_token(14)) return true; + return false; + } + + private boolean jj_3R_97() { + if (jj_3R_100()) return true; + return false; + } + + private boolean jj_3R_79() { + if (jj_scan_token(31)) return true; + if (jj_3R_47()) return true; + return false; + } + + private boolean jj_3R_154() { + if (jj_scan_token(68)) return true; + if (jj_scan_token(IDENT)) return true; + return false; + } + + private boolean jj_3_6() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + return false; + } + + private boolean jj_3R_64() { + if (jj_scan_token(21)) return true; + return false; + } + + private boolean jj_3R_49() { + if (jj_scan_token(STRING)) return true; + return false; + } + + private boolean jj_3R_90() { + if (jj_scan_token(55)) return true; + return false; + } + + private boolean jj_3R_122() { + if (jj_scan_token(77)) return true; + return false; + } + + private boolean jj_3R_45() { + if (jj_3R_59()) return true; + if (jj_scan_token(88)) return true; + if (jj_3R_47()) return true; + return false; + } + + private boolean jj_3R_81() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(46)) jj_scanpos = xsp; + if (jj_scan_token(4)) return true; + return false; + } + + private boolean jj_3R_41() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_49()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_88() { + if (jj_scan_token(46)) return true; + return false; + } + + private boolean jj_3R_72() { + if (jj_scan_token(39)) return true; + if (jj_scan_token(62)) return true; + return false; + } + + private boolean jj_3R_89() { + if (jj_scan_token(36)) return true; + return false; + } + + private boolean jj_3R_80() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_88()) jj_scanpos = xsp; + if (jj_scan_token(45)) return true; + return false; + } + + private boolean jj_3R_92() { + if (jj_scan_token(13)) return true; + return false; + } + + private boolean jj_3R_65() { + if (jj_scan_token(52)) return true; + return false; + } + + private boolean jj_3R_96() { + if (jj_3R_99()) return true; + return false; + } + + private boolean jj_3R_91() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_96()) { + jj_scanpos = xsp; + if (jj_3R_97()) return true; + } + return false; + } + + private boolean jj_3R_164() { + if (jj_scan_token(69)) return true; + return false; + } + + private boolean jj_3R_84() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(8)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(11)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(51)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(27)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_91()) { + jj_scanpos = xsp; + if (jj_3R_92()) return true; + } + return false; + } + + private boolean jj_3R_162() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_164()) { + jj_scanpos = xsp; + if (jj_3R_165()) return true; + } + return false; + } + + private boolean jj_3R_160() { + if (jj_scan_token(71)) return true; + return false; + } + + private boolean jj_3R_83() { + if (jj_3R_90()) return true; + return false; + } + + private boolean jj_3R_153() { + if (jj_3R_159()) return true; + return false; + } + + private boolean jj_3R_82() { + if (jj_3R_89()) return true; + return false; + } + + private boolean jj_3R_159() { + if (jj_scan_token(66)) return true; + if (jj_3R_162()) return true; + return false; + } + + private boolean jj_3R_63() { + if (jj_scan_token(71)) return true; + return false; + } + + private boolean jj_3R_48() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_63()) { + jj_scanpos = xsp; + if (jj_3R_64()) return true; + } + return false; + } + + private boolean jj_3R_69() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_82()) { + jj_scanpos = xsp; + if (jj_3R_83()) { + jj_scanpos = xsp; + if (jj_3R_84()) return true; + } + } + return false; + } + + private boolean jj_3R_121() { + if (jj_scan_token(76)) return true; + return false; + } + + private boolean jj_3R_53() { + if (jj_3R_69()) return true; + return false; + } + + private boolean jj_3R_43() { + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_53()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_155() { + if (jj_3R_47()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_160()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_73() { + if (jj_scan_token(43)) return true; + if (jj_3R_47()) return true; + return false; + } + + private boolean jj_3R_166() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + return false; + } + + private boolean jj_3R_152() { + if (jj_scan_token(46)) return true; + return false; + } + + private boolean jj_3R_163() { + if (jj_3R_166()) return true; + return false; + } + + private boolean jj_3R_52() { + if (jj_3R_68()) return true; + return false; + } + + private boolean jj_3R_51() { + if (jj_scan_token(59)) return true; + return false; + } + + private boolean jj_3R_161() { + if (jj_3R_163()) return true; + return false; + } + + private boolean jj_3R_50() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_5()) { + jj_scanpos = xsp; + if (jj_3R_65()) { + jj_scanpos = xsp; + if (jj_3R_66()) { + jj_scanpos = xsp; + if (jj_3R_67()) return true; + } + } + } + return false; + } + + private boolean jj_3_5() { + if (jj_scan_token(57)) return true; + if (jj_3R_43()) return true; + return false; + } + + private boolean jj_3R_93() { + if (jj_scan_token(IDENT)) return true; + return false; + } + + /** Generated Token Manager. */ + public ModelParserTokenManager token_source; + SimpleCharStream jj_input_stream; + /** Current token. */ + public Token token; + /** Next token. */ + public Token jj_nt; + private int jj_ntk; + private Token jj_scanpos, jj_lastpos; + private int jj_la; + private int jj_gen; + final private int[] jj_la1 = new int[134]; + static private int[] jj_la1_0; + static private int[] jj_la1_1; + static private int[] jj_la1_2; + static { + jj_la1_init_0(); + jj_la1_init_1(); + jj_la1_init_2(); + } + private static void jj_la1_init_0() { + jj_la1_0 = new int[] {0x0,0x0,0x45020880,0x800,0x40000000,0x0,0x0,0x5020080,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x10,0x0,0x0,0x4000,0x0,0x4000,0x0,0x80001040,0x4d8329a0,0x100,0x800,0x0,0x8000000,0x458300a0,0x458300a0,0x0,0x458320a0,0x4d8329a0,0x0,0x0,0x0,0x4000,0x0,0x0,0x810000,0x810000,0x20,0x20,0x0,0x0,0x0,0x80000000,0x0,0x0,0x0,0x0,0x2d00,0x0,0x2d00,0x400,0x800,0x2000,0x0,0x400,0x800,0x458300a0,0x458320a0,0x458300a0,0x0,0x0,0x0,0xa0240000,0x80200000,0x0,0xa0240000,0x80201040,0x100000,0x80201040,0x80201040,0x8000,0xa0240000,0x100000,0xa0240000,0xa0240000,0x8000,0x80201040,0xa0240000,0x0,0x0,0xa0240000,0x80201040,0x2000000,0x80201040,0xa0240000,0x2000000,0xa0240000,0x100000,0x80001040,0x100000,0x80001040,0x0,0x0,0x400000,0x200,0x1000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80001040,0x200000,0x200000,0x0,0x0,0x80001040,0x0,0x80001040,0x0,0x0,0x80001040,0x4000,0x0,0x0,}; + } + private static void jj_la1_init_1() { + jj_la1_1 = new int[] {0x0,0x200000,0x20049064,0x0,0x0,0x8000,0x40000,0x20041064,0x0,0x40000000,0x0,0x0,0x40000000,0x800000,0x0,0x2106000,0x106000,0x0,0x0,0x0,0x8000000,0x0,0x0,0x4400400a,0x218e9475,0x0,0x0,0x80000,0x0,0x21069465,0x21069465,0x400000,0x21069465,0x218e9475,0x0,0x0,0x40000000,0x0,0x40000000,0x0,0x0,0x0,0x20400,0x20400,0x1000001,0x1000001,0x0,0x0,0x0,0x40000000,0x0,0x40000000,0x0,0x0,0x0,0x0,0x0,0x0,0x40000000,0x0,0x0,0x21069465,0x21069465,0x21069465,0x400000,0x4000,0x4000,0x40010800,0x880,0x40000000,0x40010800,0x4400488a,0x0,0x4400488a,0x4400488a,0x0,0x40010800,0x0,0x40010800,0x40010800,0x0,0x4400488a,0x40010800,0x0,0x200,0x40010800,0x4400488a,0x0,0x4400488a,0x40010800,0x0,0x40010800,0x0,0x4400400a,0x0,0x4400400a,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4004000,0x0,0x2,0x40000008,0x0,0x0,0x0,0x0,0x0,0x0,0x4400400a,0x0,0x0,0x0,0x0,0x4400400a,0x0,0x4400400a,0x0,0x0,0x4400400a,0x0,0x0,0x0,}; + } + private static void jj_la1_init_2() { + jj_la1_2 = new int[] {0x4000010,0x0,0xc0000000,0x0,0x0,0x0,0x0,0xc0000000,0x4,0x0,0x4000000,0x80,0x0,0x0,0x80,0x0,0x0,0x8000000,0x4000010,0x0,0x0,0x0,0x4000010,0x3c03c015,0xc4000010,0x0,0x0,0x0,0x0,0xc4000010,0xc4000010,0x0,0xc4000010,0xc4000010,0x10,0x4000010,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x4,0x3000000,0x1000000,0x3000000,0x4000010,0x80,0x4000010,0x0,0x0,0x4000010,0x3000000,0x0,0x0,0xc4000010,0xc4000010,0xc4000010,0x0,0x0,0x0,0x4000010,0x4000000,0x2000000,0x4000010,0x3c03c015,0x0,0x3c03c015,0x3c03c015,0x0,0x4000010,0x0,0x4000010,0x4000010,0x0,0x3c03c015,0x4000010,0x80,0x0,0x4000010,0x3c03c015,0x0,0x3c03c015,0x4000010,0x0,0x4000010,0x0,0x3c03c015,0x0,0x3c03c015,0x20,0x20,0x0,0x0,0x0,0x3f00,0x3f00,0x3c000,0x3c000,0x3c000,0x3c0000,0x3c0000,0xc00000,0xc00000,0x4000010,0x40,0x38000000,0x4000015,0x10,0x10,0x10,0x4,0x10,0x4,0x3c03c015,0x80,0x80,0x4000000,0x80,0x3c03c015,0x80,0x3c03c015,0x80,0x80,0x3c03c035,0x0,0x4000,0x8000000,}; + } + final private JJCalls[] jj_2_rtns = new JJCalls[10]; + private boolean jj_rescan = false; + private int jj_gc = 0; + + /** Constructor with InputStream. */ + public ModelParser(java.io.InputStream stream) { + this(stream, null); + } + /** Constructor with InputStream and supplied encoding */ + public ModelParser(java.io.InputStream stream, String encoding) { + try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source = new ModelParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream, String encoding) { + try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor. */ + public ModelParser(java.io.Reader stream) { + jj_input_stream = new SimpleCharStream(stream, 1, 1); + token_source = new ModelParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor with generated Token Manager. */ + public ModelParser(ModelParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(ModelParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + jj_gen++; + if (++jj_gc > 100) { + jj_gc = 0; + for (int i = 0; i < jj_2_rtns.length; i++) { + JJCalls c = jj_2_rtns[i]; + while (c != null) { + if (c.gen < jj_gen) c.first = null; + c = c.next; + } + } + } + return token; + } + token = oldToken; + jj_kind = kind; + throw generateParseException(); + } + + static private final class LookaheadSuccess extends java.lang.Error { } + final private LookaheadSuccess jj_ls = new LookaheadSuccess(); + private boolean jj_scan_token(int kind) { + if (jj_scanpos == jj_lastpos) { + jj_la--; + if (jj_scanpos.next == null) { + jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); + } else { + jj_lastpos = jj_scanpos = jj_scanpos.next; + } + } else { + jj_scanpos = jj_scanpos.next; + } + if (jj_rescan) { + int i = 0; Token tok = token; + while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; } + if (tok != null) jj_add_error_token(kind, i); + } + if (jj_scanpos.kind != kind) return true; + if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls; + return false; + } + + +/** Get the next Token. */ + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; + } + +/** Get the specific Token. */ + final public Token getToken(int index) { + Token t = token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + private int jj_ntk() { + if ((jj_nt=token.next) == null) + return (jj_ntk = (token.next=token_source.getNextToken()).kind); + else + return (jj_ntk = jj_nt.kind); + } + + private java.util.List jj_expentries = new java.util.ArrayList(); + private int[] jj_expentry; + private int jj_kind = -1; + private int[] jj_lasttokens = new int[100]; + private int jj_endpos; + + private void jj_add_error_token(int kind, int pos) { + if (pos >= 100) return; + if (pos == jj_endpos + 1) { + jj_lasttokens[jj_endpos++] = kind; + } else if (jj_endpos != 0) { + jj_expentry = new int[jj_endpos]; + for (int i = 0; i < jj_endpos; i++) { + jj_expentry[i] = jj_lasttokens[i]; + } + jj_entries_loop: for (java.util.Iterator it = jj_expentries.iterator(); it.hasNext();) { + int[] oldentry = (int[])(it.next()); + if (oldentry.length == jj_expentry.length) { + for (int i = 0; i < jj_expentry.length; i++) { + if (oldentry[i] != jj_expentry[i]) { + continue jj_entries_loop; + } + } + jj_expentries.add(jj_expentry); + break jj_entries_loop; + } + } + if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind; + } + } + + /** Generate ParseException. */ + public ParseException generateParseException() { + jj_expentries.clear(); + boolean[] la1tokens = new boolean[96]; + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int i = 0; i < 134; i++) { + if (jj_la1[i] == jj_gen) { + for (int j = 0; j < 32; j++) { + if ((jj_la1_0[i] & (1< jj_gen) { + jj_la = p.arg; jj_lastpos = jj_scanpos = p.first; + switch (i) { + case 0: jj_3_1(); break; + case 1: jj_3_2(); break; + case 2: jj_3_3(); break; + case 3: jj_3_4(); break; + case 4: jj_3_5(); break; + case 5: jj_3_6(); break; + case 6: jj_3_7(); break; + case 7: jj_3_8(); break; + case 8: jj_3_9(); break; + case 9: jj_3_10(); break; + } + } + p = p.next; + } while (p != null); + } catch(LookaheadSuccess ls) { } + } + jj_rescan = false; + } + + private void jj_save(int index, int xla) { + JJCalls p = jj_2_rtns[index]; + while (p.gen > jj_gen) { + if (p.next == null) { p = p.next = new JJCalls(); break; } + p = p.next; + } + p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla; + } + + static final class JJCalls { + int gen; + Token first; + int arg; + JJCalls next; + } + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParserConstants.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParserConstants.java new file mode 100644 index 00000000..1f375ca7 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParserConstants.java @@ -0,0 +1,131 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. ModelParserConstants.java */ +package fi.semantum.sysdyn.solver.parser; + + +/** + * Token literal values and constants. + * Generated by org.javacc.parser.OtherFilesGen#start() + */ +public interface ModelParserConstants { + + /** End of File. */ + int EOF = 0; + /** RegularExpression Id. */ + int WHITESPACE = 1; + /** RegularExpression Id. */ + int COMMENT1 = 2; + /** RegularExpression Id. */ + int COMMENT2 = 3; + /** RegularExpression Id. */ + int IDENT = 90; + /** RegularExpression Id. */ + int STRING = 91; + /** RegularExpression Id. */ + int UNSIGNED_INTEGER = 92; + /** RegularExpression Id. */ + int UNSIGNED_NUMBER = 93; + + /** Lexical state. */ + int DEFAULT = 0; + + /** Literal token values. */ + String[] tokenImage = { + "", + "", + "", + "", + "\"algorithm\"", + "\"discrete\"", + "\"false\"", + "\"model\"", + "\"redeclare\"", + "\"and\"", + "\"each\"", + "\"final\"", + "\"not\"", + "\"replaceable\"", + "\"annotation\"", + "\"else\"", + "\"flow\"", + "\"operator\"", + "\"return\"", + "\"assert\"", + "\"elseif\"", + "\"for\"", + "\"or\"", + "\"stream\"", + "\"block\"", + "\"elsewhen\"", + "\"function\"", + "\"outer\"", + "\"then\"", + "\"break\"", + "\"encapsulated\"", + "\"if\"", + "\"output\"", + "\"true\"", + "\"class\"", + "\"end\"", + "\"import\"", + "\"package\"", + "\"type\"", + "\"connect\"", + "\"enumeration\"", + "\"in\"", + "\"parameter\"", + "\"when\"", + "\"connector\"", + "\"equation\"", + "\"initial\"", + "\"partial\"", + "\"while\"", + "\"constant\"", + "\"expandable\"", + "\"inner\"", + "\"protected\"", + "\"within\"", + "\"constrainedby\"", + "\"extends\"", + "\"input\"", + "\"public\"", + "\"der\"", + "\"external\"", + "\"loop\"", + "\"record\"", + "\"(\"", + "\")\"", + "\"{\"", + "\"}\"", + "\"[\"", + "\"]\"", + "\".\"", + "\":\"", + "\";\"", + "\",\"", + "\"<\"", + "\"<=\"", + "\">\"", + "\">=\"", + "\"==\"", + "\"<>\"", + "\"+\"", + "\"-\"", + "\".+\"", + "\".-\"", + "\"*\"", + "\"/\"", + "\".*\"", + "\"./\"", + "\"^\"", + "\".^\"", + "\"=\"", + "\":=\"", + "", + "", + "", + "", + "\"operator function\"", + "\"operator record\"", + }; + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParserTokenManager.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParserTokenManager.java new file mode 100644 index 00000000..471f3ac8 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParserTokenManager.java @@ -0,0 +1,1484 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. ModelParserTokenManager.java */ +package fi.semantum.sysdyn.solver.parser; +import java.util.ArrayList; + +/** Token Manager. */ +public class ModelParserTokenManager implements ModelParserConstants +{ + + /** Debug output. */ + public java.io.PrintStream debugStream = System.out; + /** Set debug output. */ + public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } +private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1) +{ + switch (pos) + { + case 0: + if ((active1 & 0x80000L) != 0L) + return 15; + if ((active1 & 0x8000L) != 0L) + return 37; + if ((active1 & 0xb30010L) != 0L) + return 9; + if ((active0 & 0x3ffffffffffffff0L) != 0L || (active1 & 0xc0000000L) != 0L) + { + jjmatchedKind = 90; + return 2; + } + return -1; + case 1: + if ((active1 & 0x20000L) != 0L) + return 10; + if ((active0 & 0x108420080400000L) != 0L) + return 2; + if ((active0 & 0x3ef7bdff7fbffff0L) != 0L || (active1 & 0xc0000000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 90; + jjmatchedPos = 1; + } + return 2; + } + return -1; + case 2: + if ((active0 & 0x400000800201200L) != 0L) + return 2; + if ((active0 & 0x3bfffdf77f9fedf0L) != 0L || (active1 & 0xc0000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 2; + return 2; + } + return -1; + case 3: + if ((active0 & 0x1000084212118400L) != 0L) + return 2; + if ((active0 & 0x2bfff5b56d8e69f0L) != 0L || (active1 & 0xc0000000L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 90; + jjmatchedPos = 3; + } + return 2; + } + return -1; + case 4: + if ((active0 & 0x1090004290008c0L) != 0L) + return 2; + if ((active0 & 0x2af6f5b1469e6130L) != 0L || (active1 & 0xc0000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 4; + return 2; + } + return -1; + case 5: + if ((active0 & 0x22200011009c0000L) != 0L) + return 2; + if ((active0 & 0x8d6f5a046026130L) != 0L || (active1 & 0xc0000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 5; + return 2; + } + return -1; + case 6: + if ((active0 & 0x80d0a000000000L) != 0L) + return 2; + if ((active0 & 0x856250046026130L) != 0L || (active1 & 0xc0000000L) != 0L) + { + if (jjmatchedPos != 6) + { + jjmatchedKind = 90; + jjmatchedPos = 6; + } + return 2; + } + return -1; + case 7: + if ((active0 & 0x54150040006110L) != 0L) + { + if (jjmatchedPos != 7) + { + jjmatchedKind = 90; + jjmatchedPos = 7; + } + return 2; + } + if ((active0 & 0x802200006020020L) != 0L || (active1 & 0xc0000000L) != 0L) + return 2; + return -1; + case 8: + if ((active0 & 0x10140000000110L) != 0L) + return 2; + if ((active0 & 0x44010040006000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 8; + return 2; + } + return -1; + case 9: + if ((active0 & 0x40010040002000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 9; + return 2; + } + if ((active0 & 0x4000000004000L) != 0L) + return 2; + return -1; + case 10: + if ((active0 & 0x10000002000L) != 0L) + return 2; + if ((active0 & 0x40000040000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 10; + return 2; + } + return -1; + case 11: + if ((active0 & 0x40000000L) != 0L) + return 2; + if ((active0 & 0x40000000000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 11; + return 2; + } + return -1; + case 12: + if ((active0 & 0x40000000000000L) != 0L) + return 2; + return -1; + default : + return -1; + } +} +private final int jjStartNfa_0(int pos, long active0, long active1) +{ + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1); +} +private int jjStopAtPos(int pos, int kind) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} +private int jjMoveStringLiteralDfa0_0() +{ + switch(curChar) + { + case 40: + return jjStopAtPos(0, 62); + case 41: + return jjStopAtPos(0, 63); + case 42: + return jjStopAtPos(0, 82); + case 43: + return jjStopAtPos(0, 78); + case 44: + return jjStopAtPos(0, 71); + case 45: + return jjStartNfaWithStates_0(0, 79, 37); + case 46: + jjmatchedKind = 68; + return jjMoveStringLiteralDfa1_0(0x0L, 0xb30000L); + case 47: + return jjStartNfaWithStates_0(0, 83, 15); + case 58: + jjmatchedKind = 69; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2000000L); + case 59: + return jjStopAtPos(0, 70); + case 60: + jjmatchedKind = 72; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2200L); + case 61: + jjmatchedKind = 88; + return jjMoveStringLiteralDfa1_0(0x0L, 0x1000L); + case 62: + jjmatchedKind = 74; + return jjMoveStringLiteralDfa1_0(0x0L, 0x800L); + case 91: + return jjStopAtPos(0, 66); + case 93: + return jjStopAtPos(0, 67); + case 94: + return jjStopAtPos(0, 86); + case 97: + return jjMoveStringLiteralDfa1_0(0x84210L, 0x0L); + case 98: + return jjMoveStringLiteralDfa1_0(0x21000000L, 0x0L); + case 99: + return jjMoveStringLiteralDfa1_0(0x42108400000000L, 0x0L); + case 100: + return jjMoveStringLiteralDfa1_0(0x400000000000020L, 0x0L); + case 101: + return jjMoveStringLiteralDfa1_0(0x884210842108400L, 0x0L); + case 102: + return jjMoveStringLiteralDfa1_0(0x4210840L, 0x0L); + case 105: + return jjMoveStringLiteralDfa1_0(0x108421080000000L, 0x0L); + case 108: + return jjMoveStringLiteralDfa1_0(0x1000000000000000L, 0x0L); + case 109: + return jjMoveStringLiteralDfa1_0(0x80L, 0x0L); + case 110: + return jjMoveStringLiteralDfa1_0(0x1000L, 0x0L); + case 111: + return jjMoveStringLiteralDfa1_0(0x108420000L, 0xc0000000L); + case 112: + return jjMoveStringLiteralDfa1_0(0x210842000000000L, 0x0L); + case 114: + return jjMoveStringLiteralDfa1_0(0x2000000000042100L, 0x0L); + case 115: + return jjMoveStringLiteralDfa1_0(0x800000L, 0x0L); + case 116: + return jjMoveStringLiteralDfa1_0(0x4210000000L, 0x0L); + case 119: + return jjMoveStringLiteralDfa1_0(0x21080000000000L, 0x0L); + case 123: + return jjStopAtPos(0, 64); + case 125: + return jjStopAtPos(0, 65); + default : + return jjMoveNfa_0(0, 0); + } +} +private int jjMoveStringLiteralDfa1_0(long active0, long active1) +{ + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(0, active0, active1); + return 1; + } + switch(curChar) + { + case 42: + if ((active1 & 0x100000L) != 0L) + return jjStopAtPos(1, 84); + break; + case 43: + if ((active1 & 0x10000L) != 0L) + return jjStopAtPos(1, 80); + break; + case 45: + if ((active1 & 0x20000L) != 0L) + return jjStartNfaWithStates_0(1, 81, 10); + break; + case 47: + if ((active1 & 0x200000L) != 0L) + return jjStopAtPos(1, 85); + break; + case 61: + if ((active1 & 0x200L) != 0L) + return jjStopAtPos(1, 73); + else if ((active1 & 0x800L) != 0L) + return jjStopAtPos(1, 75); + else if ((active1 & 0x1000L) != 0L) + return jjStopAtPos(1, 76); + else if ((active1 & 0x2000000L) != 0L) + return jjStopAtPos(1, 89); + break; + case 62: + if ((active1 & 0x2000L) != 0L) + return jjStopAtPos(1, 77); + break; + case 94: + if ((active1 & 0x800000L) != 0L) + return jjStopAtPos(1, 87); + break; + case 97: + return jjMoveStringLiteralDfa2_0(active0, 0x842000000440L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa2_0(active0, 0x2400000000042100L, active1, 0L); + case 102: + if ((active0 & 0x80000000L) != 0L) + return jjStartNfaWithStates_0(1, 31, 2); + break; + case 104: + return jjMoveStringLiteralDfa2_0(active0, 0x1080010000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa2_0(active0, 0x20000000000820L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa2_0(active0, 0x403118010L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa2_0(active0, 0x1000000000L, active1, 0L); + case 110: + if ((active0 & 0x20000000000L) != 0L) + { + jjmatchedKind = 41; + jjmatchedPos = 1; + } + return jjMoveStringLiteralDfa2_0(active0, 0x108410840004200L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa2_0(active0, 0x1042108000201080L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa2_0(active0, 0x20000L, active1, 0xc0000000L); + case 113: + return jjMoveStringLiteralDfa2_0(active0, 0x200000000000L, active1, 0L); + case 114: + if ((active0 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(1, 22, 2); + return jjMoveStringLiteralDfa2_0(active0, 0x10000220000000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa2_0(active0, 0x80000L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa2_0(active0, 0x800000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa2_0(active0, 0x20000010c000000L, active1, 0L); + case 120: + return jjMoveStringLiteralDfa2_0(active0, 0x884000000000000L, active1, 0L); + case 121: + return jjMoveStringLiteralDfa2_0(active0, 0x4000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(0, active0, active1); +} +private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(0, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(1, active0, active1); + return 2; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa3_0(active0, 0x400000000L, active1, 0L); + case 98: + return jjMoveStringLiteralDfa3_0(active0, 0x200000000000000L, active1, 0L); + case 99: + return jjMoveStringLiteralDfa3_0(active0, 0x2000002040000400L, active1, 0L); + case 100: + if ((active0 & 0x200L) != 0L) + return jjStartNfaWithStates_0(2, 9, 2); + else if ((active0 & 0x800000000L) != 0L) + return jjStartNfaWithStates_0(2, 35, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x180L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa3_0(active0, 0x80030020000L, active1, 0xc0000000L); + case 103: + return jjMoveStringLiteralDfa3_0(active0, 0x10L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa3_0(active0, 0x1400000000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa3_0(active0, 0x40L, active1, 0L); + case 110: + return jjMoveStringLiteralDfa3_0(active0, 0x4a108004004800L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa3_0(active0, 0x1010000001010000L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa3_0(active0, 0x104005000002000L, active1, 0L); + case 114: + if ((active0 & 0x200000L) != 0L) + return jjStartNfaWithStates_0(2, 21, 2); + else if ((active0 & 0x400000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 58, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x840000800000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa3_0(active0, 0x2188020L, active1, 0L); + case 116: + if ((active0 & 0x1000L) != 0L) + return jjStartNfaWithStates_0(2, 12, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x8a0000108040000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa3_0(active0, 0x210200000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(1, active0, active1); +} +private int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(1, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(2, active0, active1); + return 3; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa4_0(active0, 0x4240060000800L, active1, 0L); + case 99: + return jjMoveStringLiteralDfa4_0(active0, 0x5000020L, active1, 0L); + case 101: + if ((active0 & 0x8000L) != 0L) + { + jjmatchedKind = 15; + jjmatchedPos = 3; + } + else if ((active0 & 0x200000000L) != 0L) + return jjStartNfaWithStates_0(3, 33, 2); + else if ((active0 & 0x4000000000L) != 0L) + return jjStartNfaWithStates_0(3, 38, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x88800000a980180L, active1, 0L); + case 104: + if ((active0 & 0x400L) != 0L) + return jjStartNfaWithStates_0(3, 10, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x20000000000000L, active1, 0L); + case 107: + return jjMoveStringLiteralDfa4_0(active0, 0x2000000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa4_0(active0, 0x201000000002000L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa4_0(active0, 0x10000000000L, active1, 0L); + case 110: + if ((active0 & 0x10000000L) != 0L) + return jjStartNfaWithStates_0(3, 28, 2); + else if ((active0 & 0x80000000000L) != 0L) + return jjStartNfaWithStates_0(3, 43, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x108000000000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa4_0(active0, 0x2000001000004010L, active1, 0L); + case 112: + if ((active0 & 0x1000000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 60, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x100000000L, active1, 0L); + case 114: + return jjMoveStringLiteralDfa4_0(active0, 0x20000L, active1, 0xc0000000L); + case 115: + return jjMoveStringLiteralDfa4_0(active0, 0x42000400000040L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa4_0(active0, 0x10c00000000000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa4_0(active0, 0x100000000040000L, active1, 0L); + case 119: + if ((active0 & 0x10000L) != 0L) + return jjStartNfaWithStates_0(3, 16, 2); + break; + default : + break; + } + return jjStartNfa_0(2, active0, active1); +} +private int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(2, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(3, active0, active1); + return 4; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa5_0(active0, 0x2000822000L, active1, 0xc0000000L); + case 99: + return jjMoveStringLiteralDfa5_0(active0, 0x100L, active1, 0L); + case 101: + if ((active0 & 0x40L) != 0L) + return jjStartNfaWithStates_0(4, 6, 2); + else if ((active0 & 0x1000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 48, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x10118000000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa5_0(active0, 0x220c00000100000L, active1, 0L); + case 107: + if ((active0 & 0x1000000L) != 0L) + return jjStartNfaWithStates_0(4, 24, 2); + else if ((active0 & 0x20000000L) != 0L) + return jjStartNfaWithStates_0(4, 29, 2); + break; + case 108: + if ((active0 & 0x80L) != 0L) + return jjStartNfaWithStates_0(4, 7, 2); + else if ((active0 & 0x800L) != 0L) + return jjStartNfaWithStates_0(4, 11, 2); + break; + case 109: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L, active1, 0L); + case 110: + return jjMoveStringLiteralDfa5_0(active0, 0x84000000000000L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000L, active1, 0L); + case 114: + if ((active0 & 0x8000000L) != 0L) + return jjStartNfaWithStates_0(4, 27, 2); + else if ((active0 & 0x8000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 51, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x28000010000c0030L, active1, 0L); + case 115: + if ((active0 & 0x400000000L) != 0L) + return jjStartNfaWithStates_0(4, 34, 2); + break; + case 116: + if ((active0 & 0x100000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 56, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x42200004004000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa5_0(active0, 0x100000000L, active1, 0L); + case 119: + return jjMoveStringLiteralDfa5_0(active0, 0x2000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(3, active0, active1); +} +private int jjMoveStringLiteralDfa5_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(3, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(4, active0, active1); + return 5; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa6_0(active0, 0x2c00000004000L, active1, 0L); + case 99: + if ((active0 & 0x200000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 57, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x10108000002000L, active1, 0L); + case 100: + if ((active0 & 0x2000000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 61, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x84000000000000L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000020L, active1, 0L); + case 102: + if ((active0 & 0x100000L) != 0L) + return jjStartNfaWithStates_0(5, 20, 2); + break; + case 103: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000000L, active1, 0L); + case 104: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa6_0(active0, 0x200004000010L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa6_0(active0, 0x100L, active1, 0L); + case 109: + if ((active0 & 0x800000L) != 0L) + return jjStartNfaWithStates_0(5, 23, 2); + break; + case 110: + if ((active0 & 0x40000L) != 0L) + return jjStartNfaWithStates_0(5, 18, 2); + else if ((active0 & 0x20000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 53, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x800000000000000L, active1, 0L); + case 114: + return jjMoveStringLiteralDfa6_0(active0, 0x40010000000000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000L, active1, 0L); + case 116: + if ((active0 & 0x80000L) != 0L) + return jjStartNfaWithStates_0(5, 19, 2); + else if ((active0 & 0x100000000L) != 0L) + return jjStartNfaWithStates_0(5, 32, 2); + else if ((active0 & 0x1000000000L) != 0L) + return jjStartNfaWithStates_0(5, 36, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x20000L, active1, 0xc0000000L); + default : + break; + } + return jjStartNfa_0(4, active0, active1); +} +private int jjMoveStringLiteralDfa6_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(4, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(5, active0, active1); + return 6; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa7_0(active0, 0x844010000000100L, active1, 0L); + case 101: + if ((active0 & 0x2000000000L) != 0L) + return jjStartNfaWithStates_0(6, 37, 2); + return jjMoveStringLiteralDfa7_0(active0, 0x2002000L, active1, 0L); + case 108: + if ((active0 & 0x400000000000L) != 0L) + return jjStartNfaWithStates_0(6, 46, 2); + else if ((active0 & 0x800000000000L) != 0L) + return jjStartNfaWithStates_0(6, 47, 2); + break; + case 110: + return jjMoveStringLiteralDfa7_0(active0, 0x2000000000000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa7_0(active0, 0x200004020000L, active1, 0xc0000000L); + case 115: + if ((active0 & 0x80000000000000L) != 0L) + return jjStartNfaWithStates_0(6, 55, 2); + break; + case 116: + if ((active0 & 0x8000000000L) != 0L) + { + jjmatchedKind = 39; + jjmatchedPos = 6; + } + return jjMoveStringLiteralDfa7_0(active0, 0x10140000004030L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa7_0(active0, 0x40000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(5, active0, active1); +} +private int jjMoveStringLiteralDfa7_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(5, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(6, active0, active1); + return 7; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa8_0(active0, 0x2000L, active1, 0L); + case 98: + return jjMoveStringLiteralDfa8_0(active0, 0x4000000000000L, active1, 0L); + case 101: + if ((active0 & 0x20L) != 0L) + return jjStartNfaWithStates_0(7, 5, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x10040000000000L, active1, 0L); + case 104: + return jjMoveStringLiteralDfa8_0(active0, 0x10L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa8_0(active0, 0x40000000004000L, active1, 0L); + case 108: + if ((active0 & 0x800000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 59, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x40000000L, active1, 0L); + case 110: + if ((active0 & 0x2000000L) != 0L) + return jjStartNfaWithStates_0(7, 25, 2); + else if ((active0 & 0x4000000L) != 0L) + return jjStartNfaWithStates_0(7, 26, 2); + else if ((active0 & 0x200000000000L) != 0L) + return jjStartNfaWithStates_0(7, 45, 2); + break; + case 111: + return jjMoveStringLiteralDfa8_0(active0, 0x100000000000L, active1, 0L); + case 114: + if ((active0 & 0x20000L) != 0L) + { + jjmatchedKind = 17; + jjmatchedPos = 7; + } + return jjMoveStringLiteralDfa8_0(active0, 0x100L, active1, 0xc0000000L); + case 116: + if ((active0 & 0x2000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 49, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x10000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(6, active0, active1); +} +private int jjMoveStringLiteralDfa8_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(6, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(7, active0, active1); + return 8; + } + switch(curChar) + { + case 32: + return jjMoveStringLiteralDfa9_0(active0, 0L, active1, 0xc0000000L); + case 97: + return jjMoveStringLiteralDfa9_0(active0, 0x40000000L, active1, 0L); + case 98: + return jjMoveStringLiteralDfa9_0(active0, 0x2000L, active1, 0L); + case 100: + if ((active0 & 0x10000000000000L) != 0L) + return jjStartNfaWithStates_0(8, 52, 2); + break; + case 101: + if ((active0 & 0x100L) != 0L) + return jjStartNfaWithStates_0(8, 8, 2); + break; + case 105: + return jjMoveStringLiteralDfa9_0(active0, 0x10000000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa9_0(active0, 0x4000000000000L, active1, 0L); + case 109: + if ((active0 & 0x10L) != 0L) + return jjStartNfaWithStates_0(8, 4, 2); + break; + case 110: + return jjMoveStringLiteralDfa9_0(active0, 0x40000000000000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa9_0(active0, 0x4000L, active1, 0L); + case 114: + if ((active0 & 0x40000000000L) != 0L) + return jjStartNfaWithStates_0(8, 42, 2); + else if ((active0 & 0x100000000000L) != 0L) + return jjStartNfaWithStates_0(8, 44, 2); + break; + default : + break; + } + return jjStartNfa_0(7, active0, active1); +} +private int jjMoveStringLiteralDfa9_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(7, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(8, active0, active1); + return 9; + } + switch(curChar) + { + case 101: + if ((active0 & 0x4000000000000L) != 0L) + return jjStartNfaWithStates_0(9, 50, 2); + return jjMoveStringLiteralDfa10_0(active0, 0x40000000000000L, active1, 0L); + case 102: + return jjMoveStringLiteralDfa10_0(active0, 0L, active1, 0x40000000L); + case 108: + return jjMoveStringLiteralDfa10_0(active0, 0x2000L, active1, 0L); + case 110: + if ((active0 & 0x4000L) != 0L) + return jjStartNfaWithStates_0(9, 14, 2); + break; + case 111: + return jjMoveStringLiteralDfa10_0(active0, 0x10000000000L, active1, 0L); + case 114: + return jjMoveStringLiteralDfa10_0(active0, 0L, active1, 0x80000000L); + case 116: + return jjMoveStringLiteralDfa10_0(active0, 0x40000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(8, active0, active1); +} +private int jjMoveStringLiteralDfa10_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(8, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(9, active0, active1); + return 10; + } + switch(curChar) + { + case 100: + return jjMoveStringLiteralDfa11_0(active0, 0x40000000000000L, active1, 0L); + case 101: + if ((active0 & 0x2000L) != 0L) + return jjStartNfaWithStates_0(10, 13, 2); + return jjMoveStringLiteralDfa11_0(active0, 0x40000000L, active1, 0x80000000L); + case 110: + if ((active0 & 0x10000000000L) != 0L) + return jjStartNfaWithStates_0(10, 40, 2); + break; + case 117: + return jjMoveStringLiteralDfa11_0(active0, 0L, active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(9, active0, active1); +} +private int jjMoveStringLiteralDfa11_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(9, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(10, active0, active1); + return 11; + } + switch(curChar) + { + case 98: + return jjMoveStringLiteralDfa12_0(active0, 0x40000000000000L, active1, 0L); + case 99: + return jjMoveStringLiteralDfa12_0(active0, 0L, active1, 0x80000000L); + case 100: + if ((active0 & 0x40000000L) != 0L) + return jjStartNfaWithStates_0(11, 30, 2); + break; + case 110: + return jjMoveStringLiteralDfa12_0(active0, 0L, active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(10, active0, active1); +} +private int jjMoveStringLiteralDfa12_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(10, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(11, active0, active1); + return 12; + } + switch(curChar) + { + case 99: + return jjMoveStringLiteralDfa13_0(active0, 0L, active1, 0x40000000L); + case 111: + return jjMoveStringLiteralDfa13_0(active0, 0L, active1, 0x80000000L); + case 121: + if ((active0 & 0x40000000000000L) != 0L) + return jjStartNfaWithStates_0(12, 54, 2); + break; + default : + break; + } + return jjStartNfa_0(11, active0, active1); +} +private int jjMoveStringLiteralDfa13_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(11, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(12, 0L, active1); + return 13; + } + switch(curChar) + { + case 114: + return jjMoveStringLiteralDfa14_0(active1, 0x80000000L); + case 116: + return jjMoveStringLiteralDfa14_0(active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(12, 0L, active1); +} +private int jjMoveStringLiteralDfa14_0(long old1, long active1) +{ + if (((active1 &= old1)) == 0L) + return jjStartNfa_0(12, 0L, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(13, 0L, active1); + return 14; + } + switch(curChar) + { + case 100: + if ((active1 & 0x80000000L) != 0L) + return jjStopAtPos(14, 95); + break; + case 105: + return jjMoveStringLiteralDfa15_0(active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(13, 0L, active1); +} +private int jjMoveStringLiteralDfa15_0(long old1, long active1) +{ + if (((active1 &= old1)) == 0L) + return jjStartNfa_0(13, 0L, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(14, 0L, active1); + return 15; + } + switch(curChar) + { + case 111: + return jjMoveStringLiteralDfa16_0(active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(14, 0L, active1); +} +private int jjMoveStringLiteralDfa16_0(long old1, long active1) +{ + if (((active1 &= old1)) == 0L) + return jjStartNfa_0(14, 0L, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(15, 0L, active1); + return 16; + } + switch(curChar) + { + case 110: + if ((active1 & 0x40000000L) != 0L) + return jjStopAtPos(16, 94); + break; + default : + break; + } + return jjStartNfa_0(15, 0L, active1); +} +private int jjStartNfaWithStates_0(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_0(state, pos + 1); +} +static final long[] jjbitVec0 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +private int jjMoveNfa_0(int startState, int curPos) +{ + int startsAt = 0; + jjnewStateCnt = 37; + int i = 1; + jjstateSet[0] = startState; + int kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + do + { + switch(jjstateSet[--i]) + { + case 9: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(10, 11); + } + else if (curChar == 45) + jjCheckNAdd(10); + break; + case 37: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(32, 33); + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(25, 26); + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 92) + kind = 92; + jjCheckNAdd(24); + } + break; + case 0: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 92) + kind = 92; + jjCheckNAddStates(0, 4); + } + else if ((0x100002600L & l) != 0L) + { + if (kind > 1) + kind = 1; + } + else if (curChar == 45) + jjCheckNAddStates(5, 7); + else if (curChar == 47) + jjAddStates(8, 9); + else if (curChar == 46) + jjCheckNAddTwoStates(9, 10); + else if (curChar == 34) + jjCheckNAddStates(10, 12); + break; + case 15: + if (curChar == 47) + { + if (kind > 3) + kind = 3; + jjCheckNAdd(22); + } + else if (curChar == 42) + jjCheckNAddStates(13, 15); + break; + case 2: + if ((0x3ff400000000000L & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjstateSet[jjnewStateCnt++] = 2; + break; + case 3: + if (curChar == 34) + jjCheckNAddStates(10, 12); + break; + case 4: + if ((0xfffffffbfffffbffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 6: + if ((0xfffffffffffffbffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 7: + if (curChar == 34 && kind > 91) + kind = 91; + break; + case 8: + if (curChar == 46) + jjCheckNAddTwoStates(9, 10); + break; + case 10: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(10, 11); + break; + case 12: + if (curChar == 45) + jjCheckNAdd(13); + break; + case 13: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjCheckNAdd(13); + break; + case 14: + if (curChar == 47) + jjAddStates(8, 9); + break; + case 16: + if ((0xfffffbffffffffffL & l) != 0L) + jjCheckNAddStates(13, 15); + break; + case 17: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 18; + break; + case 18: + if ((0xffff7fffffffffffL & l) != 0L) + jjCheckNAddStates(13, 15); + break; + case 19: + if (curChar == 47 && kind > 2) + kind = 2; + break; + case 20: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 19; + break; + case 21: + if (curChar != 47) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(22); + break; + case 22: + if ((0xfffffffffffffbffL & l) == 0L) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(22); + break; + case 23: + if (curChar == 45) + jjCheckNAddStates(5, 7); + break; + case 24: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjCheckNAdd(24); + break; + case 25: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(25, 26); + break; + case 26: + if (curChar != 46) + break; + if (kind > 93) + kind = 93; + jjCheckNAddStates(16, 18); + break; + case 27: + if (curChar == 45) + jjCheckNAdd(28); + break; + case 28: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(28, 29); + break; + case 30: + if (curChar == 45) + jjCheckNAdd(31); + break; + case 31: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjCheckNAdd(31); + break; + case 32: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(32, 33); + break; + case 34: + if (curChar == 45) + jjCheckNAdd(35); + break; + case 35: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjCheckNAdd(35); + break; + case 36: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjCheckNAddStates(0, 4); + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 0: + case 2: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjCheckNAdd(2); + break; + case 4: + if ((0xffffffffefffffffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 5: + if (curChar == 92) + jjstateSet[jjnewStateCnt++] = 6; + break; + case 6: + jjCheckNAddStates(10, 12); + break; + case 11: + if ((0x2000000020L & l) != 0L) + jjAddStates(19, 20); + break; + case 16: + case 18: + jjCheckNAddStates(13, 15); + break; + case 22: + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 22; + break; + case 29: + if ((0x2000000020L & l) != 0L) + jjAddStates(21, 22); + break; + case 33: + if ((0x2000000020L & l) != 0L) + jjAddStates(23, 24); + break; + default : break; + } + } while(i != startsAt); + } + else + { + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 4: + case 6: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddStates(10, 12); + break; + case 16: + case 18: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddStates(13, 15); + break; + case 22: + if ((jjbitVec0[i2] & l2) == 0L) + break; + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 22; + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 37 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +static final int[] jjnextStates = { + 24, 25, 26, 32, 33, 24, 25, 32, 15, 21, 4, 5, 7, 16, 17, 20, + 27, 28, 29, 12, 13, 30, 31, 34, 35, +}; + +/** Token literal values. */ +public static final String[] jjstrLiteralImages = { +"", null, null, null, "\141\154\147\157\162\151\164\150\155", +"\144\151\163\143\162\145\164\145", "\146\141\154\163\145", "\155\157\144\145\154", +"\162\145\144\145\143\154\141\162\145", "\141\156\144", "\145\141\143\150", "\146\151\156\141\154", "\156\157\164", +"\162\145\160\154\141\143\145\141\142\154\145", "\141\156\156\157\164\141\164\151\157\156", "\145\154\163\145", +"\146\154\157\167", "\157\160\145\162\141\164\157\162", "\162\145\164\165\162\156", +"\141\163\163\145\162\164", "\145\154\163\145\151\146", "\146\157\162", "\157\162", +"\163\164\162\145\141\155", "\142\154\157\143\153", "\145\154\163\145\167\150\145\156", +"\146\165\156\143\164\151\157\156", "\157\165\164\145\162", "\164\150\145\156", "\142\162\145\141\153", +"\145\156\143\141\160\163\165\154\141\164\145\144", "\151\146", "\157\165\164\160\165\164", "\164\162\165\145", +"\143\154\141\163\163", "\145\156\144", "\151\155\160\157\162\164", "\160\141\143\153\141\147\145", +"\164\171\160\145", "\143\157\156\156\145\143\164", +"\145\156\165\155\145\162\141\164\151\157\156", "\151\156", "\160\141\162\141\155\145\164\145\162", "\167\150\145\156", +"\143\157\156\156\145\143\164\157\162", "\145\161\165\141\164\151\157\156", "\151\156\151\164\151\141\154", +"\160\141\162\164\151\141\154", "\167\150\151\154\145", "\143\157\156\163\164\141\156\164", +"\145\170\160\141\156\144\141\142\154\145", "\151\156\156\145\162", "\160\162\157\164\145\143\164\145\144", +"\167\151\164\150\151\156", "\143\157\156\163\164\162\141\151\156\145\144\142\171", +"\145\170\164\145\156\144\163", "\151\156\160\165\164", "\160\165\142\154\151\143", "\144\145\162", +"\145\170\164\145\162\156\141\154", "\154\157\157\160", "\162\145\143\157\162\144", "\50", "\51", "\173", "\175", +"\133", "\135", "\56", "\72", "\73", "\54", "\74", "\74\75", "\76", "\76\75", +"\75\75", "\74\76", "\53", "\55", "\56\53", "\56\55", "\52", "\57", "\56\52", "\56\57", +"\136", "\56\136", "\75", "\72\75", null, null, null, null, +"\157\160\145\162\141\164\157\162\40\146\165\156\143\164\151\157\156", "\157\160\145\162\141\164\157\162\40\162\145\143\157\162\144", }; + +/** Lexer state names. */ +public static final String[] lexStateNames = { + "DEFAULT", +}; +static final long[] jjtoToken = { + 0xfffffffffffffff1L, 0xffffffffL, +}; +static final long[] jjtoSkip = { + 0xeL, 0x0L, +}; +protected SimpleCharStream input_stream; +private final int[] jjrounds = new int[37]; +private final int[] jjstateSet = new int[74]; +private final StringBuilder jjimage = new StringBuilder(); +private StringBuilder image = jjimage; +private int jjimageLen; +private int lengthOfMatch; +protected char curChar; +/** Constructor. */ +public ModelParserTokenManager(SimpleCharStream stream){ + if (SimpleCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + input_stream = stream; +} + +/** Constructor. */ +public ModelParserTokenManager(SimpleCharStream stream, int lexState){ + this(stream); + SwitchTo(lexState); +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream) +{ + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); +} +private void ReInitRounds() +{ + int i; + jjround = 0x80000001; + for (i = 37; i-- > 0;) + jjrounds[i] = 0x80000000; +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream, int lexState) +{ + ReInit(stream); + SwitchTo(lexState); +} + +/** Switch to specified lex state. */ +public void SwitchTo(int lexState) +{ + if (lexState >= 1 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); + else + curLexState = lexState; +} + +protected Token jjFillToken() +{ + final Token t; + final String curTokenImage; + final int beginLine; + final int endLine; + final int beginColumn; + final int endColumn; + String im = jjstrLiteralImages[jjmatchedKind]; + curTokenImage = (im == null) ? input_stream.GetImage() : im; + beginLine = input_stream.getBeginLine(); + beginColumn = input_stream.getBeginColumn(); + endLine = input_stream.getEndLine(); + endColumn = input_stream.getEndColumn(); + t = Token.newToken(jjmatchedKind, curTokenImage); + + t.beginLine = beginLine; + t.endLine = endLine; + t.beginColumn = beginColumn; + t.endColumn = endColumn; + + return t; +} + +int curLexState = 0; +int defaultLexState = 0; +int jjnewStateCnt; +int jjround; +int jjmatchedPos; +int jjmatchedKind; + +/** Get the next Token. */ +public Token getNextToken() +{ + Token matchedToken; + int curPos = 0; + + EOFLoop : + for (;;) + { + try + { + curChar = input_stream.BeginToken(); + } + catch(java.io.IOException e) + { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + } + image = jjimage; + image.setLength(0); + jjimageLen = 0; + + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + if (jjmatchedKind != 0x7fffffff) + { + if (jjmatchedPos + 1 < curPos) + input_stream.backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) + { + matchedToken = jjFillToken(); + TokenLexicalActions(matchedToken); + return matchedToken; + } + else + { + continue EOFLoop; + } + } + int error_line = input_stream.getEndLine(); + int error_column = input_stream.getEndColumn(); + String error_after = null; + boolean EOFSeen = false; + try { input_stream.readChar(); input_stream.backup(1); } + catch (java.io.IOException e1) { + EOFSeen = true; + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + if (curChar == '\n' || curChar == '\r') { + error_line++; + error_column = 0; + } + else + error_column++; + } + if (!EOFSeen) { + input_stream.backup(1); + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + } + throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); + } +} + +void TokenLexicalActions(Token matchedToken) +{ + switch(jjmatchedKind) + { + case 91 : + image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); + matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); + break; + default : + break; + } +} +private void jjCheckNAdd(int state) +{ + if (jjrounds[state] != jjround) + { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } +} +private void jjAddStates(int start, int end) +{ + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); +} +private void jjCheckNAddTwoStates(int state1, int state2) +{ + jjCheckNAdd(state1); + jjCheckNAdd(state2); +} + +private void jjCheckNAddStates(int start, int end) +{ + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); +} + +} diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParserTreeConstants.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParserTreeConstants.java new file mode 100644 index 00000000..39cc66d4 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelParserTreeConstants.java @@ -0,0 +1,173 @@ +/* Generated By:JavaCC: Do not edit this line. ModelParserTreeConstants.java Version 5.0 */ +package fi.semantum.sysdyn.solver.parser; + +public interface ModelParserTreeConstants +{ + public int JJTPARSE = 0; + public int JJTSTORED = 1; + public int JJTCLASS_DEFINITION = 2; + public int JJTCLASS_SPECIFIER = 3; + public int JJTBASE_PREFIX = 4; + public int JJTENUM_LIST = 5; + public int JJTENUMERATION_LITERAL = 6; + public int JJTPARSE_COMPOSITION = 7; + public int JJTCOMPOSITION = 8; + public int JJTLANGUAGE_SPECIFICATION = 9; + public int JJTEXTERNAL_FUNCTION_CALL = 10; + public int JJTELEMENT_LIST = 11; + public int JJTELEMENT = 12; + public int JJTIMPORT_CLAUSE = 13; + public int JJTEXTENDS_CLAUSE = 14; + public int JJTCONSTRAINING_CLAUSE = 15; + public int JJTCOMPONENT_CLAUSE = 16; + public int JJTTYPE_PREFIX = 17; + public int JJTTYPE_SPECIFIER = 18; + public int JJTCOMPONENT_LIST = 19; + public int JJTCOMPONENT_DECLARATION = 20; + public int JJTCONDITIONAL_ATTRIBUTE = 21; + public int JJTDECLARATION = 22; + public int JJTMODIFICATION = 23; + public int JJTCLASS_MODIFICATION = 24; + public int JJTARGUMENT_LIST = 25; + public int JJTARGUMENT = 26; + public int JJTELEMENT_MODIFICATION_OR_REPLACEABLE = 27; + public int JJTELEMENT_MODIFICATION = 28; + public int JJTELEMENT_REDECLARATION = 29; + public int JJTELEMENT_REPLACEABLE = 30; + public int JJTCOMPONENT_CLAUSE1 = 31; + public int JJTCOMPONENT_DECLARATION1 = 32; + public int JJTEQUATION_SECTION = 33; + public int JJTALGORITHM_SECTION = 34; + public int JJTASSIGNMENT = 35; + public int JJTEQUATION = 36; + public int JJTSTATEMENT = 37; + public int JJTIF_EQUATION = 38; + public int JJTTHEN_STATEMENT = 39; + public int JJTELSEIF_STATEMENT = 40; + public int JJTELSE_STATEMENT = 41; + public int JJTIF_STATEMENT = 42; + public int JJTFOR_EQUATION = 43; + public int JJTFOR_STATEMENT = 44; + public int JJTFOR_INDICES = 45; + public int JJTFOR_INDEX = 46; + public int JJTWHILE_STATEMENT = 47; + public int JJTWHEN_EQUATION = 48; + public int JJTWHEN_STATEMENT = 49; + public int JJTCONNECT_CLAUSE = 50; + public int JJTEXPR = 51; + public int JJTIF_EXPRESSION = 52; + public int JJTEXPRESSION = 53; + public int JJTSIMPLE_EXPRESSION = 54; + public int JJTLOGICAL_EXPRESSION = 55; + public int JJTLOGICAL_TERM = 56; + public int JJTLOGICAL_FACTOR = 57; + public int JJTRELATION = 58; + public int JJTREL_OP = 59; + public int JJTARITHMETIC_EXPRESSION = 60; + public int JJTADD_OP = 61; + public int JJTTERM = 62; + public int JJTMUL_OP = 63; + public int JJTFACTOR = 64; + public int JJTDER_INITIAL = 65; + public int JJTSUBSCRIPT_2 = 66; + public int JJTARRAY = 67; + public int JJTPRIMARY = 68; + public int JJTNAME = 69; + public int JJTCOMPONENT_REFERENCE = 70; + public int JJTFUNCTION_CALL_ARGS = 71; + public int JJTFUNCTION_ARGUMENTS = 72; + public int JJTNAMED_ARGUMENTS = 73; + public int JJTNAMED_ARGUMENT = 74; + public int JJTOUTPUT_EXPRESSION_LIST = 75; + public int JJTEXPRESSION_LIST = 76; + public int JJTARRAY_SUBSCRIPTS = 77; + public int JJTSUBSCRIPT = 78; + public int JJTVOID = 79; + public int JJTANNOTATION = 80; + + + public String[] jjtNodeName = { + "parse", + "STORED", + "class_definition", + "class_specifier", + "base_prefix", + "enum_list", + "enumeration_literal", + "parse_composition", + "composition", + "language_specification", + "external_function_call", + "element_list", + "element", + "import_clause", + "extends_clause", + "constraining_clause", + "component_clause", + "type_prefix", + "type_specifier", + "component_list", + "component_declaration", + "conditional_attribute", + "declaration", + "modification", + "class_modification", + "argument_list", + "argument", + "element_modification_or_replaceable", + "element_modification", + "element_redeclaration", + "element_replaceable", + "component_clause1", + "component_declaration1", + "equation_section", + "algorithm_section", + "assignment", + "equation", + "statement", + "if_equation", + "then_statement", + "elseif_statement", + "else_statement", + "if_statement", + "for_equation", + "for_statement", + "for_indices", + "for_index", + "while_statement", + "when_equation", + "when_statement", + "connect_clause", + "expr", + "if_expression", + "expression", + "simple_expression", + "logical_expression", + "logical_term", + "logical_factor", + "relation", + "rel_op", + "arithmetic_expression", + "add_op", + "term", + "mul_op", + "factor", + "der_initial", + "subscript_2", + "array", + "primary", + "name", + "component_reference", + "function_call_args", + "function_arguments", + "named_arguments", + "named_argument", + "output_expression_list", + "expression_list", + "array_subscripts", + "subscript", + "void", + "annotation", + }; +} +/* JavaCC - OriginalChecksum=2406c3a5da0aa9cd9047b868bc6069b1 (do not edit this line) */ diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jj b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jj new file mode 100644 index 00000000..990cfd10 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jj @@ -0,0 +1,2922 @@ +/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. ModelicaParser.jj */ +/*@egen*/options { + JDK_VERSION = "1.6"; + STATIC = false; +} + +PARSER_BEGIN(ModelParser) +package fi.semantum.sysdyn.solver.parser; + +import java.util.ArrayList; + +public class ModelParser/*@bgen(jjtree)*/implements ModelParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/ + protected JJTModelParserState jjtree = new JJTModelParserState(); + +/*@egen*/ + + private ArrayList inputs = new ArrayList(); + private ArrayList outputs = new ArrayList(); + + private enum InterfaceVariableType { INPUT, OUTPUT, OTHER + } + + public class Parameter { + public String name; + public boolean optional; + public String description; + public String type; + + public Parameter() { + name = new String(""); + optional = false; + description = null; + type = null; + } } + + public ArrayList getInputs() + { + return inputs; + } + + public ArrayList getOutputs() + { + return outputs; + } + +} + +PARSER_END(ModelParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ +"algorithm" | "discrete" | "false" | "model" | "redeclare" +| "and" | "each" | "final" | "not" | "replaceable" +| "annotation" | "else" | "flow" | "operator" | "return" +|"assert" | "elseif" | "for" | "or" | "stream" +| "block" | "elsewhen" | "function" | "outer" | "then" +| "break" | "encapsulated" | "if" | "output" | "true" +| "class" | "end" | "import" | "package" | "type" +| "connect" | "enumeration" | "in" | "parameter" | "when" +| "connector" | "equation" | "initial" | "partial" | "while" +| "constant" | "expandable" | "inner" | "protected" | "within" +| "constrainedby" | "extends" | "input" | "public" +| "der" | "external" | "loop" | "record" +| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | "," +| "<" | "<=" | ">" | ">=" | "==" | "<>" +| "+" | "-" | ".+" | ".-" +| "*" | "/" | ".*" | "./" +| "^" | ".^" +| "=" | ":=" +| +| + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +| +| "." ()? (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +} + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + +Node parse() : {/*@bgen(jjtree) parse */ + SimpleNode jjtn000 = new SimpleNode(JJTPARSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) parse */ + try { +/*@egen*/ + stored_definition() /*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { return jjtn000; }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +/*** Stored Definition - Within ************************************/ + +Node stored_definition() : {/*@bgen(jjtree) STORED */ + SimpleNode jjtn000 = new SimpleNode(JJTSTORED); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) STORED */ + try { +/*@egen*/ +// stored_definition: +// [ within [ name ] ";" ] +// { [ final ] class_definition ";" } + ( "within" ( name() )? ";" )? + ( ( "final" )? class_definition() ";" )*/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { return jjtn000; }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +/*** Class Definition **********************************************/ + +void class_definition() : {/*@bgen(jjtree) class_definition */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASS_DEFINITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) class_definition */ + try { +/*@egen*/ +// class_definition : +// [ encapsulated ] +// [ partial +// ] ( class modelrecordblock expandableconnectortype +// | | | | [ ] | | package | function | operator | operator function | operator record ) +// class_specifier + ( "encapsulated" )? + ( "partial" )? + ( "class" | "model" | "record" | "block" | ( "expandable" )? "connector" | "type" | + "package" | "function" { jjtn000.op = "function"; } | "operator" | "operator function" | "operator record" ) + class_specifier()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + + +void class_specifier() : {/*@bgen(jjtree) class_specifier */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASS_SPECIFIER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ Token t; +} {/*@bgen(jjtree) class_specifier */ + try { +/*@egen*/ +// class_specifier : +// IDENT string_comment composition end IDENT +// | IDENT "=" base_prefix name [ array_subscripts ] +// [ class_modification ] comment +// | IDENT "=" enumeration "(" ( [enum_list] | ":" ) ")" comment +// | IDENT "=" der "(" name "," IDENT { "," IDENT } ")" comment +// | extends IDENT [ class_modification ] string_comment composition +// end IDENT + LOOKAHEAD(2) t= { jjtn000.op = t.image; } string_comment() composition() "end" + | LOOKAHEAD(2) "=" base_prefix() name() ( array_subscripts() )? ( class_modification() )? comment() + | LOOKAHEAD(3) "=" "enumeration" "(" ( ( enum_list() )? | ":" ) ")" comment() + |LOOKAHEAD(3) "=" "der" "(" name() "," ( "," )* ")" comment() + | "extends" ( class_modification() )? string_comment() composition() "end" /*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void base_prefix() : {/*@bgen(jjtree) base_prefix */ + SimpleNode jjtn000 = new SimpleNode(JJTBASE_PREFIX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) base_prefix */ + try { +/*@egen*/ + type_prefix()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void enum_list() : {/*@bgen(jjtree) enum_list */ + SimpleNode jjtn000 = new SimpleNode(JJTENUM_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) enum_list */ + try { +/*@egen*/ +// enumeration_literal { "," enumeration_literal} + enumeration_literal() ( "," enumeration_literal() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void enumeration_literal() : {/*@bgen(jjtree) enumeration_literal */ + SimpleNode jjtn000 = new SimpleNode(JJTENUMERATION_LITERAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) enumeration_literal */ + try { +/*@egen*/ + comment()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void parse_composition() : {/*@bgen(jjtree) parse_composition */ + SimpleNode jjtn000 = new SimpleNode(JJTPARSE_COMPOSITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) parse_composition */ + try { +/*@egen*/ + composition() /*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void composition() : {/*@bgen(jjtree) composition */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPOSITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) composition */ + try { +/*@egen*/ +// element_list +// { public element_list | +// protected element_list | +// equation_section | +// algorithm_section +// } +// [ external [ language_specification ] +// [ external_function_call ] [ annotation ] ";" ] +// [ annotation ";" ] + element_list() + ( LOOKAHEAD(2) "public" element_list() | "protected" element_list() | equation_section() | algorithm_section() )* + ( "external" ( language_specification() )? ( external_function_call() )? ( annotation() )? ";" )? + ( annotation() ";" )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void language_specification() : {/*@bgen(jjtree) language_specification */ + SimpleNode jjtn000 = new SimpleNode(JJTLANGUAGE_SPECIFICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) language_specification */ + try { +/*@egen*/ + /*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void external_function_call() : {/*@bgen(jjtree) external_function_call */ + SimpleNode jjtn000 = new SimpleNode(JJTEXTERNAL_FUNCTION_CALL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) external_function_call */ + try { +/*@egen*/ +// [ component_reference "=" ] +// IDENT "(" [ expression_list ] ")" + ( component_reference() "=" )? + "(" ( expression_list() )? ")"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void element_list() : {/*@bgen(jjtree) element_list */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) element_list */ + try { +/*@egen*/ + ( element() ";" )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +Node element() : {/*@bgen(jjtree) element */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) element */ + try { +/*@egen*/ +// import_clause | +// extends_clause | +// [ redeclare ] +// [ final ] +// [ inner ] [ outer ] +// ( ( class_definition | component_clause) | +// replaceable ( class_definition | component_clause) +// [constraining_clause comment]) + import_clause() | + extends_clause() | + ( "redeclare" )? + ( "final" )? + ( "inner" )? ( "outer" )? + ( (class_definition() | component_clause()) | + "replaceable" (class_definition() | component_clause()) + (constraining_clause() comment())?)/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { return jjtn000; }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void import_clause() : {/*@bgen(jjtree) import_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTIMPORT_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) import_clause */ + try { +/*@egen*/ +// import ( IDENT "=" name | name ["." "*"] ) comment + "import" (LOOKAHEAD(2) "=" name() | name() ("." "*")? ) comment()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +/*** Extends *******************************************************/ +void extends_clause() : {/*@bgen(jjtree) extends_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTEXTENDS_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) extends_clause */ + try { +/*@egen*/ +// extends name [ class_modification ] [annotation] + "extends" name() ( class_modification() )? ( annotation() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void constraining_clause() : {/*@bgen(jjtree) constraining_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTCONSTRAINING_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) constraining_clause */ + try { +/*@egen*/ +// constrainedby name [ class_modification ] + "constrainedby" name() ( class_modification() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +/*** Component Clause **********************************************/ +void component_clause() : {/*@bgen(jjtree) component_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ + InterfaceVariableType ioType = InterfaceVariableType.OTHER; + String typeSpecifier = ""; + //String arraySubscripts = null; + ArrayList componentList = new ArrayList(); +} {/*@bgen(jjtree) component_clause */ + try { +/*@egen*/ + +// type_prefix type_specifier [ array_subscripts ] component_list + ( ioType = type_prefix() ) + ( typeSpecifier = type_specifier() ) + ( /*arraySubscripts =*/ array_subscripts() )? + ( componentList = component_list() )/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { + if (ioType == InterfaceVariableType.INPUT) { + for (Parameter input : componentList) { + input.type = typeSpecifier; + inputs.add(input); } + } else if (ioType == InterfaceVariableType.OUTPUT) { + for (Parameter output : componentList) { + output.type = typeSpecifier; + outputs.add(output); + } + } + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +InterfaceVariableType type_prefix() : {/*@bgen(jjtree) type_prefix */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPE_PREFIX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ + InterfaceVariableType type = InterfaceVariableType.OTHER; +} {/*@bgen(jjtree) type_prefix */ + try { +/*@egen*/ +// [ flow | stream ] +// [ discrete | parameter | constant ] [ input | output ] + ( "flow" | "stream" )? + ( "discrete" { jjtn000.op = "discrete"; }| "parameter" { jjtn000.op = "parameter"; }| "constant" { jjtn000.op = "constant"; })? + ( "output" { type = InterfaceVariableType.OUTPUT; jjtn000.op = "output"; } + | "input" { type = InterfaceVariableType.INPUT; jjtn000.op = "input"; } + )?/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { + return type; + }/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} +String type_specifier() : {/*@bgen(jjtree) type_specifier */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPE_SPECIFIER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ + String ret = new String(""); +} {/*@bgen(jjtree) type_specifier */ + try { +/*@egen*/ + ret = name()/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { + jjtn000.op = ret; return ret; + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +ArrayList component_list() : {/*@bgen(jjtree) component_list */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ + ArrayList ret = new ArrayList(); + Parameter temp; +} {/*@bgen(jjtree) component_list */ + try { +/*@egen*/ +// component_declaration { "," component_declaration } + temp = component_declaration() { ret.add(temp); } ( "," temp = component_declaration() { ret.add(temp); } )*/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { return ret; + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +Parameter component_declaration() : {/*@bgen(jjtree) component_declaration */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_DECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ + Parameter ret; + String temp = ""; +} {/*@bgen(jjtree) component_declaration */ + try { +/*@egen*/ +// declaration [ conditional_attribute ] comment + ret = declaration() ( conditional_attribute() )? ret.description = comment()/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { + return ret; + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void conditional_attribute() : {/*@bgen(jjtree) conditional_attribute */ + SimpleNode jjtn000 = new SimpleNode(JJTCONDITIONAL_ATTRIBUTE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) conditional_attribute */ + try { +/*@egen*/ + "if" expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +Parameter declaration() : {/*@bgen(jjtree) declaration */ + SimpleNode jjtn000 = new SimpleNode(JJTDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ Token t; + // Parameter here without comment yet. + Parameter ret = new Parameter(); +} {/*@bgen(jjtree) declaration */ + try { +/*@egen*/ +// IDENT [ array_subscripts ] [ modification ] + { ret.name = new String(token.image); jjtn000.op = token.image; } + ( array_subscripts() )? + ( ret.optional = modification() )?/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { return ret; }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +/*** Modification **********************************************/ +boolean modification() : {/*@bgen(jjtree) modification */ + SimpleNode jjtn000 = new SimpleNode(JJTMODIFICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ + boolean optional = false; +} {/*@bgen(jjtree) modification */ + try { +/*@egen*/ +// class_modification [ "=" expression ] +// | "=" expression +// | ":=" expression + ( class_modification() ( "=" expression() )? + | "=" expression() { optional = true; } + | ":=" expression() { optional = true; } )/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { return optional; + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void class_modification() : {/*@bgen(jjtree) class_modification */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASS_MODIFICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) class_modification */ + try { +/*@egen*/ +// "(" [ argument_list ] ")" + "(" ( argument_list() )? ")"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void argument_list() : {/*@bgen(jjtree) argument_list */ + SimpleNode jjtn000 = new SimpleNode(JJTARGUMENT_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) argument_list */ + try { +/*@egen*/ +// argument { "," argument } + argument() ( "," argument() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void argument() : {/*@bgen(jjtree) argument */ + SimpleNode jjtn000 = new SimpleNode(JJTARGUMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) argument */ + try { +/*@egen*/ +// element_modification_or_replaceable +// | element_redeclaration + element_modification_or_replaceable() | + element_redeclaration()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void element_modification_or_replaceable() : {/*@bgen(jjtree) element_modification_or_replaceable */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_MODIFICATION_OR_REPLACEABLE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) element_modification_or_replaceable */ + try { +/*@egen*/ +// [ each ] [ final ] ( element_modification | element_replaceable) + ( "each" )? ( "final" )? ( element_modification() | element_replaceable() )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void element_modification() : {/*@bgen(jjtree) element_modification */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_MODIFICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) element_modification */ + try { +/*@egen*/ +// name [ modification ] string_comment + name() ( modification() )? string_comment()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void element_redeclaration() : {/*@bgen(jjtree) element_redeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_REDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) element_redeclaration */ + try { +/*@egen*/ +// redeclare [ each ] [ final ] +// ( ( class_definition | component_clause1) | element_replaceable ) + "redeclare" ( "each" )? ( "final" )? + ( ( class_definition() | component_clause1() ) | element_replaceable() )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void element_replaceable() : {/*@bgen(jjtree) element_replaceable */ + SimpleNode jjtn000 = new SimpleNode(JJTELEMENT_REPLACEABLE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) element_replaceable */ + try { +/*@egen*/ +// replaceable ( class_definition | component_clause1) +// [constraining_clause] + "replaceable" ( class_definition() | component_clause1() ) ( constraining_clause() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void component_clause1() : {/*@bgen(jjtree) component_clause1 */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_CLAUSE1); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) component_clause1 */ + try { +/*@egen*/ +// type_prefix type_specifier component_declaration1 + type_prefix() type_specifier() component_declaration1()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void component_declaration1() : {/*@bgen(jjtree) component_declaration1 */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_DECLARATION1); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) component_declaration1 */ + try { +/*@egen*/ + declaration() comment()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + + +/*** Equations *************************************************/ +void equation_section() : {/*@bgen(jjtree) equation_section */ + SimpleNode jjtn000 = new SimpleNode(JJTEQUATION_SECTION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) equation_section */ + try { +/*@egen*/ +// [ initial ] equation { equation ";" } + ( "initial" { jjtn000.op = "initial"; } )? "equation" ( LOOKAHEAD(2) equation() ";" )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void algorithm_section() : {/*@bgen(jjtree) algorithm_section */ + SimpleNode jjtn000 = new SimpleNode(JJTALGORITHM_SECTION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) algorithm_section */ + try { +/*@egen*/ +// [ initial ] algorithm { statement ";" } + ( "initial" )? "algorithm" ( statement() ";" )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void assignment() : {/*@bgen(jjtree) assignment */ + SimpleNode jjtn000 = new SimpleNode(JJTASSIGNMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) assignment */ + try { +/*@egen*/ + ( simple_expression() "=" expression() )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +Node equation() : {/*@bgen(jjtree) equation */ + SimpleNode jjtn000 = new SimpleNode(JJTEQUATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) equation */ + try { +/*@egen*/ +// ( simple_expression "=" expression +// | if_equation +// | for_equation +// | connect_clause +// | when_equation +// | IDENT function_call_args ) +// comment + ( LOOKAHEAD(3) assignment() + | if_equation() + | for_equation() + | connect_clause() + | when_equation() + | function_call_args() ) + comment()/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { return jjtn000; }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void statement() : {/*@bgen(jjtree) statement */ + SimpleNode jjtn000 = new SimpleNode(JJTSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) statement */ + try { +/*@egen*/ +// ( component_reference ( ":=" expression | function_call_args ) +// | "(" output_expression_list ")" ":=" component_reference function_call_args +// | break +// | return +// | if_statement +// | for_statement +// | while_statement +// | when_statement ) +// comment + ( component_reference() ( ":=" expression() | function_call_args() ) + | "(" output_expression_list() ")" ":=" component_reference() function_call_args() + | "break" + | "return" + | if_statement() + | for_statement() + | while_statement() + | when_statement() ) + comment()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void if_equation() : {/*@bgen(jjtree) if_equation */ + SimpleNode jjtn000 = new SimpleNode(JJTIF_EQUATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) if_equation */ + try { +/*@egen*/ +// if expression then +// { equation ";" } +// { elseif expression then +// { equation ";" } +// } +// [ else +// { equation ";" } +// ] +// end if + "if" expression() "then" + ( equation() ";" )* + ( "elseif" expression() "then" + ( equation() ";" )* + )* + ( "else" + ( equation() ";" )* + )? + "end" "if"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void then_statement() : {/*@bgen(jjtree) then_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTTHEN_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) then_statement */ + try { +/*@egen*/ + ( statement() )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void elseif_statement() : {/*@bgen(jjtree) elseif_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTELSEIF_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) elseif_statement */ + try { +/*@egen*/ + ( statement() )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void else_statement() : {/*@bgen(jjtree) else_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTELSE_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) else_statement */ + try { +/*@egen*/ + ( statement() )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void if_statement() : {/*@bgen(jjtree) if_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTIF_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) if_statement */ + try { +/*@egen*/ +// if expression then +// { statement ";" } +// { elseif expression then +// { statement ";" } +// } +// [ else +// { statement ";" } +// ] +// end if + "if" expression() "then" + ( then_statement() ";" )* + ( "elseif" expression() "then" + ( elseif_statement() ";" )* + )* + ( "else" + ( else_statement() ";" )* + )? + "end" "if"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void for_equation() : {/*@bgen(jjtree) for_equation */ + SimpleNode jjtn000 = new SimpleNode(JJTFOR_EQUATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) for_equation */ + try { +/*@egen*/ +// for for_indices loop +// { equation ";" } +// end for + "for" for_indices() "loop" + ( equation() ";" )* + "end" "for"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void for_statement() : {/*@bgen(jjtree) for_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTFOR_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) for_statement */ + try { +/*@egen*/ +// for for_indices loop +// { equation ";" } +// end for + "for" for_indices() "loop" + ( statement() ";" )* + "end" "for"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void for_indices() : {/*@bgen(jjtree) for_indices */ + SimpleNode jjtn000 = new SimpleNode(JJTFOR_INDICES); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) for_indices */ + try { +/*@egen*/ + //for_index {"," for_index} + for_index() ("," for_index())*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void for_index() : {/*@bgen(jjtree) for_index */ + SimpleNode jjtn000 = new SimpleNode(JJTFOR_INDEX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ Token t; +} {/*@bgen(jjtree) for_index */ + try { +/*@egen*/ + //IDENT [ in expression ] + t= { jjtn000.op = t.image; } ( "in" expression() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void while_statement() : {/*@bgen(jjtree) while_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTWHILE_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) while_statement */ + try { +/*@egen*/ +// while expression loop +// { statement ";" } +// end while + "while" expression() "loop" + ( statement() ";" )* + "end" "while"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void when_equation() : {/*@bgen(jjtree) when_equation */ + SimpleNode jjtn000 = new SimpleNode(JJTWHEN_EQUATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) when_equation */ + try { +/*@egen*/ +// when expression then +// { equation ";" } +// { elsewhen expression then +// { equation ";" } } +// end when + "when" expression() "then" + ( equation() ";" )* + ( "elsewhen" expression() "then" + ( equation() ";" )* + )* + "end" "when"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void when_statement() : {/*@bgen(jjtree) when_statement */ + SimpleNode jjtn000 = new SimpleNode(JJTWHEN_STATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) when_statement */ + try { +/*@egen*/ +// when expression then +// { statement ";" } +// { elsewhen expression then +// { statement ";" } } +// end when + "when" expression() "then" + ( statement() ";" )* + ( "elsewhen" expression() "then" + ( statement() ";" )* + )* + "end" "when"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void connect_clause() : {/*@bgen(jjtree) connect_clause */ + SimpleNode jjtn000 = new SimpleNode(JJTCONNECT_CLAUSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) connect_clause */ + try { +/*@egen*/ +// connect "(" component_reference "," component_reference ")" + "connect" "(" component_reference() "," component_reference() ")"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +/*** Expressions ***************************************************/ +void expr() : {/*@bgen(jjtree) expr */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) expr */ + try { +/*@egen*/ + simple_expression() + | + "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* + "else" expression() /*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void if_expression() : {/*@bgen(jjtree) if_expression */ + SimpleNode jjtn000 = new SimpleNode(JJTIF_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) if_expression */ + try { +/*@egen*/ + "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* + "else" expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + + +void expression() : {/*@bgen(jjtree) expression */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) expression */ + try { +/*@egen*/ + simple_expression() | if_expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void simple_expression() : {/*@bgen(jjtree) simple_expression */ + SimpleNode jjtn000 = new SimpleNode(JJTSIMPLE_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) simple_expression */ + try { +/*@egen*/ + logical_expression() ( ":" logical_expression() ( ":" logical_expression() )? )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void logical_expression() : {/*@bgen(jjtree) logical_expression */ + SimpleNode jjtn000 = new SimpleNode(JJTLOGICAL_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) logical_expression */ + try { +/*@egen*/ + logical_term() ( "or" logical_term() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void logical_term() : {/*@bgen(jjtree) logical_term */ + SimpleNode jjtn000 = new SimpleNode(JJTLOGICAL_TERM); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) logical_term */ + try { +/*@egen*/ + logical_factor() ( "and" logical_factor() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void logical_factor() : {/*@bgen(jjtree) logical_factor */ + SimpleNode jjtn000 = new SimpleNode(JJTLOGICAL_FACTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) logical_factor */ + try { +/*@egen*/ + ( "not" )? relation()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void relation() : {/*@bgen(jjtree) relation */ + SimpleNode jjtn000 = new SimpleNode(JJTRELATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) relation */ + try { +/*@egen*/ + arithmetic_expression() ( rel_op() arithmetic_expression() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void rel_op() : {/*@bgen(jjtree) rel_op */ + SimpleNode jjtn000 = new SimpleNode(JJTREL_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) rel_op */ + try { +/*@egen*/ + "<"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = "< ";} | "<="/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = "<=";} | ">"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = " >";} | ">="/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = " >=";} | "=="/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = "==";} | "<>"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = "<>";}/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void arithmetic_expression() : {/*@bgen(jjtree) arithmetic_expression */ + SimpleNode jjtn000 = new SimpleNode(JJTARITHMETIC_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) arithmetic_expression */ + try { +/*@egen*/ + (add_op())? term() (add_op() term())*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void add_op() : {/*@bgen(jjtree) add_op */ + SimpleNode jjtn000 = new SimpleNode(JJTADD_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) add_op */ + try { +/*@egen*/ + "+"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = "+";} | "-"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = "-";} | ".+" | ".-"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + + +void term() : {/*@bgen(jjtree) term */ + SimpleNode jjtn000 = new SimpleNode(JJTTERM); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) term */ + try { +/*@egen*/ + factor() ( mul_op() factor() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void mul_op() : {/*@bgen(jjtree) mul_op */ + SimpleNode jjtn000 = new SimpleNode(JJTMUL_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) mul_op */ + try { +/*@egen*/ + "*"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = "*";} | "/"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = "/";} | ".*" | "./"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void factor() : {/*@bgen(jjtree) factor */ + SimpleNode jjtn000 = new SimpleNode(JJTFACTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) factor */ + try { +/*@egen*/ + primary() ( "^" | ".^" primary() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void der_initial() : {/*@bgen(jjtree) der_initial */ + SimpleNode jjtn000 = new SimpleNode(JJTDER_INITIAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) der_initial */ + try { +/*@egen*/ + ( (name() { jjtn000.op = "application"; } |"der" { jjtn000.op = "der";} |"initial" { jjtn000.op = "initial";} ) function_call_args() )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void subscript_2() : {/*@bgen(jjtree) subscript_2 */ + SimpleNode jjtn000 = new SimpleNode(JJTSUBSCRIPT_2); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) subscript_2 */ + try { +/*@egen*/ + ( expression_list() ( ";" expression_list() )* )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void array() : {/*@bgen(jjtree) array */ + SimpleNode jjtn000 = new SimpleNode(JJTARRAY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ } {/*@bgen(jjtree) array */ + try { +/*@egen*/ + ( "{" function_arguments() "}" )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ } + +void primary() : {/*@bgen(jjtree) primary */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMARY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ Token t; +} {/*@bgen(jjtree) primary */ + try { +/*@egen*/ + t=/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = token.image; } + | t=/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = token.image; } + | t=/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = token.image; } + | t="false"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = token.image; } + | t="true"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = token.image; } + | LOOKAHEAD( (name()|"der"|"initial") "(" ) der_initial() | component_reference() + /* | "(" output_expression_list() ")" */ // Not needed, replaced with following: + | "(" expression() ")" + | "[" subscript_2() "]" + | array() + | "end"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +String name() : {/*@bgen(jjtree) name */ + SimpleNode jjtn000 = new SimpleNode(JJTNAME); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ + String ret = new String(""); +} {/*@bgen(jjtree) name */ + try { +/*@egen*/ +// [ "." ] IDENT { "." IDENT } + ( "." { ret += "."; } )? + { ret += token.image; jjtn000.op = token.image;} + ( "." { ret += "."; } + { ret += token.image; jjtn000.op = token.image;} + )*/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ + { return ret; + }/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void component_reference() : {/*@bgen(jjtree) component_reference */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPONENT_REFERENCE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ + Token t; +} {/*@bgen(jjtree) component_reference */ + try { +/*@egen*/ +// [ "." ] IDENT [ array_subscripts ] { "." IDENT [ array_subscripts ] } + ( "." )? t= { jjtn000.op = t.image; } ( array_subscripts() )? ( "." ( array_subscripts() )? )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void function_call_args() : {/*@bgen(jjtree) function_call_args */ + SimpleNode jjtn000 = new SimpleNode(JJTFUNCTION_CALL_ARGS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) function_call_args */ + try { +/*@egen*/ +// "(" [ function_arguments ] ")" + "(" ( function_arguments() )? ")"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void function_arguments() : {/*@bgen(jjtree) function_arguments */ + SimpleNode jjtn000 = new SimpleNode(JJTFUNCTION_ARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) function_arguments */ + try { +/*@egen*/ + //expression [ "," function_arguments | for for_indices ] + //| named_arguments + LOOKAHEAD(2) expression() ( "," function_arguments() | "for" for_indices() )? + | named_arguments()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void named_arguments() : {/*@bgen(jjtree) named_arguments */ + SimpleNode jjtn000 = new SimpleNode(JJTNAMED_ARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) named_arguments */ + try { +/*@egen*/ +// named_argument [ "," named_arguments ] + named_argument() ( "," named_arguments() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void named_argument() : {/*@bgen(jjtree) named_argument */ + SimpleNode jjtn000 = new SimpleNode(JJTNAMED_ARGUMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) named_argument */ + try { +/*@egen*/ + "=" expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void output_expression_list() : {/*@bgen(jjtree) output_expression_list */ + SimpleNode jjtn000 = new SimpleNode(JJTOUTPUT_EXPRESSION_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) output_expression_list */ + try { +/*@egen*/ +// [ expression ] { "," [ expression ] } + ( expression() )? ( "," ( expression() )? )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void expression_list() : {/*@bgen(jjtree) expression_list */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPRESSION_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) expression_list */ + try { +/*@egen*/ +// expression { "," expression } + expression() ( "," expression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void array_subscripts() : {/*@bgen(jjtree) array_subscripts */ + SimpleNode jjtn000 = new SimpleNode(JJTARRAY_SUBSCRIPTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) array_subscripts */ + try { +/*@egen*/ +// "[" subscript { "," subscript } "]" + "[" subscript() ( "," subscript() )* "]"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +void subscript() : {/*@bgen(jjtree) subscript */ + SimpleNode jjtn000 = new SimpleNode(JJTSUBSCRIPT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) subscript */ + try { +/*@egen*/ +// ":" | expression ":"/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + } +/*@egen*/ { jjtn000.op = "all"; } | expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + +String comment() : { + String ret; } { // string_comment [ annotation ] + ret = string_comment() ( annotation() )? + { return ret; + } +} + +String string_comment() : { + String ret = null; +} { +// [ STRING { "+" STRING } ] + ( { ret = new String(token.image); } + ( "+" { ret += "+"; } + { ret += token.image; } + )* + )? + { return ret; + } } + +void annotation() : {/*@bgen(jjtree) annotation */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); +/*@egen*/ +} {/*@bgen(jjtree) annotation */ + try { +/*@egen*/ +// annotation class_modification + "annotation" class_modification()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + } + } +/*@egen*/ +} + diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jjt b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jjt new file mode 100644 index 00000000..793e0cfd --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jjt @@ -0,0 +1,782 @@ +options { + JDK_VERSION = "1.6"; + STATIC = false; +} + +PARSER_BEGIN(ModelParser) +package fi.semantum.sysdyn.solver.parser; + +import java.util.ArrayList; + +public class ModelParser { + + private ArrayList inputs = new ArrayList(); + private ArrayList outputs = new ArrayList(); + + private enum InterfaceVariableType { INPUT, OUTPUT, OTHER + } + + public class Parameter { + public String name; + public boolean optional; + public String description; + public String type; + + public Parameter() { + name = new String(""); + optional = false; + description = null; + type = null; + } } + + public ArrayList getInputs() + { + return inputs; + } + + public ArrayList getOutputs() + { + return outputs; + } + +} + +PARSER_END(ModelParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ +"algorithm" | "discrete" | "false" | "model" | "redeclare" +| "and" | "each" | "final" | "not" | "replaceable" +| "annotation" | "else" | "flow" | "operator" | "return" +|"assert" | "elseif" | "for" | "or" | "stream" +| "block" | "elsewhen" | "function" | "outer" | "then" +| "break" | "encapsulated" | "if" | "output" | "true" +| "class" | "end" | "import" | "package" | "type" +| "connect" | "enumeration" | "in" | "parameter" | "when" +| "connector" | "equation" | "initial" | "partial" | "while" +| "constant" | "expandable" | "inner" | "protected" | "within" +| "constrainedby" | "extends" | "input" | "public" +| "der" | "external" | "loop" | "record" +| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | "," +| "<" | "<=" | ">" | ">=" | "==" | "<>" +| "+" | "-" | ".+" | ".-" +| "*" | "/" | ".*" | "./" +| "^" | ".^" +| "=" | ":=" +| +| + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +| +| "." ()? (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +} + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + +Node parse() : { +} { + stored_definition() + { return jjtThis; } +} + +/*** Stored Definition - Within ************************************/ + +Node stored_definition() #STORED : { +} { +// stored_definition: +// [ within [ name ] ";" ] +// { [ final ] class_definition ";" } + ( "within" ( name() )? ";" )? + ( ( "final" )? class_definition() ";" )* + { return jjtThis; } +} + +/*** Class Definition **********************************************/ + +void class_definition() : { +} { +// class_definition : +// [ encapsulated ] +// [ partial +// ] ( class modelrecordblock expandableconnectortype +// | | | | [ ] | | package | function | operator | operator function | operator record ) +// class_specifier + ( "encapsulated" )? + ( "partial" )? + ( "class" | "model" | "record" | "block" | ( "expandable" )? "connector" | "type" | + "package" | "function" { jjtThis.op = "function"; } | "operator" | "operator function" | "operator record" ) + class_specifier() +} + + +void class_specifier() : { Token t; +} { +// class_specifier : +// IDENT string_comment composition end IDENT +// | IDENT "=" base_prefix name [ array_subscripts ] +// [ class_modification ] comment +// | IDENT "=" enumeration "(" ( [enum_list] | ":" ) ")" comment +// | IDENT "=" der "(" name "," IDENT { "," IDENT } ")" comment +// | extends IDENT [ class_modification ] string_comment composition +// end IDENT + LOOKAHEAD(2) t= { jjtThis.op = t.image; } string_comment() composition() "end" + | LOOKAHEAD(2) "=" base_prefix() name() ( array_subscripts() )? ( class_modification() )? comment() + | LOOKAHEAD(3) "=" "enumeration" "(" ( ( enum_list() )? | ":" ) ")" comment() + |LOOKAHEAD(3) "=" "der" "(" name() "," ( "," )* ")" comment() + | "extends" ( class_modification() )? string_comment() composition() "end" +} + +void base_prefix() : { +} { + type_prefix() +} + +void enum_list() : { +} { +// enumeration_literal { "," enumeration_literal} + enumeration_literal() ( "," enumeration_literal() )* +} + +void enumeration_literal() : { +} { + comment() +} + +void parse_composition() : { +} { + composition() +} + +void composition() : { +} { +// element_list +// { public element_list | +// protected element_list | +// equation_section | +// algorithm_section +// } +// [ external [ language_specification ] +// [ external_function_call ] [ annotation ] ";" ] +// [ annotation ";" ] + element_list() + ( LOOKAHEAD(2) "public" element_list() | "protected" element_list() | equation_section() | algorithm_section() )* + ( "external" ( language_specification() )? ( external_function_call() )? ( annotation() )? ";" )? + ( annotation() ";" )? +} + +void language_specification() : { +} { + +} + +void external_function_call() : { +} { +// [ component_reference "=" ] +// IDENT "(" [ expression_list ] ")" + ( component_reference() "=" )? + "(" ( expression_list() )? ")" +} + +void element_list() : { +} { + ( element() ";" )* +} + +Node element() : { +} { +// import_clause | +// extends_clause | +// [ redeclare ] +// [ final ] +// [ inner ] [ outer ] +// ( ( class_definition | component_clause) | +// replaceable ( class_definition | component_clause) +// [constraining_clause comment]) + import_clause() | + extends_clause() | + ( "redeclare" )? + ( "final" )? + ( "inner" )? ( "outer" )? + ( (class_definition() | component_clause()) | + "replaceable" (class_definition() | component_clause()) + (constraining_clause() comment())?) + { return jjtThis; } +} + +void import_clause() : { +} { +// import ( IDENT "=" name | name ["." "*"] ) comment + "import" (LOOKAHEAD(2) "=" name() | name() ("." "*")? ) comment() +} + +/*** Extends *******************************************************/ +void extends_clause() : { +} { +// extends name [ class_modification ] [annotation] + "extends" name() ( class_modification() )? ( annotation() )? +} + +void constraining_clause() : { +} { +// constrainedby name [ class_modification ] + "constrainedby" name() ( class_modification() )? +} + +/*** Component Clause **********************************************/ +void component_clause() : { + InterfaceVariableType ioType = InterfaceVariableType.OTHER; + String typeSpecifier = ""; + //String arraySubscripts = null; + ArrayList componentList = new ArrayList(); +} { + +// type_prefix type_specifier [ array_subscripts ] component_list + ( ioType = type_prefix() ) + ( typeSpecifier = type_specifier() ) + ( /*arraySubscripts =*/ array_subscripts() )? + ( componentList = component_list() ) + { + if (ioType == InterfaceVariableType.INPUT) { + for (Parameter input : componentList) { + input.type = typeSpecifier; + inputs.add(input); } + } else if (ioType == InterfaceVariableType.OUTPUT) { + for (Parameter output : componentList) { + output.type = typeSpecifier; + outputs.add(output); + } + } + } +} + +InterfaceVariableType type_prefix() : { + InterfaceVariableType type = InterfaceVariableType.OTHER; +} { +// [ flow | stream ] +// [ discrete | parameter | constant ] [ input | output ] + ( "flow" | "stream" )? + ( "discrete" { jjtThis.op = "discrete"; }| "parameter" { jjtThis.op = "parameter"; }| "constant" { jjtThis.op = "constant"; })? + ( "output" { type = InterfaceVariableType.OUTPUT; jjtThis.op = "output"; } + | "input" { type = InterfaceVariableType.INPUT; jjtThis.op = "input"; } + )? + { + return type; + } +} +String type_specifier() : { + String ret = new String(""); +} { + ret = name() + { + jjtThis.op = ret; return ret; + } +} + +ArrayList component_list() : { + ArrayList ret = new ArrayList(); + Parameter temp; +} { +// component_declaration { "," component_declaration } + temp = component_declaration() { ret.add(temp); } ( "," temp = component_declaration() { ret.add(temp); } )* + { return ret; + } +} + +Parameter component_declaration() : { + Parameter ret; + String temp = ""; +} { +// declaration [ conditional_attribute ] comment + ret = declaration() ( conditional_attribute() )? ret.description = comment() + { + return ret; + } +} + +void conditional_attribute() : { +} { + "if" expression() +} + +Parameter declaration() : { Token t; + // Parameter here without comment yet. + Parameter ret = new Parameter(); +} { +// IDENT [ array_subscripts ] [ modification ] + { ret.name = new String(token.image); jjtThis.op = token.image; } + ( array_subscripts() )? + ( ret.optional = modification() )? + { return ret; } +} + +/*** Modification **********************************************/ +boolean modification() : { + boolean optional = false; +} { +// class_modification [ "=" expression ] +// | "=" expression +// | ":=" expression + ( class_modification() ( "=" expression() )? + | "=" expression() { optional = true; } + | ":=" expression() { optional = true; } ) + { return optional; + } +} + +void class_modification() : { +} { +// "(" [ argument_list ] ")" + "(" ( argument_list() )? ")" +} + +void argument_list() : { +} { +// argument { "," argument } + argument() ( "," argument() )* +} + +void argument() : { +} { +// element_modification_or_replaceable +// | element_redeclaration + element_modification_or_replaceable() | + element_redeclaration() +} + +void element_modification_or_replaceable() : { +} { +// [ each ] [ final ] ( element_modification | element_replaceable) + ( "each" )? ( "final" )? ( element_modification() | element_replaceable() ) } + +void element_modification() : { +} { +// name [ modification ] string_comment + name() ( modification() )? string_comment() +} + +void element_redeclaration() : { +} { +// redeclare [ each ] [ final ] +// ( ( class_definition | component_clause1) | element_replaceable ) + "redeclare" ( "each" )? ( "final" )? + ( ( class_definition() | component_clause1() ) | element_replaceable() ) } + +void element_replaceable() : { +} { +// replaceable ( class_definition | component_clause1) +// [constraining_clause] + "replaceable" ( class_definition() | component_clause1() ) ( constraining_clause() )? +} + +void component_clause1() : { +} { +// type_prefix type_specifier component_declaration1 + type_prefix() type_specifier() component_declaration1() +} + +void component_declaration1() : { +} { + declaration() comment() +} + + +/*** Equations *************************************************/ +void equation_section() : { +} { +// [ initial ] equation { equation ";" } + ( "initial" { jjtThis.op = "initial"; } )? "equation" ( LOOKAHEAD(2) equation() ";" )* +} + +void algorithm_section() : { +} { +// [ initial ] algorithm { statement ";" } + ( "initial" )? "algorithm" ( statement() ";" )* } + +void assignment() : { +} { + ( simple_expression() "=" expression() ) +} + +Node equation() : { +} { +// ( simple_expression "=" expression +// | if_equation +// | for_equation +// | connect_clause +// | when_equation +// | IDENT function_call_args ) +// comment + ( LOOKAHEAD(3) assignment() + | if_equation() + | for_equation() + | connect_clause() + | when_equation() + | function_call_args() ) + comment() { return jjtThis; } +} + +void statement() : { +} { +// ( component_reference ( ":=" expression | function_call_args ) +// | "(" output_expression_list ")" ":=" component_reference function_call_args +// | break +// | return +// | if_statement +// | for_statement +// | while_statement +// | when_statement ) +// comment + ( component_reference() ( ":=" expression() | function_call_args() ) + | "(" output_expression_list() ")" ":=" component_reference() function_call_args() + | "break" + | "return" + | if_statement() + | for_statement() + | while_statement() + | when_statement() ) + comment() +} + +void if_equation() : { +} { +// if expression then +// { equation ";" } +// { elseif expression then +// { equation ";" } +// } +// [ else +// { equation ";" } +// ] +// end if + "if" expression() "then" + ( equation() ";" )* + ( "elseif" expression() "then" + ( equation() ";" )* + )* + ( "else" + ( equation() ";" )* + )? + "end" "if" } + +void then_statement() : { +} { + ( statement() ) } + +void elseif_statement() : { +} { + ( statement() ) +} + +void else_statement() : { +} { + ( statement() ) +} + +void if_statement() : { +} { +// if expression then +// { statement ";" } +// { elseif expression then +// { statement ";" } +// } +// [ else +// { statement ";" } +// ] +// end if + "if" expression() "then" + ( then_statement() ";" )* + ( "elseif" expression() "then" + ( elseif_statement() ";" )* + )* + ( "else" + ( else_statement() ";" )* + )? + "end" "if" } + +void for_equation() : { +} { +// for for_indices loop +// { equation ";" } +// end for + "for" for_indices() "loop" + ( equation() ";" )* + "end" "for" } + +void for_statement() : { +} { +// for for_indices loop +// { equation ";" } +// end for + "for" for_indices() "loop" + ( statement() ";" )* + "end" "for" } + +void for_indices() : { +} { + //for_index {"," for_index} + for_index() ("," for_index())* +} + +void for_index() : { Token t; +} { + //IDENT [ in expression ] + t= { jjtThis.op = t.image; } ( "in" expression() )? +} + +void while_statement() : { +} { +// while expression loop +// { statement ";" } +// end while + "while" expression() "loop" + ( statement() ";" )* + "end" "while" } + +void when_equation() : { +} { +// when expression then +// { equation ";" } +// { elsewhen expression then +// { equation ";" } } +// end when + "when" expression() "then" + ( equation() ";" )* + ( "elsewhen" expression() "then" + ( equation() ";" )* + )* + "end" "when" } + +void when_statement() : { +} { +// when expression then +// { statement ";" } +// { elsewhen expression then +// { statement ";" } } +// end when + "when" expression() "then" + ( statement() ";" )* + ( "elsewhen" expression() "then" + ( statement() ";" )* + )* + "end" "when" } + +void connect_clause() : { +} { +// connect "(" component_reference "," component_reference ")" + "connect" "(" component_reference() "," component_reference() ")" +} + +/*** Expressions ***************************************************/ +void expr() : { +} { + simple_expression() + | + "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* + "else" expression() +} + +void if_expression() : { +} { + "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* + "else" expression() +} + + +void expression() : { +} { + simple_expression() | if_expression() +} + +void simple_expression() : { +} { + logical_expression() ( ":" logical_expression() ( ":" logical_expression() )? )? +} + +void logical_expression() : { +} { + logical_term() ( "or" logical_term() )* +} + +void logical_term() : { +} { + logical_factor() ( "and" logical_factor() )* +} + +void logical_factor() : { +} { + ( "not" )? relation() +} + +void relation() : { +} { + arithmetic_expression() ( rel_op() arithmetic_expression() )? +} + +void rel_op() : { +} { + "<" { jjtThis.op = "< ";} | "<=" { jjtThis.op = "<=";} | ">" { jjtThis.op = " >";} | ">=" { jjtThis.op = " >=";} | "==" { jjtThis.op = "==";} | "<>" { jjtThis.op = "<>";} +} + +void arithmetic_expression() : { +} { + (add_op())? term() (add_op() term())* +} + +void add_op() : { +} { + "+" { jjtThis.op = "+";} | "-" { jjtThis.op = "-";} | ".+" | ".-" +} + + +void term() : { +} { + factor() ( mul_op() factor() )* +} + +void mul_op() : { +} { + "*" { jjtThis.op = "*";} | "/" { jjtThis.op = "/";} | ".*" | "./" +} + +void factor() : { +} { + primary() ( "^" | ".^" primary() )? +} + +void der_initial() : { +} { + ( (name() { jjtThis.op = "application"; } |"der" { jjtThis.op = "der";} |"initial" { jjtThis.op = "initial";} ) function_call_args() ) +} + +void subscript_2() : { +} { + ( expression_list() ( ";" expression_list() )* ) +} + +void array() : { } { + ( "{" function_arguments() "}" ) } + +void primary() : { Token t; +} { + t= { jjtThis.op = token.image; } + | t= { jjtThis.op = token.image; } + | t= { jjtThis.op = token.image; } + | t="false" { jjtThis.op = token.image; } + | t="true" { jjtThis.op = token.image; } + | LOOKAHEAD( (name()|"der"|"initial") "(" ) der_initial() | component_reference() + /* | "(" output_expression_list() ")" */ // Not needed, replaced with following: + | "(" expression() ")" + | "[" subscript_2() "]" + | array() + | "end" +} + +String name() : { + String ret = new String(""); +} { +// [ "." ] IDENT { "." IDENT } + ( "." { ret += "."; } )? + { ret += token.image; jjtThis.op = token.image;} + ( "." { ret += "."; } + { ret += token.image; jjtThis.op = token.image;} + )* + { return ret; + } +} + +void component_reference() : { + Token t; +} { +// [ "." ] IDENT [ array_subscripts ] { "." IDENT [ array_subscripts ] } + ( "." )? t= { jjtThis.op = t.image; } ( array_subscripts() )? ( "." ( array_subscripts() )? )* +} + +void function_call_args() : { +} { +// "(" [ function_arguments ] ")" + "(" ( function_arguments() )? ")" +} + +void function_arguments() : { +} { + //expression [ "," function_arguments | for for_indices ] + //| named_arguments + LOOKAHEAD(2) expression() ( "," function_arguments() | "for" for_indices() )? + | named_arguments() +} + +void named_arguments() : { +} { +// named_argument [ "," named_arguments ] + named_argument() ( "," named_arguments() )? +} + +void named_argument() : { +} { + "=" expression() +} + +void output_expression_list() : { +} { +// [ expression ] { "," [ expression ] } + ( expression() )? ( "," ( expression() )? )* +} + +void expression_list() : { +} { +// expression { "," expression } + expression() ( "," expression() )* +} + +void array_subscripts() : { +} { +// "[" subscript { "," subscript } "]" + "[" subscript() ( "," subscript() )* "]" +} + +void subscript() : { +} { +// ":" | expression ":" { jjtThis.op = "all"; } | expression() +} + +String comment() #void : { + String ret; } { // string_comment [ annotation ] + ret = string_comment() ( annotation() )? + { return ret; + } +} + +String string_comment() #void : { + String ret = null; +} { +// [ STRING { "+" STRING } ] + ( { ret = new String(token.image); } + ( "+" { ret += "+"; } + { ret += token.image; } + )* + )? + { return ret; + } } + +void annotation() : { +} { +// annotation class_modification + "annotation" class_modification() +} + diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/Node.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/Node.java new file mode 100644 index 00000000..862f65fb --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/Node.java @@ -0,0 +1,36 @@ +/* Generated By:JJTree: Do not edit this line. Node.java Version 4.3 */ +/* JavaCCOptions:MULTI=false,NODE_USES_PARSER=false,VISITOR=false,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package fi.semantum.sysdyn.solver.parser; + +/* All AST nodes must implement this interface. It provides basic + machinery for constructing the parent and child relationships + between nodes. */ + +public +interface Node { + + /** This method is called after the node has been made the current + node. It indicates that child nodes can now be added to it. */ + public void jjtOpen(); + + /** This method is called after all the child nodes have been + added. */ + public void jjtClose(); + + /** This pair of methods are used to inform the node of its + parent. */ + public void jjtSetParent(Node n); + public Node jjtGetParent(); + + /** This method tells the node to add its argument to the node's + list of children. */ + public void jjtAddChild(Node n, int i); + + /** This method returns a child node. The children are numbered + from zero, left to right. */ + public Node jjtGetChild(int i); + + /** Return the number of children the node has. */ + public int jjtGetNumChildren(); +} +/* JavaCC - OriginalChecksum=3ac4c20d0d1bb5d97b8317a16454eef1 (do not edit this line) */ diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ParseException.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ParseException.java new file mode 100644 index 00000000..de4ad462 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ParseException.java @@ -0,0 +1,187 @@ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */ +/* JavaCCOptions:KEEP_LINE_COL=null */ +package fi.semantum.sysdyn.solver.parser; + +/** + * This exception is thrown when parse errors are encountered. + * You can explicitly create objects of this exception type by + * calling the method generateParseException in the generated + * parser. + * + * You can modify this class to customize your error reporting + * mechanisms so long as you retain the public fields. + */ +public class ParseException extends Exception { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * This constructor is used by the method "generateParseException" + * in the generated parser. Calling this constructor generates + * a new object of this type with the fields "currentToken", + * "expectedTokenSequences", and "tokenImage" set. + */ + public ParseException(Token currentTokenVal, + int[][] expectedTokenSequencesVal, + String[] tokenImageVal + ) + { + super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal)); + currentToken = currentTokenVal; + expectedTokenSequences = expectedTokenSequencesVal; + tokenImage = tokenImageVal; + } + + /** + * The following constructors are for use by you for whatever + * purpose you can think of. Constructing the exception in this + * manner makes the exception behave in the normal way - i.e., as + * documented in the class "Throwable". The fields "errorToken", + * "expectedTokenSequences", and "tokenImage" do not contain + * relevant information. The JavaCC generated code does not use + * these constructors. + */ + + public ParseException() { + super(); + } + + /** Constructor with message. */ + public ParseException(String message) { + super(message); + } + + + /** + * This is the last token that has been consumed successfully. If + * this object has been created due to a parse error, the token + * followng this token will (therefore) be the first error token. + */ + public Token currentToken; + + /** + * Each entry in this array is an array of integers. Each array + * of integers represents a sequence of tokens (by their ordinal + * values) that is expected at this point of the parse. + */ + public int[][] expectedTokenSequences; + + /** + * This is a reference to the "tokenImage" array of the generated + * parser within which the parse error occurred. This array is + * defined in the generated ...Constants interface. + */ + public String[] tokenImage; + + /** + * It uses "currentToken" and "expectedTokenSequences" to generate a parse + * error message and returns it. If this object has been created + * due to a parse error, and you do not catch it (it gets thrown + * from the parser) the correct error message + * gets displayed. + */ + private static String initialise(Token currentToken, + int[][] expectedTokenSequences, + String[] tokenImage) { + String eol = System.getProperty("line.separator", "\n"); + StringBuffer expected = new StringBuffer(); + int maxSize = 0; + for (int i = 0; i < expectedTokenSequences.length; i++) { + if (maxSize < expectedTokenSequences[i].length) { + maxSize = expectedTokenSequences[i].length; + } + for (int j = 0; j < expectedTokenSequences[i].length; j++) { + expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); + } + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + expected.append("..."); + } + expected.append(eol).append(" "); + } + String retval = "Encountered \""; + Token tok = currentToken.next; + for (int i = 0; i < maxSize; i++) { + if (i != 0) retval += " "; + if (tok.kind == 0) { + retval += tokenImage[0]; + break; + } + retval += " " + tokenImage[tok.kind]; + retval += " \""; + retval += add_escapes(tok.image); + retval += " \""; + tok = tok.next; + } + retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; + retval += "." + eol; + if (expectedTokenSequences.length == 1) { + retval += "Was expecting:" + eol + " "; + } else { + retval += "Was expecting one of:" + eol + " "; + } + retval += expected.toString(); + return retval; + } + + /** + * The end of line string for this machine. + */ + protected String eol = System.getProperty("line.separator", "\n"); + + /** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal. + */ + static String add_escapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + +} +/* JavaCC - OriginalChecksum=b5f58e7b423243b1bf84726ed111c7e8 (do not edit this line) */ diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/SimpleCharStream.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/SimpleCharStream.java new file mode 100644 index 00000000..14ba6213 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/SimpleCharStream.java @@ -0,0 +1,471 @@ +/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */ +/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package fi.semantum.sysdyn.solver.parser; + +/** + * An implementation of interface CharStream, where the stream is assumed to + * contain only ASCII characters (without unicode processing). + */ + +public class SimpleCharStream +{ +/** Whether parser is static. */ + public static final boolean staticFlag = false; + int bufsize; + int available; + int tokenBegin; +/** Position in buffer. */ + public int bufpos = -1; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int inBuf = 0; + protected int tabSize = 8; + + protected void setTabSize(int i) { tabSize = i; } + protected int getTabSize(int i) { return tabSize; } + + + protected void ExpandBuff(boolean wrapAround) + { + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try + { + if (wrapAround) + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos += (bufsize - tokenBegin)); + } + else + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos -= tokenBegin); + } + } + catch (Throwable t) + { + throw new Error(t.getMessage()); + } + + + bufsize += 2048; + available = bufsize; + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException + { + if (maxNextCharInd == available) + { + if (available == bufsize) + { + if (tokenBegin > 2048) + { + bufpos = maxNextCharInd = 0; + available = tokenBegin; + } + else if (tokenBegin < 0) + bufpos = maxNextCharInd = 0; + else + ExpandBuff(false); + } + else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + int i; + try { + if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1) + { + inputStream.close(); + throw new java.io.IOException(); + } + else + maxNextCharInd += i; + return; + } + catch(java.io.IOException e) { + --bufpos; + backup(0); + if (tokenBegin == -1) + tokenBegin = bufpos; + throw e; + } + } + +/** Start. */ + public char BeginToken() throws java.io.IOException + { + tokenBegin = -1; + char c = readChar(); + tokenBegin = bufpos; + + return c; + } + + protected void UpdateLineColumn(char c) + { + column++; + + if (prevCharIsLF) + { + prevCharIsLF = false; + line += (column = 1); + } + else if (prevCharIsCR) + { + prevCharIsCR = false; + if (c == '\n') + { + prevCharIsLF = true; + } + else + line += (column = 1); + } + + switch (c) + { + case '\r' : + prevCharIsCR = true; + break; + case '\n' : + prevCharIsLF = true; + break; + case '\t' : + column--; + column += (tabSize - (column % tabSize)); + break; + default : + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + +/** Read a character. */ + public char readChar() throws java.io.IOException + { + if (inBuf > 0) + { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + if (++bufpos >= maxNextCharInd) + FillBuff(); + + char c = buffer[bufpos]; + + UpdateLineColumn(c); + return c; + } + + @Deprecated + /** + * @deprecated + * @see #getEndColumn + */ + + public int getColumn() { + return bufcolumn[bufpos]; + } + + @Deprecated + /** + * @deprecated + * @see #getEndLine + */ + + public int getLine() { + return bufline[bufpos]; + } + + /** Get token end column number. */ + public int getEndColumn() { + return bufcolumn[bufpos]; + } + + /** Get token end line number. */ + public int getEndLine() { + return bufline[bufpos]; + } + + /** Get token beginning column number. */ + public int getBeginColumn() { + return bufcolumn[tokenBegin]; + } + + /** Get token beginning line number. */ + public int getBeginLine() { + return bufline[tokenBegin]; + } + +/** Backup a number of characters. */ + public void backup(int amount) { + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length) + { + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + bufpos = -1; + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, 1, 1, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, startline, startcolumn, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + /** Get token literal value. */ + public String GetImage() + { + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + else + return new String(buffer, tokenBegin, bufsize - tokenBegin) + + new String(buffer, 0, bufpos + 1); + } + + /** Get the suffix. */ + public char[] GetSuffix(int len) + { + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else + { + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, + len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + /** Reset buffer when finished. */ + public void Done() + { + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + */ + public void adjustBeginLineColumn(int newLine, int newCol) + { + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin) + { + len = bufpos - tokenBegin + inBuf + 1; + } + else + { + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k = 0; + int nextColDiff = 0, columnDiff = 0; + + while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) + { + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len) + { + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while (i++ < len) + { + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + +} +/* JavaCC - OriginalChecksum=ca8536fa0e367b808d68ae76a4e5e3a7 (do not edit this line) */ diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/SimpleNode.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/SimpleNode.java new file mode 100644 index 00000000..b399a88f --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/SimpleNode.java @@ -0,0 +1,81 @@ +/* Generated By:JJTree: Do not edit this line. SimpleNode.java Version 4.3 */ +/* JavaCCOptions:MULTI=false,NODE_USES_PARSER=false,VISITOR=false,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package fi.semantum.sysdyn.solver.parser; + +public +class SimpleNode implements Node { + + protected Node parent; + protected Node[] children; + protected int id; + protected Object value; + protected ModelParser parser; + + public String op; + + public SimpleNode(int i) { + id = i; + } + + public SimpleNode(ModelParser p, int i) { + this(i); + parser = p; + } + + public void jjtOpen() { + } + + public void jjtClose() { + } + + public void jjtSetParent(Node n) { parent = n; } + public Node jjtGetParent() { return parent; } + + public void jjtAddChild(Node n, int i) { + if (children == null) { + children = new Node[i + 1]; + } else if (i >= children.length) { + Node c[] = new Node[i + 1]; + System.arraycopy(children, 0, c, 0, children.length); + children = c; + } + children[i] = n; + } + + public Node jjtGetChild(int i) { + return children[i]; + } + + public int jjtGetNumChildren() { + return (children == null) ? 0 : children.length; + } + + public void jjtSetValue(Object value) { this.value = value; } + public Object jjtGetValue() { return value; } + + /* You can override these two methods in subclasses of SimpleNode to + customize the way the node appears when the tree is dumped. If + your output uses more than one line you should override + toString(String), otherwise overriding toString() is probably all + you need to do. */ + + public String toString() { return ModelParserTreeConstants.jjtNodeName[id]; } + public String toString(String prefix) { return prefix + toString(); } + + /* Override this method if you want to customize how the node dumps + out its children. */ + + public void dump(String prefix) { + System.out.println(toString(prefix)); + if (children != null) { + for (int i = 0; i < children.length; ++i) { + SimpleNode n = (SimpleNode)children[i]; + if (n != null) { + n.dump(prefix + " "); + } + } + } + } +} + +/* JavaCC - OriginalChecksum=77b52cae8f60a97f6e484f498134f167 (do not edit this line) */ diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/Token.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/Token.java new file mode 100644 index 00000000..0cfda203 --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/Token.java @@ -0,0 +1,131 @@ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */ +/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package fi.semantum.sysdyn.solver.parser; + +/** + * Describes the input token stream. + */ + +public class Token implements java.io.Serializable { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** The line number of the first character of this Token. */ + public int beginLine; + /** The column number of the first character of this Token. */ + public int beginColumn; + /** The line number of the last character of this Token. */ + public int endLine; + /** The column number of the last character of this Token. */ + public int endColumn; + + /** + * The string image of the token. + */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** + * An optional attribute value of the Token. + * Tokens which are not used as syntactic sugar will often contain + * meaningful values that will be used later on by the compiler or + * interpreter. This attribute value is often different from the image. + * Any subclass of Token that actually wants to return a non-null value can + * override this method as appropriate. + */ + public Object getValue() { + return null; + } + + /** + * No-argument constructor + */ + public Token() {} + + /** + * Constructs a new token for the specified Image. + */ + public Token(int kind) + { + this(kind, null); + } + + /** + * Constructs a new token for the specified Image and Kind. + */ + public Token(int kind, String image) + { + this.kind = kind; + this.image = image; + } + + /** + * Returns the image. + */ + public String toString() + { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simply add something like : + * + * case MyParserConstants.ID : return new IDToken(ofKind, image); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use sit in your lexical actions. + */ + public static Token newToken(int ofKind, String image) + { + switch(ofKind) + { + default : return new Token(ofKind, image); + } + } + + public static Token newToken(int ofKind) + { + return newToken(ofKind, null); + } + +} +/* JavaCC - OriginalChecksum=849435840a0a4c85d87a2152b704b03b (do not edit this line) */ diff --git a/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/TokenMgrError.java b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/TokenMgrError.java new file mode 100644 index 00000000..f33980de --- /dev/null +++ b/dev-jkauttio/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/TokenMgrError.java @@ -0,0 +1,147 @@ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */ +/* JavaCCOptions: */ +package fi.semantum.sysdyn.solver.parser; + +/** Token Manager Error. */ +public class TokenMgrError extends Error +{ + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** + * Lexical error occurred. + */ + static final int LEXICAL_ERROR = 0; + + /** + * An attempt was made to create a second instance of a static token manager. + */ + static final int STATIC_LEXER_ERROR = 1; + + /** + * Tried to change to an invalid lexical state. + */ + static final int INVALID_LEXICAL_STATE = 2; + + /** + * Detected (and bailed out of) an infinite loop in the token manager. + */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + + /** + * Replaces unprintable characters by their escaped (or unicode escaped) + * equivalents in the given string + */ + protected static final String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + + /** + * Returns a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + * Parameters : + * EOFSeen : indicates if EOF caused the lexical error + * curLexState : lexical state in which this error occurred + * errorLine : line number when the error occurred + * errorColumn : column number when the error occurred + * errorAfter : prefix that was seen before this error occurred + * curchar : the offending character + * Note: You can customize the lexical error message by modifying this method. + */ + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { + return("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * + * "Internal Error : Please file a bug report .... " + * + * from this method for such cases in the release version of your parser. + */ + public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + /** No arg constructor. */ + public TokenMgrError() { + } + + /** Constructor with message and reason. */ + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + /** Full Constructor. */ + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); + } +} +/* JavaCC - OriginalChecksum=e56f34a3810aefee801894d03cfcfd89 (do not edit this line) */ diff --git a/dev-jkauttio/installer/.project b/dev-jkauttio/installer/.project new file mode 100644 index 00000000..dd9ed4ea --- /dev/null +++ b/dev-jkauttio/installer/.project @@ -0,0 +1,11 @@ + + + sysdyn-installer + + + + + + + + diff --git a/dev-jkauttio/installer/7za/7-zip.chm b/dev-jkauttio/installer/7za/7-zip.chm new file mode 100644 index 00000000..eee875ee Binary files /dev/null and b/dev-jkauttio/installer/7za/7-zip.chm differ diff --git a/dev-jkauttio/installer/7za/7z.sfx b/dev-jkauttio/installer/7za/7z.sfx new file mode 100644 index 00000000..97ff6055 Binary files /dev/null and b/dev-jkauttio/installer/7za/7z.sfx differ diff --git a/dev-jkauttio/installer/7za/7zS.sfx b/dev-jkauttio/installer/7za/7zS.sfx new file mode 100644 index 00000000..f37714d8 Binary files /dev/null and b/dev-jkauttio/installer/7za/7zS.sfx differ diff --git a/dev-jkauttio/installer/7za/7zSD.sfx b/dev-jkauttio/installer/7za/7zSD.sfx new file mode 100644 index 00000000..ad3915d7 Binary files /dev/null and b/dev-jkauttio/installer/7za/7zSD.sfx differ diff --git a/dev-jkauttio/installer/7za/7za.dll b/dev-jkauttio/installer/7za/7za.dll new file mode 100644 index 00000000..dcd0d3d5 Binary files /dev/null and b/dev-jkauttio/installer/7za/7za.dll differ diff --git a/dev-jkauttio/installer/7za/7za.exe b/dev-jkauttio/installer/7za/7za.exe new file mode 100644 index 00000000..12b9499a Binary files /dev/null and b/dev-jkauttio/installer/7za/7za.exe differ diff --git a/dev-jkauttio/installer/7za/7zr.exe b/dev-jkauttio/installer/7za/7zr.exe new file mode 100644 index 00000000..08acdc0e Binary files /dev/null and b/dev-jkauttio/installer/7za/7zr.exe differ diff --git a/dev-jkauttio/installer/7za/7zxa.dll b/dev-jkauttio/installer/7za/7zxa.dll new file mode 100644 index 00000000..fa5aa015 Binary files /dev/null and b/dev-jkauttio/installer/7za/7zxa.dll differ diff --git a/dev-jkauttio/installer/7za/Installer/config.txt b/dev-jkauttio/installer/7za/Installer/config.txt new file mode 100644 index 00000000..4200104f --- /dev/null +++ b/dev-jkauttio/installer/7za/Installer/config.txt @@ -0,0 +1,5 @@ +;!@Install@!UTF-8! +Title="Software 5.00" +BeginPrompt="Do you want to install the Software 5.00?" +RunProgram="7zr.exe" +;!@InstallEnd@! diff --git a/dev-jkauttio/installer/7za/Installer/cr.bat b/dev-jkauttio/installer/7za/Installer/cr.bat new file mode 100644 index 00000000..aa347978 --- /dev/null +++ b/dev-jkauttio/installer/7za/Installer/cr.bat @@ -0,0 +1,4 @@ +del archive.7z +del archive.exe +..\7zr a archive.7z ..\7zr.exe -m0=BCJ2 -m1=LZMA:d25:fb255 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3 -mx +copy /b ..\7zSD.sfx + config.txt + archive.7z archive.exe diff --git a/dev-jkauttio/installer/7za/Installer/readme.txt b/dev-jkauttio/installer/7za/Installer/readme.txt new file mode 100644 index 00000000..0da060d7 --- /dev/null +++ b/dev-jkauttio/installer/7za/Installer/readme.txt @@ -0,0 +1,98 @@ +7-Zip for installers 4.65 +------------------------- + +7-Zip is a file archiver for Windows 98/ME/NT/2000/2003/XP. + +7-Zip Copyright (C) 1999-2009 Igor Pavlov. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +7zr.exe is reduced version of 7za.exe of 7-Zip. +7zr.exe supports only 7z format with this codecs: LZMA, BCJ, BCJ2, Copy. + +Example of compressing command for installation packages: + +7zr a -t7z archive.7z * -m0=BCJ2 -m1=LZMA:d25:fb255 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3 -mx + + +7zSD.sfx is SFX module for installers (it uses msvcrt.dll) + +SFX modules for installers (7zS.sfx and 7zSD.sfx) allow to create installation program. +Such module extracts archive to temp folder and then runs specified program and removes +temp files after program finishing. Self-extract archive for installers must be created +as joining 3 files: SFX_Module, Installer_Config, 7z_Archive. +Installer_Config is optional file. You can use the following command to create installer +self-extract archive: + +copy /b 7zSD.sfx + config.txt + archive.7z archive.exe + +The smallest installation package size can be achivied, if installation files was +uncompressed before including to 7z archive. + +-y switch for installer module (at runtime) specifies quiet mode for extracting. + +Installer Config file format +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Config file contains commands for Installer. File begins from string +;!@Install@!UTF-8! and ends with ;!@InstallEnd@!. File must be written +in UTF-8 encoding. File contains string pairs: + +ID_String="Value" + +ID_String Description + +Title Title for messages +BeginPrompt Begin Prompt message +Progress Value can be "yes" or "no". Default value is "yes". +RunProgram Command for executing. Default value is "setup.exe". + Substring %%T will be replaced with path to temporary + folder, where files were extracted +Directory Directory prefix for "RunProgram". Default value is ".\\" +ExecuteFile Name of file for executing +ExecuteParameters Parameters for "ExecuteFile" + + +You can omit any values. + +There are two ways to run program: RunProgram and ExecuteFile. +Use RunProgram, if you want to run some program from .7z archive. +Use ExecuteFile, if you want to open some document from .7z archive or +if you want to execute some command from Windows. + +If you use RunProgram and if you specify empty directory prefix: Directory="", +the system searches for the executable file in the following sequence: + +1. The directory from which the application (installer) loaded. +2. The temporary folder, where files were extracted. +3. The Windows system directory. + + +Config file Examples +~~~~~~~~~~~~~~~~~~~~ + +;!@Install@!UTF-8! +Title="7-Zip 4.00" +BeginPrompt="Do you want to install the 7-Zip 4.00?" +RunProgram="setup.exe" +;!@InstallEnd@! + + + +;!@Install@!UTF-8! +Title="7-Zip 4.00" +BeginPrompt="Do you want to install the 7-Zip 4.00?" +ExecuteFile="7zip.msi" +;!@InstallEnd@! + + + +;!@Install@!UTF-8! +Title="7-Zip 4.01 Update" +BeginPrompt="Do you want to install the 7-Zip 4.01 Update?" +ExecuteFile="msiexec.exe" +ExecuteParameters="/i 7zip.msi REINSTALL=ALL REINSTALLMODE=vomus" +;!@InstallEnd@! + diff --git a/dev-jkauttio/installer/7za/copying.txt b/dev-jkauttio/installer/7za/copying.txt new file mode 100644 index 00000000..f3926a61 --- /dev/null +++ b/dev-jkauttio/installer/7za/copying.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/dev-jkauttio/installer/7za/history.txt b/dev-jkauttio/installer/7za/history.txt new file mode 100644 index 00000000..c4afdb9f --- /dev/null +++ b/dev-jkauttio/installer/7za/history.txt @@ -0,0 +1,44 @@ +7-Zip Extra history +------------------- + +4.65 2009-02-03 +------------------------------ + - Some bugs were fixed. + + +4.38 beta 2006-04-13 +------------------------------ + - SFX for installers now supports new properties in config file: + Progress, Directory, ExecuteFile, ExecuteParameters. + + +4.34 beta 2006-02-27 +------------------------------ + - ISetProperties::SetProperties: + it's possible to specify desirable number of CPU threads: + PROPVARIANT: name=L"mt", vt = VT_UI4, ulVal = NumberOfThreads + If "mt" is not defined, 7za.dll will check number of processors in system to set + number of desirable threads. + Now 7za.dll can use: + 2 threads for LZMA compressing + N threads for BZip2 compressing + 4 threads for BZip2 decompressing + Other codecs use only one thread. + Note: 7za.dll can use additional "small" threads with low CPU load. + - It's possible to call ISetProperties::SetProperties to specify "mt" property for decoder. + + +4.33 beta 2006-02-05 +------------------------------ + - Compressing speed and Memory requirements were increased. + Default dictionary size was increased: Fastest: 64 KB, Fast: 1 MB, + Normal: 4 MB, Max: 16 MB, Ultra: 64 MB. + - 7z/LZMA now can use only these match finders: HC4, BT2, BT3, BT4 + + +4.27 2005-09-21 +------------------------------ + - Some GUIDs/interfaces were changed. + IStream.h: + ISequentialInStream::Read now works as old ReadPart + ISequentialOutStream::Write now works as old WritePart diff --git a/dev-jkauttio/installer/7za/license.txt b/dev-jkauttio/installer/7za/license.txt new file mode 100644 index 00000000..7b66cf7a --- /dev/null +++ b/dev-jkauttio/installer/7za/license.txt @@ -0,0 +1,30 @@ + 7-Zip Command line version + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + License for use and distribution + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + 7-Zip Copyright (C) 1999-2009 Igor Pavlov. + + 7za.exe is distributed under the GNU LGPL license + + Notes: + You can use 7-Zip on any computer, including a computer in a commercial + organization. You don't need to register or pay for 7-Zip. + + + GNU LGPL information + -------------------- + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA diff --git a/dev-jkauttio/installer/7za/readme.txt b/dev-jkauttio/installer/7za/readme.txt new file mode 100644 index 00000000..782494a7 --- /dev/null +++ b/dev-jkauttio/installer/7za/readme.txt @@ -0,0 +1,42 @@ +7-Zip Command line version 4.65 +------------------------------- + +7-Zip is a file archiver with high compression ratio. +7za.exe is a standalone command line version of 7-Zip. + +7-Zip Copyright (C) 1999-2009 Igor Pavlov. + +Features of 7za.exe: + - High compression ratio in new 7z format + - Supported formats: + - Packing / unpacking: 7z, ZIP, GZIP, BZIP2 and TAR + - Unpacking only: Z + - Highest compression ratio for ZIP and GZIP formats. + - Fast compression and decompression + - Strong AES-256 encryption in 7z and ZIP formats. + +7za.exe is a free software distributed under the GNU LGPL. +Read license.txt for more information. + +Source code of 7za.exe and 7-Zip can be found at +http://www.7-zip.org/ + +7za.exe can work in Windows 95/98/ME/NT/2000/XP/2003/Vista. + +There is also port of 7za.exe for POSIX systems like Unix (Linux, Solaris, OpenBSD, +FreeBSD, Cygwin, AIX, ...), MacOS X and BeOS: + +http://p7zip.sourceforge.net/ + + + This distributive packet contains the following files: + + 7za.exe - 7-Zip standalone command line version. + readme.txt - This file. + copying.txt - GNU LGPL license. + license.txt - License information. + 7-zip.chm - User's Manual in HTML Help format. + + +--- +End of document diff --git a/dev-jkauttio/installer/7za/upx.exe b/dev-jkauttio/installer/7za/upx.exe new file mode 100644 index 00000000..6266213c Binary files /dev/null and b/dev-jkauttio/installer/7za/upx.exe differ diff --git a/dev-jkauttio/installer/CustomLangpack_eng.xml b/dev-jkauttio/installer/CustomLangpack_eng.xml new file mode 100644 index 00000000..7d66c45b --- /dev/null +++ b/dev-jkauttio/installer/CustomLangpack_eng.xml @@ -0,0 +1,20 @@ + + + + + + + + + Sorry, the target directory cannot currently contain + spaces due to limitations imposed by the MinGW + C compiler used by OpenModelica. + + For more information on the issue, see + http://www.mingw.org/wiki/Getting_Started. + + + + + + diff --git a/dev-jkauttio/installer/EPL.html b/dev-jkauttio/installer/EPL.html new file mode 100644 index 00000000..eae8395e --- /dev/null +++ b/dev-jkauttio/installer/EPL.html @@ -0,0 +1,266 @@ + + + + +Eclipse Public License - Version 1.0 + + + + +

Licenses

+ +

Simantics System Dynamics product consists of two main components: Simantics and Open Modelica.

+

Simantics is distributed under Eclipse Public License (EPL), see below.

+

Open Modelica is distributed under Open Source Modelica Consortium Public License (OSMC-PL), see http://www.openmodelica.org/index.php/home/license/140.

+

You are not allowed to redistribute OpenModelica integrated with Simantics, as in the System Dynamics Tool, without a membership in OSMC or without a separate contract with a level 2 member of OSMC.

+ +
+ +

Eclipse Public License - v 1.0

+ +

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE +PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR +DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS +AGREEMENT.

+ +

1. DEFINITIONS

+ +

"Contribution" means:

+ +

a) in the case of the initial Contributor, the initial +code and documentation distributed under this Agreement, and

+

b) in the case of each subsequent Contributor:

+

i) changes to the Program, and

+

ii) additions to the Program;

+

where such changes and/or additions to the Program +originate from and are distributed by that particular Contributor. A +Contribution 'originates' from a Contributor if it was added to the +Program by such Contributor itself or anyone acting on such +Contributor's behalf. Contributions do not include additions to the +Program which: (i) are separate modules of software distributed in +conjunction with the Program under their own license agreement, and (ii) +are not derivative works of the Program.

+ +

"Contributor" means any person or entity that distributes +the Program.

+ +

"Licensed Patents" mean patent claims licensable by a +Contributor which are necessarily infringed by the use or sale of its +Contribution alone or when combined with the Program.

+ +

"Program" means the Contributions distributed in accordance +with this Agreement.

+ +

"Recipient" means anyone who receives the Program under +this Agreement, including all Contributors.

+ +

2. GRANT OF RIGHTS

+ +

a) Subject to the terms of this Agreement, each +Contributor hereby grants Recipient a non-exclusive, worldwide, +royalty-free copyright license to reproduce, prepare derivative works +of, publicly display, publicly perform, distribute and sublicense the +Contribution of such Contributor, if any, and such derivative works, in +source code and object code form.

+ +

b) Subject to the terms of this Agreement, each +Contributor hereby grants Recipient a non-exclusive, worldwide, +royalty-free patent license under Licensed Patents to make, use, sell, +offer to sell, import and otherwise transfer the Contribution of such +Contributor, if any, in source code and object code form. This patent +license shall apply to the combination of the Contribution and the +Program if, at the time the Contribution is added by the Contributor, +such addition of the Contribution causes such combination to be covered +by the Licensed Patents. The patent license shall not apply to any other +combinations which include the Contribution. No hardware per se is +licensed hereunder.

+ +

c) Recipient understands that although each Contributor +grants the licenses to its Contributions set forth herein, no assurances +are provided by any Contributor that the Program does not infringe the +patent or other intellectual property rights of any other entity. Each +Contributor disclaims any liability to Recipient for claims brought by +any other entity based on infringement of intellectual property rights +or otherwise. As a condition to exercising the rights and licenses +granted hereunder, each Recipient hereby assumes sole responsibility to +secure any other intellectual property rights needed, if any. For +example, if a third party patent license is required to allow Recipient +to distribute the Program, it is Recipient's responsibility to acquire +that license before distributing the Program.

+ +

d) Each Contributor represents that to its knowledge it +has sufficient copyright rights in its Contribution, if any, to grant +the copyright license set forth in this Agreement.

+ +

3. REQUIREMENTS

+ +

A Contributor may choose to distribute the Program in object code +form under its own license agreement, provided that:

+ +

a) it complies with the terms and conditions of this +Agreement; and

+ +

b) its license agreement:

+ +

i) effectively disclaims on behalf of all Contributors +all warranties and conditions, express and implied, including warranties +or conditions of title and non-infringement, and implied warranties or +conditions of merchantability and fitness for a particular purpose;

+ +

ii) effectively excludes on behalf of all Contributors +all liability for damages, including direct, indirect, special, +incidental and consequential damages, such as lost profits;

+ +

iii) states that any provisions which differ from this +Agreement are offered by that Contributor alone and not by any other +party; and

+ +

iv) states that source code for the Program is available +from such Contributor, and informs licensees how to obtain it in a +reasonable manner on or through a medium customarily used for software +exchange.

+ +

When the Program is made available in source code form:

+ +

a) it must be made available under this Agreement; and

+ +

b) a copy of this Agreement must be included with each +copy of the Program.

+ +

Contributors may not remove or alter any copyright notices contained +within the Program.

+ +

Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent +Recipients to identify the originator of the Contribution.

+ +

4. COMMERCIAL DISTRIBUTION

+ +

Commercial distributors of software may accept certain +responsibilities with respect to end users, business partners and the +like. While this license is intended to facilitate the commercial use of +the Program, the Contributor who includes the Program in a commercial +product offering should do so in a manner which does not create +potential liability for other Contributors. Therefore, if a Contributor +includes the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and +indemnify every other Contributor ("Indemnified Contributor") +against any losses, damages and costs (collectively "Losses") +arising from claims, lawsuits and other legal actions brought by a third +party against the Indemnified Contributor to the extent caused by the +acts or omissions of such Commercial Contributor in connection with its +distribution of the Program in a commercial product offering. The +obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In +order to qualify, an Indemnified Contributor must: a) promptly notify +the Commercial Contributor in writing of such claim, and b) allow the +Commercial Contributor to control, and cooperate with the Commercial +Contributor in, the defense and any related settlement negotiations. The +Indemnified Contributor may participate in any such claim at its own +expense.

+ +

For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those +performance claims and warranties, and if a court requires any other +Contributor to pay any damages as a result, the Commercial Contributor +must pay those damages.

+ +

5. NO WARRANTY

+ +

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS +PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, +ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY +OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely +responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its +exercise of rights under this Agreement , including but not limited to +the risks and costs of program errors, compliance with applicable laws, +damage to or loss of data, programs or equipment, and unavailability or +interruption of operations.

+ +

6. DISCLAIMER OF LIABILITY

+ +

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT +NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING +WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR +DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

+ +

7. GENERAL

+ +

If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further action +by the parties hereto, such provision shall be reformed to the minimum +extent necessary to make such provision valid and enforceable.

+ +

If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other +software or hardware) infringes such Recipient's patent(s), then such +Recipient's rights granted under Section 2(b) shall terminate as of the +date such litigation is filed.

+ +

All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of time +after becoming aware of such noncompliance. If all Recipient's rights +under this Agreement terminate, Recipient agrees to cease use and +distribution of the Program as soon as reasonably practicable. However, +Recipient's obligations under this Agreement and any licenses granted by +Recipient relating to the Program shall continue and survive.

+ +

Everyone is permitted to copy and distribute copies of this +Agreement, but in order to avoid inconsistency the Agreement is +copyrighted and may only be modified in the following manner. The +Agreement Steward reserves the right to publish new versions (including +revisions) of this Agreement from time to time. No one other than the +Agreement Steward has the right to modify this Agreement. The Eclipse +Foundation is the initial Agreement Steward. The Eclipse Foundation may +assign the responsibility to serve as the Agreement Steward to a +suitable separate entity. Each new version of the Agreement will be +given a distinguishing version number. The Program (including +Contributions) may always be distributed subject to the version of the +Agreement under which it was received. In addition, after a new version +of the Agreement is published, Contributor may elect to distribute the +Program (including its Contributions) under the new version. Except as +expressly stated in Sections 2(a) and 2(b) above, Recipient receives no +rights or licenses to the intellectual property of any Contributor under +this Agreement, whether expressly, by implication, estoppel or +otherwise. All rights in the Program not expressly granted under this +Agreement are reserved.

+ +

This Agreement is governed by the laws of the State of New York and +the intellectual property laws of the United States of America. No party +to this Agreement will bring a legal action under this Agreement more +than one year after the cause of action arose. Each party waives its +rights to a jury trial in any resulting litigation.

+ + + + \ No newline at end of file diff --git a/dev-jkauttio/installer/TargetDir.txt.unix b/dev-jkauttio/installer/TargetDir.txt.unix new file mode 100644 index 00000000..55c23358 --- /dev/null +++ b/dev-jkauttio/installer/TargetDir.txt.unix @@ -0,0 +1 @@ +${USER_HOME}/Simantics/Sysdyn/$APP_VER \ No newline at end of file diff --git a/dev-jkauttio/installer/TargetDir.txt.windows b/dev-jkauttio/installer/TargetDir.txt.windows new file mode 100644 index 00000000..ccd82001 --- /dev/null +++ b/dev-jkauttio/installer/TargetDir.txt.windows @@ -0,0 +1 @@ +C:\Simantics\Sysdyn\$APP_VER \ No newline at end of file diff --git a/dev-jkauttio/installer/build.properties.unix b/dev-jkauttio/installer/build.properties.unix new file mode 100644 index 00000000..71833353 --- /dev/null +++ b/dev-jkauttio/installer/build.properties.unix @@ -0,0 +1,7 @@ +izpack.home=/opt/IzPack +izpack.src=${izpack.home}/src +izpack.compiler=${izpack.home}/bin/compile +izpack2exe.home=${izpack.home}/utils/wrappers/izpack2exe +izpack2exe=${izpack2exe.home}/izpack2exe.py +sevenzip.executable=/usr/bin/7za +upx.executable=/usr/bin/upx diff --git a/dev-jkauttio/installer/build.properties.windows b/dev-jkauttio/installer/build.properties.windows new file mode 100644 index 00000000..4d6a2836 --- /dev/null +++ b/dev-jkauttio/installer/build.properties.windows @@ -0,0 +1,7 @@ +izpack.home=C:/Program Files/IzPack +izpack.src=${izpack.home}/src +izpack.compiler=${izpack.home}/bin/compile.bat +izpack2exe.home=${izpack.home}/utils/wrappers/izpack2exe +izpack2exe=${izpack2exe.home}/izpack2exe.exe +sevenzip.executable=${basedir}\\7za\\7za.exe +upx.executable=${basedir}\\7za\\upx.exe \ No newline at end of file diff --git a/dev-jkauttio/installer/build.xml b/dev-jkauttio/installer/build.xml new file mode 100644 index 00000000..7ac10e3f --- /dev/null +++ b/dev-jkauttio/installer/build.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/installer/custom/NonBlankTargetPanel.java b/dev-jkauttio/installer/custom/NonBlankTargetPanel.java new file mode 100644 index 00000000..5a0f937d --- /dev/null +++ b/dev-jkauttio/installer/custom/NonBlankTargetPanel.java @@ -0,0 +1,51 @@ + +/* + * Created on 29.06.2005 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package com.izforge.izpack.panels; + +import com.izforge.izpack.installer.InstallData; +import com.izforge.izpack.installer.InstallerFrame; + + +/** + * @author fabrice mirabile + */ +public class NonBlankTargetPanel extends TargetPanel +{ + private static final long serialVersionUID = 3248705610571943817L; + + public NonBlankTargetPanel(InstallerFrame parent, InstallData idata) + { + super(parent, idata); + } + + public boolean isValidated() + { + String chosenPath = pathSelectionPanel.getPath(); + if(chosenPath == null || chosenPath.length() < 1 ) + return( false ); + if( chosenPath.indexOf(" ") >= 0 ) + { + emitError(parent.langpack.getString("installer.error"), + parent.langpack.getString("NonBlankTargetPanel.noBlanks")); + return( false ); + } + return(super.isValidated() ); + } + + public void panelActivate() + { + super.panelActivate(); + String chosenPath = pathSelectionPanel.getPath(); + if(chosenPath == null || chosenPath.length() < 1 ) + return; + if( chosenPath.indexOf(" ") >= 0 ) + pathSelectionPanel.setPath(""); + } + + +} \ No newline at end of file diff --git a/dev-jkauttio/installer/custom/build.xml b/dev-jkauttio/installer/custom/build.xml new file mode 100644 index 00000000..35c193fb --- /dev/null +++ b/dev-jkauttio/installer/custom/build.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/installer/custom/izpack-src-build.xml b/dev-jkauttio/installer/custom/izpack-src-build.xml new file mode 100644 index 00000000..436cc5c2 --- /dev/null +++ b/dev-jkauttio/installer/custom/izpack-src-build.xml @@ -0,0 +1,1346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + sucessfully created: + ${dist.dir}/${installer.name}${ver}.${rel}.jar + + + + + + + + + + + + + + + + + + + + + + + Fixing linefeeds for several files in: + "${dist.src.dir}" + and + "${dist.bin.dir}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/installer/default_shortcut_specification.xml b/dev-jkauttio/installer/default_shortcut_specification.xml new file mode 100644 index 00000000..091dca92 --- /dev/null +++ b/dev-jkauttio/installer/default_shortcut_specification.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/installer/download b/dev-jkauttio/installer/download new file mode 100755 index 00000000..4288e4e2 --- /dev/null +++ b/dev-jkauttio/installer/download @@ -0,0 +1,10 @@ +#!/bin/bash + +pushd . +cd `dirname $0` +BUILD=$1 + +rm -f files/dist.zip +cp -v /var/lib/jenkins/jobs/${BUILD} files/dist.zip || exit -1 + +popd > /dev/null diff --git a/dev-jkauttio/installer/download.bat b/dev-jkauttio/installer/download.bat new file mode 100644 index 00000000..73752506 --- /dev/null +++ b/dev-jkauttio/installer/download.bat @@ -0,0 +1,17 @@ +@echo off + +setlocal +pushd . +cd %~dp0 +set BUILD=%1 +set JOB_NAME=%2 + +del /s /q dist +wget -O dist.zip "http://www.simantics.org/hudson/job/%JOB_NAME%/%BUILD%/artifact/build/dist/*zip*/dist.zip" +unzip -o dist.zip +del files\dist.zip +copy dist\*sdk*.zip files\dist.zip +del /s /q dist.zip dist + +popd +endlocal diff --git a/dev-jkauttio/installer/files/Microsoft.VC90.CRT.setup.exe b/dev-jkauttio/installer/files/Microsoft.VC90.CRT.setup.exe new file mode 100644 index 00000000..823345da Binary files /dev/null and b/dev-jkauttio/installer/files/Microsoft.VC90.CRT.setup.exe differ diff --git a/dev-jkauttio/installer/files/install_msvcrt.bat b/dev-jkauttio/installer/files/install_msvcrt.bat new file mode 100644 index 00000000..7d56badc --- /dev/null +++ b/dev-jkauttio/installer/files/install_msvcrt.bat @@ -0,0 +1,2 @@ +@echo off +"%~dp0Microsoft.VC90.CRT.setup.exe" /q \ No newline at end of file diff --git a/dev-jkauttio/installer/files/jre-6u29-windows-i586-iftw.exe b/dev-jkauttio/installer/files/jre-6u29-windows-i586-iftw.exe new file mode 100644 index 00000000..39a0d7b9 Binary files /dev/null and b/dev-jkauttio/installer/files/jre-6u29-windows-i586-iftw.exe differ diff --git a/dev-jkauttio/installer/installer.xml b/dev-jkauttio/installer/installer.xml new file mode 100644 index 00000000..db16f51e --- /dev/null +++ b/dev-jkauttio/installer/installer.xml @@ -0,0 +1,104 @@ + + + + Simantics System Dynamics + Sysdyn + 1.6 + + + + http://www.simantics.org + + 1.6 + no + yes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Simantics SDK requires an up-to-date version of the Java Runtime Environment version 6. +If your JRE is old, you can install JRE 6 update 29 by selecting this. +NOTE: Installing this will require network access for downloading Java components. +Other Java installers are available at http://www.java.com/en/download/manual.jsp. + + + + + + + + Microsoft Visual C++ Run-Time 9.0 libraries. +These are required by native Simantics components. +Nothing is done if these are already installed on your system. + + + + + + + + + The Simantics System Dynamics application. + + + + + + + + diff --git a/dev-jkauttio/installer/side.png b/dev-jkauttio/installer/side.png new file mode 100644 index 00000000..e5438045 Binary files /dev/null and b/dev-jkauttio/installer/side.png differ diff --git a/dev-jkauttio/installer/side.svg b/dev-jkauttio/installer/side.svg new file mode 100644 index 00000000..ffb16f8d --- /dev/null +++ b/dev-jkauttio/installer/side.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + Simantics + + diff --git a/dev-jkauttio/installer/unzip.exe b/dev-jkauttio/installer/unzip.exe new file mode 100644 index 00000000..1e947195 Binary files /dev/null and b/dev-jkauttio/installer/unzip.exe differ diff --git a/dev-jkauttio/installer/userInputSpec.xml b/dev-jkauttio/installer/userInputSpec.xml new file mode 100644 index 00000000..200fb9d3 --- /dev/null +++ b/dev-jkauttio/installer/userInputSpec.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/installer/wget.exe b/dev-jkauttio/installer/wget.exe new file mode 100644 index 00000000..1b15a042 Binary files /dev/null and b/dev-jkauttio/installer/wget.exe differ diff --git a/dev-jkauttio/org.simantics.fmu.me.win32/.classpath b/dev-jkauttio/org.simantics.fmu.me.win32/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu.me.win32/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu.me.win32/.project b/dev-jkauttio/org.simantics.fmu.me.win32/.project new file mode 100644 index 00000000..e22d6638 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu.me.win32/.project @@ -0,0 +1,28 @@ + + + org.simantics.fmu.me.win32 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.fmu.me.win32/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.fmu.me.win32/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..f287d53c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu.me.win32/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.fmu.me.win32/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.fmu.me.win32/META-INF/MANIFEST.MF new file mode 100644 index 00000000..a08acbbf --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu.me.win32/META-INF/MANIFEST.MF @@ -0,0 +1,9 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Win32 binaries for FMI model exchange +Bundle-SymbolicName: org.simantics.fmu.me.win32 +Bundle-Version: 1.1.0.qualifier +Bundle-Vendor: Semantum Oy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0", + org.simantics.utils;bundle-version="1.1.0" diff --git a/dev-jkauttio/org.simantics.fmu.me.win32/build.properties b/dev-jkauttio/org.simantics.fmu.me.win32/build.properties new file mode 100644 index 00000000..150031be --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu.me.win32/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + libraries/ diff --git a/dev-jkauttio/org.simantics.fmu.me.win32/libraries/FMUSimulator.dll b/dev-jkauttio/org.simantics.fmu.me.win32/libraries/FMUSimulator.dll new file mode 100644 index 00000000..dc1720d9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu.me.win32/libraries/FMUSimulator.dll differ diff --git a/dev-jkauttio/org.simantics.fmu.me.win32/libraries/miniunz.dll b/dev-jkauttio/org.simantics.fmu.me.win32/libraries/miniunz.dll new file mode 100644 index 00000000..56a5b2f5 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu.me.win32/libraries/miniunz.dll differ diff --git a/dev-jkauttio/org.simantics.fmu.me.win32/libraries/zlibwapi.dll b/dev-jkauttio/org.simantics.fmu.me.win32/libraries/zlibwapi.dll new file mode 100644 index 00000000..767b655a Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu.me.win32/libraries/zlibwapi.dll differ diff --git a/dev-jkauttio/org.simantics.fmu/.classpath b/dev-jkauttio/org.simantics.fmu/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/.project b/dev-jkauttio/org.simantics.fmu/.project new file mode 100644 index 00000000..9b34bda9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/.project @@ -0,0 +1,28 @@ + + + org.simantics.fmu + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.fmu/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.fmu/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..f287d53c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/7z.dll b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/7z.dll new file mode 100644 index 00000000..7e629218 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/7z.dll differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/7z.exe b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/7z.exe new file mode 100644 index 00000000..f1f56e37 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/7z.exe differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/License.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/License.txt new file mode 100644 index 00000000..44802a8a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/License.txt @@ -0,0 +1,57 @@ + 7-Zip + ~~~~~ + License for use and distribution + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + 7-Zip Copyright (C) 1999-2007 Igor Pavlov. + + Licenses for files are: + + 1) 7z.dll: GNU LGPL + unRAR restriction + 2) All other files: GNU LGPL + + The GNU LGPL + unRAR restriction means that you must follow both + GNU LGPL rules and unRAR restriction rules. + + + Note: + You can use 7-Zip on any computer, including a computer in a commercial + organization. You don't need to register or pay for 7-Zip. + + + GNU LGPL information + -------------------- + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + unRAR restriction + ----------------- + + The decompression engine for RAR archives was developed using source + code of unRAR program. + All copyrights to original unRAR code are owned by Alexander Roshal. + + The license for original unRAR code has the following restriction: + + The unRAR sources cannot be used to re-create the RAR compression algorithm, + which is proprietary. Distribution of modified unRAR sources in separate form + or as a part of other software is permitted, provided that it is clearly + stated in the documentation and source comments that the code may + not be used to develop a RAR (WinRAR) compatible archiver. + + + -- + Igor Pavlov diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/fmusim_cs.exe b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/fmusim_cs.exe new file mode 100644 index 00000000..7020feab Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/fmusim_cs.exe differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/fmusim_me.exe b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/fmusim_me.exe new file mode 100644 index 00000000..41999eee Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/bin/fmusim_me.exe differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/FmuSdk_reference.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/FmuSdk_reference.html new file mode 100644 index 00000000..5f2e531f --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/FmuSdk_reference.html @@ -0,0 +1,210 @@ + + + Documentation for FMU SDK 1.0.2 + + + +

FMU SDK 1.0.2

+ The FMU SDK is a free software development kit provided by + QTronic. + The FMU SDK demonstrates basic use of Functional Mockup Units (FMUs) + as defined by the following specifications + + The FMI specifications are available from + here. + A short overview on FMUs and the FMI specification can be found + here. + The FMU SDK can also serve as starting point for developing applications + that create or process FMUs. +

+ The FMU SDK contains the C sources for various discrete and continuous + FMU models, a batch file for compiling and zip'ing these models, + an XML parser for parsing the model description of an FMU and two simple + simulation programs that run a given FMU and output the result as CSV file. +

+ The FMU SDK can be downloaded from + + http://www.qtronic.de/doc/fmusdk.zip. + For bug reports, questions or comments regarding the FMU SDK, please + mail to fmu@qtronic.de. + Questions or comments regarding the FMU specification should be sent to + info@functional-mockup-interface.org. + + +


+ +

Table of Contents

+ + +
+

Building and Installing the FMU SDK

+Downwload the FMU SDK from here, +and unzip in a directory where you have write access. +That directory is called FMUSDK_HOME below and may contain white space, such as in "C:\Program Files\fmusdk". +The FMU SDK contains only the C sources of the FMUs and the simulator, not the executables, +and should compile on all Windows platforms. +

+To build the FMUs and the simulator, double click on FMUSDK_HOME\src\build_all.bat. +This should create fmu files in FMUSDK_HOME\fmu\me and FMUSDK_HOME\fmu\cs, as well as two +simulators fmusim_me.exe and fmusim_cs.exe in FMUSDK_HOME\bin. +Compilation using build_all.bat requires that you have installed +Microsoft Visual Studio 2005 (VS8) or 2008 (VS9), for example the free Express Edition. +To compile with another compiler, adapt file build_all.bat. +


+

Simulating an FMU

+To run a given FMU, open a command shell in directory FMUSDK_HOME and run the command fmusim +
+fmusim fmi model.fmu tEnd h loggingOn csvSeparator
+  fmi ........... cs for co-simulation or me for model exchange, required
+  model.fmu ..... path to FMU, relative to current dir or absolute, required
+  tEnd .......... end  time of simulation, optional, defaults to 1.0 sec
+  h ............. step size of simulation, optional, defaults to 0.1 sec
+  loggingOn ..... 1 to activate logging,   optional, defaults to 0
+  csvSeparator .. c for comma, s for semicolon, optional, defaults to c
+
+This unzips the given FMU, parses the contained modelDescription.xml file, simulates +the FMU from t=0 to t=tEnd, and writes the solution to file 'result.csv'. The file +is written in CSV format (comma-separated values), using ';' to separate columns and +using ',' instead of '.' as decimal dot to print floating-point numbers. +To change the result file format, use the 'csv separator' option. +The logging option activates logging of the simulated FMU. The FMI specification does +not specify, what exactly to log in this case. However, when logging is switched on, +the sample FMUs of the FMU SDK log every single FMU function call. Moreover, the +fmusim simulators logs every step and every event that is detected. +

+Example command: +

+> fmusim me fmu/me/bouncingBall.fmu 5 0.1 0 s
+FMU Simulator: run 'fmu/bouncingBall.fmu' from t=0..5 with step size h=0.1, loggingOn=0, csv separator=';'
+Simulation from 0 to 5 terminated successful
+  steps ............ 51
+  fixed step size .. 0.1
+  time events ...... 0
+  state events ..... 14
+  step events ...... 0
+CSV file 'result.csv' written
+
+To plot the result file, open it e.g. in a spread-sheet program, such as Miscrosoft Excel or OpenOffice Calc. +The figure below shows the result of the above simulation when plotted using OpenOffice Calc 3.0. +Note that the height h of the bouncing ball as computed by fmusim becomes negative at the contact points, +while the true solution of the FMU does actually not contain negative height values. +This is not a limitation of the FMU, but of fmusim_me, which does not attempt to locate the +exact time of state events. +To improve this, either reduce the step size or add your own procedure for state-event location to fmusim_me. +

+ + +


+

Creating your own FMUs

+The FMU SDK contains a few sample FMUs +
    +
  • dq the Dahlquist test function x = -k der(x)
  • +
  • inc increments an integer counter every second
  • +
  • values demonstrates the use of all scalar FMU data types
  • +
  • vanDerPol ODE with 2 continuous states
  • +
  • bouncingBall a bouncing ball that defines state events
  • +
+To implement your own FMU using the FMU SDK, create a directory - say xy - in FMUSDK_HOME\src\models, and create +files modelDescription.xml and xy.c there. +The names of the new directory and the .c file must be the same. The content of the .c file should +follow the existing FMU examples, see the comments in the example code. +The XML file must not contain the <implementation> +element and the closing </fmiModelDescription> tag, because this is added automatically during build. +When done with editing the xml file and xy.c, open a command shell in FMUSDK_HOME\src\model and run the +command build_fmu me xy to build an FMU for model exchange, or build_fmu cs xy to build an FMU for co-simulation. +This should create the FMU file xy.fmu in directory FMUSDK_HOME\fmu\me or FMUSDK_HOME\fmu\cs. +

+The figure below might help to create or process the XML file modelDescription.xml. +It shows all XML elements (without attributes) used in the schema files (XSD) for +model exchange and co-simulation. Notation: UML class diagram. + + +


+ +

FMU SDK Revision history

+
    +
  • 07.02.2010, Version 1.0 +
      +
    • First release
    • +
    • demo FMI for Model Exchange 1.0
    • +
    +
  • +
  • 05.03.2010, Version 1.0.1 +
      +
    • demo FMI for Model Exchange 1.0
    • +
    • bug-fix in fmuTemplate.c: fmiSetString now copies the passed + string argument and fmiFreeModelInstance frees all string copies +
    • +
    • fmusim/main.c: removed strerror(GetLastError()) from error messages +
    • +
    +
  • +
  • 22.08.2011, Version 1.0.2 +
      +
    • demo FMI for Model Exchange 1.0 and FMI for Co-Simulation 1.0
    • +
    • added support for FMI for Co-Simulation 1.0 (standalone, no tool coupling)
    • +
    • bug-fix in fmusim/main.c: added missing calls to fmiTerminate and fmiFreeModelInstance
    • +
    +
  • +
+ +

License conditions

+The FMU SDK is provided by QTronic under the +BSD License. +
+
+FMU SDK license 
+
+Copyright © 2008-2011, QTronic GmbH. All rights reserved.
+The FmuSdk is licensed by the copyright holder under the BSD License
+(http://www.opensource.org/licenses/bsd-license.html):
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY QTRONIC GMBH "AS IS" AND ANY EXPRESS OR 
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL QTRONIC GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ +The following additional tools are distributed with the FMU SDK under their +respective licenses +
    +
  • 7z 4.57 + by Igor Pavlov. Used here to zip and unzip FMUs, + license is here.
  • +
  • eXpat 2.0.1 + by James Clark. Used here to parse the modelDescription.xml file of an FMU, + license is here.
  • +
+
+ + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/bouncingBallCalc.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/bouncingBallCalc.png new file mode 100644 index 00000000..1944a623 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/bouncingBallCalc.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/fmu10-xml-schema.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/fmu10-xml-schema.png new file mode 100644 index 00000000..772eaf6d Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/fmu10-xml-schema.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/fmus.jpg b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/fmus.jpg new file mode 100644 index 00000000..d7eec877 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/fmus.jpg differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/fmusdk_license.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/fmusdk_license.txt new file mode 100644 index 00000000..e1ac0aa9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/doc/fmusdk_license.txt @@ -0,0 +1,24 @@ + +FMU SDK license + +Copyright © 2008-2011, QTronic GmbH. All rights reserved. +The FmuSdk is licensed by the copyright holder under the BSD License +(http://www.opensource.org/licenses/bsd-license.html): +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +- Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY QTRONIC GMBH "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL QTRONIC GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/Model.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/Model.fmu new file mode 100644 index 00000000..ad3b03e2 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/Model.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/bouncingBall.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/bouncingBall.fmu new file mode 100644 index 00000000..7f009f62 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/bouncingBall.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/dq.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/dq.fmu new file mode 100644 index 00000000..38e5c2bd Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/dq.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/inc.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/inc.fmu new file mode 100644 index 00000000..fbbd4490 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/inc.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/values.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/values.fmu new file mode 100644 index 00000000..7b03aa41 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/values.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/vanDerPol.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/vanDerPol.fmu new file mode 100644 index 00000000..f36f4c22 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/cs/vanDerPol.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/bouncingBall.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/bouncingBall.fmu new file mode 100644 index 00000000..f0847441 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/bouncingBall.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/dq.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/dq.fmu new file mode 100644 index 00000000..821fb564 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/dq.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/inc.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/inc.fmu new file mode 100644 index 00000000..d9a5b7d6 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/inc.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/values.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/values.fmu new file mode 100644 index 00000000..a450894c Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/values.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/vanDerPol.fmu b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/vanDerPol.fmu new file mode 100644 index 00000000..e694c540 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmu/me/vanDerPol.fmu differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmusdk.zip b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmusdk.zip new file mode 100644 index 00000000..519bf018 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmusdk.zip differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmusim.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmusim.bat new file mode 100644 index 00000000..c9e575c1 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/fmusim.bat @@ -0,0 +1,9 @@ +@echo off +rem ------------------------------------------------------------ +rem To run a simulation, start this batch in this directory. +rem Example: fmusim me fmu/me/dq.fmu 0.3 0.1 1 c +rem To build simulators bin\*.exe and FMUs, run src\build_all.bat +rem ------------------------------------------------------------ + +set FMUSDK_HOME=. +if %1==me (bin\fmusim_me.exe %2 %3 %4 %5 %6) else bin\fmusim_cs.exe %2 %3 %4 %5 %6 diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/run_all.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/run_all.bat new file mode 100644 index 00000000..8de848b8 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/run_all.bat @@ -0,0 +1,50 @@ +@echo off + +rem ------------------------------------------------------------ +rem This batch simulates all FMUs of the FmuSDK and stores +rem simulation results in CSV files, one per simulation run. +rem (c) 2011 QTronic GmbH +rem ------------------------------------------------------------ + +echo ----------------------------------------------------------- +echo Runnig all FMUs of the FmuSDK ... + +echo ----------------------------------------------------------- +call fmusim me fmu\me\bouncingBall.fmu 4 0.01 0 c +move /Y result.csv result_me_bouncingBall.csv + +echo ----------------------------------------------------------- +call fmusim cs fmu\cs\bouncingBall.fmu 4 0.01 0 c +move /Y result.csv result_cs_bouncingBall.csv + +echo ----------------------------------------------------------- +call fmusim me fmu\me\vanDerPol.fmu 5 0.1 0 c +move /Y result.csv result_me_vanDerPol.csv + +echo ----------------------------------------------------------- +call fmusim cs fmu\cs\vanDerPol.fmu 5 0.1 0 c +move /Y result.csv result_cs_vanDerPol.csv + +echo ----------------------------------------------------------- +call fmusim me fmu\me\dq.fmu 1 0.1 0 c +move /Y result.csv result_me_dq.csv + +echo ----------------------------------------------------------- +call fmusim cs fmu\cs\dq.fmu 1 0.1 0 c +move /Y result.csv result_cs_dq.csv + +echo ----------------------------------------------------------- +call fmusim me fmu\me\inc.fmu 15 15 0 c +move /Y result.csv result_me_inc.csv + +echo ----------------------------------------------------------- +call fmusim cs fmu\cs\inc.fmu 15 0.5 0 c +move /Y result.csv result_cs_inc.csv + +echo ----------------------------------------------------------- +call fmusim me fmu\me\values.fmu 12 12 0 c +move /Y result.csv result_me_values.csv + +echo ----------------------------------------------------------- +call fmusim cs fmu\cs\values.fmu 12 0.3 0 c +move /Y result.csv result_cs_values.csv diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/build_all.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/build_all.bat new file mode 100644 index 00000000..cdd75152 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/build_all.bat @@ -0,0 +1,28 @@ +@echo off + +rem ------------------------------------------------------------ +rem This batch builds both simulators and all FMUs of the FmuSDK +rem (c) 2011 QTronic GmbH +rem ------------------------------------------------------------ + +call build_fmusim_me +call build_fmusim_cs +echo ----------------------------------------------------------- +echo Making the FMUs of the FmuSDK ... +pushd models + +call build_fmu me dq +call build_fmu me inc +call build_fmu me values +call build_fmu me vanDerPol +call build_fmu me bouncingBall + +call build_fmu cs dq +call build_fmu cs inc +call build_fmu cs values +call build_fmu cs vanDerPol +call build_fmu cs bouncingBall + +popd + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/build_fmusim_cs.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/build_fmusim_cs.bat new file mode 100644 index 00000000..6e90292c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/build_fmusim_cs.bat @@ -0,0 +1,48 @@ +@echo off +rem ------------------------------------------------------------ +rem This batch builds the FMU simulator fmusim_cs.exe +rem (c) 2011 QTronic GmbH +rem ------------------------------------------------------------ + +echo ----------------------------------------------------------- +echo building fmusim_cs.exe - FMI for Co-Simulation 1.0 +echo ----------------------------------------------------------- + +rem save env variable settings +set PREV_PATH=%PATH% +if defined INCLUDE set PREV_INCLUDE=%INLUDE% +if defined LIB set PREV_LIB=%LIB% +if defined LIBPATH set PREV_LIBPATH=%LIBPATH% + +rem setup the compiler +if defined VS90COMNTOOLS (call "%VS90COMNTOOLS%\vsvars32.bat") else ^ +if defined VS80COMNTOOLS (call "%VS80COMNTOOLS%\vsvars32.bat") else ^ +goto noCompiler + +set SRC=fmusim_cs\main.c ..\shared\xml_parser.c ..\shared\stack.c ..\shared\sim_support.c +set INC=/Iinclude /I../shared /Ifmusim_cs +set OPTIONS=/DFMI_COSIMULATION /wd4090 /nologo + +rem create fmusim_cs.exe in the fmusim_cs dir +rem /wd4090 to disable warnings about different 'const' qualifiers +pushd co_simulation +cl %SRC% %INC% %OPTIONS% /Fefmusim_cs.exe /link ..\shared\libexpatMT.lib +del *.obj +popd +if not exist co_simulation\fmusim_cs.exe goto compileError +move /Y co_simulation\fmusim_cs.exe ..\bin +goto done + +:noCompiler +echo No Microsoft Visual C compiler found + +:compileError +echo build of fmusim_cs.exe failed + +:done +rem undo variable settings performed by vsvars32.bat +set PATH=%PREV_PATH% +if defined PREV_INCLUDE set INCLUDE=%PREV_INLUDE% +if defined PREV_LIB set LIB=%PREV_LIB% +if defined PREV_LIBPATH set LIBPATH=%PREV_LIBPATH% +echo done. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/build_fmusim_me.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/build_fmusim_me.bat new file mode 100644 index 00000000..0828428b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/build_fmusim_me.bat @@ -0,0 +1,51 @@ +@echo off +rem ------------------------------------------------------------ +rem This batch builds the FMU simulator fmusim_me.exe +rem (c) 2011 QTronic GmbH +rem ------------------------------------------------------------ + +echo ----------------------------------------------------------- +echo building fmusim_me.exe - FMI for Model Exchange 1.0 +echo ----------------------------------------------------------- + +rem save env variable settings +set PREV_PATH=%PATH% +if defined INCLUDE set PREV_INCLUDE=%INLUDE% +if defined LIB set PREV_LIB=%LIB% +if defined LIBPATH set PREV_LIBPATH=%LIBPATH% + +rem setup the compiler +if defined VS90COMNTOOLS (call "%VS90COMNTOOLS%\vsvars32.bat") else ^ +if defined VS80COMNTOOLS (call "%VS80COMNTOOLS%\vsvars32.bat") else ^ +goto noCompiler + +set SRC=fmusim_me\main.c ..\shared\xml_parser.c ..\shared\stack.c ..\shared\sim_support.c +set INC=/Iinclude /I../shared /Ifmusim_me +set OPTIONS=/wd4090 /nologo + +rem create fmusim_me.exe in the fmusim_me dir +rem /wd4090 to disable warnings about different 'const' qualifiers +pushd model_exchange +cl %SRC% %INC% %OPTIONS% /Fefmusim_me.exe /link ..\shared\libexpatMT.lib +del *.obj +popd +if not exist model_exchange\fmusim_me.exe goto compileError +move /Y model_exchange\fmusim_me.exe ..\bin +goto done + +:noCompiler +echo No Microsoft Visual C compiler found + +:compileError +echo build of fmusim_me.exe failed + +:done +rem undo variable settings performed by vsvars32.bat +set PATH=%PREV_PATH% +if defined PREV_INCLUDE set INCLUDE=%PREV_INLUDE% +if defined PREV_LIB set LIB=%PREV_LIB% +if defined PREV_LIBPATH set LIBPATH=%PREV_LIBPATH% +echo done. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/fmusim_cs/fmi_cs.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/fmusim_cs/fmi_cs.h new file mode 100644 index 00000000..f446eac1 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/fmusim_cs/fmi_cs.h @@ -0,0 +1,78 @@ +/* ------------------------------------------------------------------------- + * fmi_cs.h + * Function types for all function of the "FMI for Co-Simulation 1.0" + * and a struct with the corresponding function pointers. + * Copyright 2011 QTronic GmbH. All rights reserved. + * ------------------------------------------------------------------------- + */ + +#ifndef FMI_CS_H +#define FMI_CS_H + +#include +#include "fmiFunctions.h" +#include "xml_parser.h" + +typedef const char* (*fGetTypesPlatform)(); +typedef const char* (*fGetVersion)(); +typedef fmiStatus (*fSetDebugLogging) (fmiComponent c, fmiBoolean loggingOn); +typedef fmiStatus (*fSetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); +typedef fmiStatus (*fSetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); +typedef fmiStatus (*fSetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); +typedef fmiStatus (*fSetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); +typedef fmiStatus (*fGetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); +typedef fmiStatus (*fGetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); +typedef fmiStatus (*fGetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); +typedef fmiStatus (*fGetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); +typedef fmiComponent (*fInstantiateSlave) (fmiString instanceName, fmiString fmuGUID, fmiString fmuLocation, + fmiString mimeType, fmiReal timeout, fmiBoolean visible, fmiBoolean interactive, + fmiCallbackFunctions functions, fmiBoolean loggingOn); +typedef fmiStatus (*fInitializeSlave)(fmiComponent c, fmiReal tStart, fmiBoolean StopTimeDefined, fmiReal tStop); +typedef fmiStatus (*fTerminateSlave) (fmiComponent c); +typedef fmiStatus (*fResetSlave) (fmiComponent c); +typedef void (*fFreeSlaveInstance)(fmiComponent c); +typedef fmiStatus (*fSetRealInputDerivatives)(fmiComponent c, const fmiValueReference vr[], size_t nvr, + const fmiInteger order[], const fmiReal value[]); +typedef fmiStatus (*fGetRealOutputDerivatives)(fmiComponent c, const fmiValueReference vr[], size_t nvr, + const fmiInteger order[], fmiReal value[]); +typedef fmiStatus (*fCancelStep)(fmiComponent c); +typedef fmiStatus (*fDoStep)(fmiComponent c, fmiReal currentCommunicationPoint, + fmiReal communicationStepSize, fmiBoolean newStep); +typedef fmiStatus (*fGetStatus) (fmiComponent c, const fmiStatusKind s, fmiStatus* value); +typedef fmiStatus (*fGetRealStatus) (fmiComponent c, const fmiStatusKind s, fmiReal* value); +typedef fmiStatus (*fGetIntegerStatus)(fmiComponent c, const fmiStatusKind s, fmiInteger* value); +typedef fmiStatus (*fGetBooleanStatus)(fmiComponent c, const fmiStatusKind s, fmiBoolean* value); +typedef fmiStatus (*fGetStringStatus) (fmiComponent c, const fmiStatusKind s, fmiString* value); + +typedef struct { + ModelDescription* modelDescription; + HANDLE dllHandle; + fGetTypesPlatform getTypesPlatform; + fGetVersion getVersion; + fSetDebugLogging setDebugLogging; + fSetReal setReal; + fSetInteger setInteger; + fSetBoolean setBoolean; + fSetString setString; + fGetReal getReal; + fGetInteger getInteger; + fGetBoolean getBoolean; + fGetString getString; + fInstantiateSlave instantiateSlave; + fInitializeSlave initializeSlave; + fTerminateSlave terminateSlave; + fResetSlave resetSlave; + fFreeSlaveInstance freeSlaveInstance; + fGetRealOutputDerivatives getRealOutputDerivatives; + fSetRealInputDerivatives setRealInputDerivatives; + fDoStep doStep; + fCancelStep cancelStep; + fGetStatus getStatus; + fGetRealStatus getRealStatus; + fGetIntegerStatus getIntegerStatus; + fGetBooleanStatus getBooleanStatus; + fGetStringStatus getStringStatus; +} FMU; + +#endif // FMI_CS_H + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/fmusim_cs/main.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/fmusim_cs/main.c new file mode 100644 index 00000000..f0673d11 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/fmusim_cs/main.c @@ -0,0 +1,127 @@ +/* ------------------------------------------------------------------------- + * main.c + * Implements simulation of a single FMU instance + * that implements the "FMI for Co-Simulation 1.0" interface. + * Command syntax: see printHelp() + * Simulates the given FMU from t = 0 .. tEnd with fixed step size h and + * writes the computed solution to file 'result.csv'. + * The CSV file (comma-separated values) may e.g. be plotted using + * OpenOffice Calc or Microsoft Excel. + * This progamm demonstrates basic use of an FMU. + * Real applications may use advanced master algorithms to cosimulate + * many FMUs, limit the numerical error using error estimation + * and back-stepping, provide graphical plotting utilities, debug support, + * and user control of parameter and start values, or perform a clean + * error handling (e.g. call freeSlaveInstance when a call to the fmu + * returns with error). All this is missing here. + * + * Revision history + * 22.08.2011 initial version released in FMU SDK 1.0.2 + * + * Free libraries and tools used to implement this simulator: + * - header files from the FMU specification + * - eXpat 2.0.1 XML parser, see http://expat.sourceforge.net + * - 7z.exe 4.57 zip and unzip tool, see http://www.7-zip.org + * Author: Jakob Mauss + * Copyright 2011 QTronic GmbH. All rights reserved. + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include "fmi_cs.h" +#include "sim_support.h" + +FMU fmu; // the fmu to simulate + +// simulate the given FMU using the forward euler method. +// time events are processed by reducing step size to exactly hit tNext. +// state events are checked and fired only at the end of an Euler step. +// the simulator may therefore miss state events and fires state events typically too late. +static int simulate(FMU* fmu, double tEnd, double h, fmiBoolean loggingOn, char separator) { + double time; + double tStart = 0; // start time + const char* guid; // global unique id of the fmu + fmiComponent c; // instance of the fmu + fmiStatus fmiFlag; // return code of the fmu functions + const char* fmuLocation = NULL; // path to the fmu as URL, "file://C:\QTronic\sales" + const char* mimeType = "application/x-fmu-sharedlibrary"; // denotes tool in case of tool coupling + fmiReal timeout = 1000; // wait period in milli seconds, 0 for unlimited wait period" + fmiBoolean visible = fmiFalse; // no simulator user interface + fmiBoolean interactive = fmiFalse; // simulation run without user interaction + fmiCallbackFunctions callbacks; // called by the model during simulation + ModelDescription* md; // handle to the parsed XML file + int nSteps = 0; + FILE* file; + + // instantiate the fmu + md = fmu->modelDescription; + guid = getString(md, att_guid); + callbacks.logger = fmuLogger; + callbacks.allocateMemory = calloc; + callbacks.freeMemory = free; + callbacks.stepFinished = NULL; // fmiDoStep has to be carried out synchronously + c = fmu->instantiateSlave(getModelIdentifier(md), guid, fmuLocation, mimeType, + timeout, visible, interactive, callbacks, loggingOn); + if (!c) return error("could not instantiate model"); + + // open result file + if (!(file=fopen(RESULT_FILE, "w"))) { + printf("could not write %s because:\n", RESULT_FILE); + printf(" %s\n", strerror(errno)); + return 0; // failure + } + + // StopTimeDefined=fmiFalse means: ignore value of tEnd + fmiFlag = fmu->initializeSlave(c, tStart, fmiTrue, tEnd); + if (fmiFlag > fmiWarning) return error("could not initialize model"); + + // output solution for time t0 + outputRow(fmu, c, tStart, file, separator, TRUE); // output column names + outputRow(fmu, c, tStart, file, separator, FALSE); // output values + + // enter the simulation loop + time = tStart; + while (time < tEnd) { + fmiFlag = fmu->doStep(c, time, h, fmiTrue); + if (fmiFlag != fmiOK) return error("could not complete simulation of the model"); + time += h; + outputRow(fmu, c, time, file, separator, FALSE); // output values for this step + nSteps++; + } + + // end simulation + fmiFlag = fmu->terminateSlave(c); + fmu->freeSlaveInstance(c); + + // print simulation summary + printf("Simulation from %g to %g terminated successful\n", tStart, tEnd); + printf(" steps ............ %d\n", nSteps); + printf(" fixed step size .. %g\n", h); + return 1; // success +} + +int main(int argc, char *argv[]) { + const char* fmuFileName; + + // parse command line arguments and load the FMU + double tEnd = 1.0; + double h=0.1; + int loggingOn = 0; + char csv_separator = ';'; + parseArguments(argc, argv, &fmuFileName, &tEnd, &h, &loggingOn, &csv_separator); + loadFMU(fmuFileName); + + // run the simulation + printf("FMU Simulator: run '%s' from t=0..%g with step size h=%g, loggingOn=%d, csv separator='%c'\n", + fmuFileName, tEnd, h, loggingOn, csv_separator); + simulate(&fmu, tEnd, h, loggingOn, csv_separator); + printf("CSV file '%s' written\n", RESULT_FILE); + + // release FMU + FreeLibrary(fmu.dllHandle); + freeElement(fmu.modelDescription); + return EXIT_SUCCESS; +} + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/include/fmiFunctions.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/include/fmiFunctions.h new file mode 100644 index 00000000..f4341025 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/include/fmiFunctions.h @@ -0,0 +1,231 @@ +#ifndef fmiFunctions_h +#define fmiFunctions_h + +/* This header file must be utilized when compiling a FMU. + It defines all functions of Co-Simulation Interface. + In order to have unique function names even if several FMUs + are compiled together (e.g. for embedded systems), every "real" function name + is constructed by prepending the function name by + "MODEL_IDENTIFIER" + "_" where "MODEL_IDENTIFIER" is the short name + of the model used as the name of the zip-file where the model is stored. + Therefore, the typical usage is: + + #define MODEL_IDENTIFIER MyModel + #include "fmiFunctions.h" + + As a result, a function that is defined as "fmiGetDerivatives" in this header file, + is actually getting the name "MyModel_fmiGetDerivatives". + + Revisions: + - November 4, 2010: Adapted to specification text: + o fmiGetModelTypesPlatform renamed to fmiGetTypesPlatform + o fmiInstantiateSlave: Argument GUID replaced by fmuGUID + Argument mimetype replaced by mimeType + o tabs replaced by spaces + - October 16, 2010: First public Version + + + Copyright © 2008-2010, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html): + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- +*/ + +#include "fmiPlatformTypes.h" +#include + +/* Export fmi functions on Windows */ +#ifdef _MSC_VER +#define DllExport __declspec( dllexport ) +#else +#define DllExport +#endif + +/* Macros to construct the real function name + (prepend function name by MODEL_IDENTIFIER + "_") */ + +#define fmiPaste(a,b) a ## b +#define fmiPasteB(a,b) fmiPaste(a,b) +#define fmiFullName(name) fmiPasteB(MODEL_IDENTIFIER, name) + +/*************************************************** +Common Functions +****************************************************/ +#define fmiGetTypesPlatform fmiFullName(_fmiGetTypesPlatform) +#define fmiGetVersion fmiFullName(_fmiGetVersion) +#define fmiSetDebugLogging fmiFullName(_fmiSetDebugLogging) + +/*Data Exchange*/ +#define fmiSetReal fmiFullName(_fmiSetReal) +#define fmiSetInteger fmiFullName(_fmiSetInteger) +#define fmiSetBoolean fmiFullName(_fmiSetBoolean) +#define fmiSetString fmiFullName(_fmiSetString) + +#define fmiGetReal fmiFullName(_fmiGetReal) +#define fmiGetInteger fmiFullName(_fmiGetInteger) +#define fmiGetBoolean fmiFullName(_fmiGetBoolean) +#define fmiGetString fmiFullName(_fmiGetString) + +/*************************************************** +Functions for FMI for Co-Simulation +****************************************************/ +#define fmiInstantiateSlave fmiFullName(_fmiInstantiateSlave) +#define fmiInitializeSlave fmiFullName(_fmiInitializeSlave) +#define fmiTerminateSlave fmiFullName(_fmiTerminateSlave) +#define fmiResetSlave fmiFullName(_fmiResetSlave) +#define fmiFreeSlaveInstance fmiFullName(_fmiFreeSlaveInstance) +#define fmiSetRealInputDerivatives fmiFullName(_fmiSetRealInputDerivatives) +#define fmiGetRealOutputDerivatives fmiFullName(_fmiGetRealOutputDerivatives) +#define fmiDoStep fmiFullName(_fmiDoStep) +#define fmiCancelStep fmiFullName(_fmiCancelStep) +#define fmiGetStatus fmiFullName(_fmiGetStatus) +#define fmiGetRealStatus fmiFullName(_fmiGetRealStatus) +#define fmiGetIntegerStatus fmiFullName(_fmiGetIntegerStatus) +#define fmiGetBooleanStatus fmiFullName(_fmiGetBooleanStatus) +#define fmiGetStringStatus fmiFullName(_fmiGetStringStatus) + +/* Version number */ +#define fmiVersion "1.0" + +/* make sure all compiler use the same alignment policies for structures */ +#ifdef WIN32 +#pragma pack(push,8) +#endif + + +/* Type definitions */ + typedef enum {fmiOK, + fmiWarning, + fmiDiscard, + fmiError, + fmiFatal, + fmiPending} fmiStatus; + + typedef void (*fmiCallbackLogger) (fmiComponent c, fmiString instanceName, fmiStatus status, + fmiString category, fmiString message, ...); + typedef void* (*fmiCallbackAllocateMemory)(size_t nobj, size_t size); + typedef void (*fmiCallbackFreeMemory) (void* obj); + typedef void (*fmiStepFinished) (fmiComponent c, fmiStatus status); + + typedef struct { + fmiCallbackLogger logger; + fmiCallbackAllocateMemory allocateMemory; + fmiCallbackFreeMemory freeMemory; + fmiStepFinished stepFinished; + } fmiCallbackFunctions; + + typedef struct { + fmiBoolean iterationConverged; + fmiBoolean stateValueReferencesChanged; + fmiBoolean stateValuesChanged; + fmiBoolean terminateSimulation; + fmiBoolean upcomingTimeEvent; + fmiReal nextEventTime; + } fmiEventInfo; + +/* reset alignment policy to the one set before reading this file */ +#ifdef WIN32 +#pragma pack(pop) +#endif + +/*************************************************** +Common Functions +****************************************************/ + +/* Inquire version numbers of header files */ + DllExport const char* fmiGetTypesPlatform(); + DllExport const char* fmiGetVersion(); + + DllExport fmiStatus fmiSetDebugLogging (fmiComponent c, fmiBoolean loggingOn); + +/* Data Exchange Functions*/ + DllExport fmiStatus fmiGetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); + DllExport fmiStatus fmiGetInteger(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); + DllExport fmiStatus fmiGetBoolean(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); + DllExport fmiStatus fmiGetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); + + DllExport fmiStatus fmiSetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); + DllExport fmiStatus fmiSetInteger (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); + DllExport fmiStatus fmiSetBoolean (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); + DllExport fmiStatus fmiSetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); + +/*************************************************** +Functions for FMI for Co-Simulation +****************************************************/ + +/* Creation and destruction of slave instances and setting debug status */ + DllExport fmiComponent fmiInstantiateSlave(fmiString instanceName, + fmiString fmuGUID, + fmiString fmuLocation, + fmiString mimeType, + fmiReal timeout, + fmiBoolean visible, + fmiBoolean interactive, + fmiCallbackFunctions functions, + fmiBoolean loggingOn); + + DllExport fmiStatus fmiInitializeSlave(fmiComponent c, + fmiReal tStart, + fmiBoolean StopTimeDefined, + fmiReal tStop); + + DllExport fmiStatus fmiTerminateSlave (fmiComponent c); + DllExport fmiStatus fmiResetSlave (fmiComponent c); + DllExport void fmiFreeSlaveInstance(fmiComponent c); + + DllExport fmiStatus fmiSetRealInputDerivatives(fmiComponent c, + const fmiValueReference vr[], + size_t nvr, + const fmiInteger order[], + const fmiReal value[]); + + DllExport fmiStatus fmiGetRealOutputDerivatives(fmiComponent c, + const fmiValueReference vr[], + size_t nvr, + const fmiInteger order[], + fmiReal value[]); + + DllExport fmiStatus fmiCancelStep(fmiComponent c); + DllExport fmiStatus fmiDoStep (fmiComponent c, + fmiReal currentCommunicationPoint, + fmiReal communicationStepSize, + fmiBoolean newStep); + + + typedef enum {fmiDoStepStatus, + fmiPendingStatus, + fmiLastSuccessfulTime} fmiStatusKind; + + DllExport fmiStatus fmiGetStatus (fmiComponent c, const fmiStatusKind s, fmiStatus* value); + DllExport fmiStatus fmiGetRealStatus (fmiComponent c, const fmiStatusKind s, fmiReal* value); + DllExport fmiStatus fmiGetIntegerStatus(fmiComponent c, const fmiStatusKind s, fmiInteger* value); + DllExport fmiStatus fmiGetBooleanStatus(fmiComponent c, const fmiStatusKind s, fmiBoolean* value); + DllExport fmiStatus fmiGetStringStatus (fmiComponent c, const fmiStatusKind s, fmiString* value); + + +#endif // fmiFunctions_h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/include/fmiPlatformTypes.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/include/fmiPlatformTypes.h new file mode 100644 index 00000000..7916f792 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/co_simulation/include/fmiPlatformTypes.h @@ -0,0 +1,73 @@ +#ifndef fmiPlatformTypes_h +#define fmiPlatformTypes_h + +/* Standard header file to define the argument types of the + functions of the Model Execution Interface. + This header file must be utilized both by the model and + by the simulation engine. + + Revisions: + - October 2010: First public Version + + + Copyright © 2008-2010, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html): + + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- +*/ + +/* Platform (combination of machine, compiler, operating system) */ +#define fmiPlatform "standard32" + +/* Type definitions of variables passed as arguments + Version "standard32" means: + + fmiComponent : 32 bit pointer + fmiValueReference: 32 bit + fmiReal : 64 bit + fmiInteger : 32 bit + fmiBoolean : 8 bit + fmiString : 32 bit pointer + +*/ + typedef void* fmiComponent; + typedef unsigned int fmiValueReference; + typedef double fmiReal ; + typedef int fmiInteger; + typedef char fmiBoolean; + typedef const char* fmiString ; + +/* Values for fmiBoolean */ +#define fmiTrue 1 +#define fmiFalse 0 + +/* Undefined value for fmiValueReference (largest unsigned int value) */ +#define fmiUndefinedValueReference (fmiValueReference)(-1) + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/fmusim_me/fmi_me.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/fmusim_me/fmi_me.h new file mode 100644 index 00000000..f1152455 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/fmusim_me/fmi_me.h @@ -0,0 +1,89 @@ +/* ------------------------------------------------------------------------- + * fmi_me.h + * Function types for all function of the "FMI for Model Exchange 1.0" + * and a struct with the corresponding function pointers. + * Copyright 2011 QTronic GmbH. All rights reserved. + * ------------------------------------------------------------------------- + */ + +#ifndef FMI_ME_H +#define FMI_ME_H + +#include +#include "fmiModelFunctions.h" +#include "xml_parser.h" + +typedef const char* (*fGetModelTypesPlatform)(); +typedef const char* (*fGetVersion)(); +typedef fmiComponent (*fInstantiateModel)(fmiString instanceName, fmiString GUID, + fmiCallbackFunctions functions, fmiBoolean loggingOn); +typedef void (*fFreeModelInstance) (fmiComponent c); +typedef fmiStatus (*fSetDebugLogging) (fmiComponent c, fmiBoolean loggingOn); +typedef fmiStatus (*fSetTime) (fmiComponent c, fmiReal time); +typedef fmiStatus (*fSetContinuousStates)(fmiComponent c, const fmiReal x[], size_t nx); +typedef fmiStatus (*fCompletedIntegratorStep)(fmiComponent c, fmiBoolean* callEventUpdate); +typedef fmiStatus (*fSetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); +typedef fmiStatus (*fSetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); +typedef fmiStatus (*fSetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); +typedef fmiStatus (*fSetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); +typedef fmiStatus (*fInitialize)(fmiComponent c, fmiBoolean toleranceControlled, + fmiReal relativeTolerance, fmiEventInfo* eventInfo); +typedef fmiStatus (*fGetDerivatives) (fmiComponent c, fmiReal derivatives[] , size_t nx); +typedef fmiStatus (*fGetEventIndicators)(fmiComponent c, fmiReal eventIndicators[], size_t ni); +typedef fmiStatus (*fGetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); +typedef fmiStatus (*fGetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); +typedef fmiStatus (*fGetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); +typedef fmiStatus (*fGetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); +typedef fmiStatus (*fEventUpdate) (fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo); +typedef fmiStatus (*fGetContinuousStates) (fmiComponent c, fmiReal states[], size_t nx); +typedef fmiStatus (*fGetNominalContinuousStates)(fmiComponent c, fmiReal x_nominal[], size_t nx); +typedef fmiStatus (*fGetStateValueReferences) (fmiComponent c, fmiValueReference vrx[], size_t nx); +typedef fmiStatus (*fTerminate) (fmiComponent c); + +typedef struct { + ModelDescription* modelDescription; + HANDLE dllHandle; + fGetModelTypesPlatform getModelTypesPlatform; + fGetVersion getVersion; + fInstantiateModel instantiateModel; + fFreeModelInstance freeModelInstance; + fSetDebugLogging setDebugLogging; + fSetTime setTime; + fSetContinuousStates setContinuousStates; + fCompletedIntegratorStep completedIntegratorStep; + fSetReal setReal; + fSetInteger setInteger; + fSetBoolean setBoolean; + fSetString setString; + fInitialize initialize; + fGetDerivatives getDerivatives; + fGetEventIndicators getEventIndicators; + fGetReal getReal; + fGetInteger getInteger; + fGetBoolean getBoolean; + fGetString getString; + fEventUpdate eventUpdate; + fGetContinuousStates getContinuousStates; + fGetNominalContinuousStates getNominalContinuousStates; + fGetStateValueReferences getStateValueReferences; + fTerminate terminate; +/* + fInstantiateSlave instantiateSlave; + fInitializeSlave initializeSlave; + fTerminateSlave terminateSlave; + fResetSlave resetSlave; + fFreeSlaveInstance freeSlaveInstance; + fGetRealOutputDerivatives getRealOutputDerivatives; + fSetRealInputDerivatives setRealInputDerivatives; + fDoStep doStep; + fCancelStep cancelStep; + fGetStatus getStatus; + fGetRealStatus getRealStatus; + fGetIntegerStatus getIntegerStatus; + fGetBooleanStatus getBooleanStatus; + fGetStringStatus getStringStatus; +*/ +} FMU; + +#endif // FMI_ME_H + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/fmusim_me/main.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/fmusim_me/main.c new file mode 100644 index 00000000..d911fa90 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/fmusim_me/main.c @@ -0,0 +1,233 @@ +/* ------------------------------------------------------------------------- + * main.c + * Implements simulation of a single FMU instance using the forward Euler + * method for numerical integration. + * Command syntax: see printHelp() + * Simulates the given FMU from t = 0 .. tEnd with fixed step size h and + * writes the computed solution to file 'result.csv'. + * The CSV file (comma-separated values) may e.g. be plotted using + * OpenOffice Calc or Microsoft Excel. + * This progamm demonstrates basic use of an FMU. + * Real applications may use advanced numerical solvers instead, means to + * exactly locate state events in time, graphical plotting utilities, support + * for coexecution of many FMUs, stepping and debug support, user control + * of parameter and start values etc. + * All this is missing here. + * + * Revision history + * 07.02.2010 initial version released in FMU SDK 1.0 + * 05.03.2010 bug fix: removed strerror(GetLastError()) from error messages + * 11.06.2010 bug fix: replaced win32 API call to OpenFile in getFmuPath + * which restricted path length to FMU to 128 chars. New limit is MAX_PATH. + * 15.07.2010 fixed wrong label in xml parser: deault instead of default + * 13.12.2010 added check for undefined 'declared type' to xml parser + * 31.07.2011 bug fix: added missing freeModelInstance(c) + * 31.07.2011 bug fix: added missing terminate(c) + * + * Free libraries and tools used to implement this simulator: + * - header files from the FMU specification + * - eXpat 2.0.1 XML parser, see http://expat.sourceforge.net + * - 7z.exe 4.57 zip and unzip tool, see http://www.7-zip.org + * Author: Jakob Mauss + * Copyright 2011 QTronic GmbH. All rights reserved. + * ------------------------------------------------------------------------- + */ + +#include +#include +#include "fmi_me.h" +#include "sim_support.h" + +FMU fmu; // the fmu to simulate + +// simulate the given FMU using the forward euler method. +// time events are processed by reducing step size to exactly hit tNext. +// state events are checked and fired only at the end of an Euler step. +// the simulator may therefore miss state events and fires state events typically too late. +static int simulate(FMU* fmu, double tEnd, double h, fmiBoolean loggingOn, char separator) { + int i, n; + double dt, tPre; + fmiBoolean timeEvent, stateEvent, stepEvent; + double time; + int nx; // number of state variables + int nz; // number of state event indicators + double *x; // continuous states + double *xdot; // the crresponding derivatives in same order + double *z = NULL; // state event indicators + double *prez = NULL; // previous values of state event indicators + fmiEventInfo eventInfo; // updated by calls to initialize and eventUpdate + ModelDescription* md; // handle to the parsed XML file + const char* guid; // global unique id of the fmu + fmiCallbackFunctions callbacks; // called by the model during simulation + fmiComponent c; // instance of the fmu + fmiStatus fmiFlag; // return code of the fmu functions + fmiReal t0 = 0; // start time + fmiBoolean toleranceControlled = fmiFalse; + int nSteps = 0; + int nTimeEvents = 0; + int nStepEvents = 0; + int nStateEvents = 0; + FILE* file; + + // instantiate the fmu + md = fmu->modelDescription; + guid = getString(md, att_guid); + callbacks.logger = fmuLogger; + callbacks.allocateMemory = calloc; + callbacks.freeMemory = free; + c = fmu->instantiateModel(getModelIdentifier(md), guid, callbacks, loggingOn); + if (!c) return error("could not instantiate model"); + + // allocate memory + nx = getNumberOfStates(md); + nz = getNumberOfEventIndicators(md); + x = (double *) calloc(nx, sizeof(double)); + xdot = (double *) calloc(nx, sizeof(double)); + if (nz>0) { + z = (double *) calloc(nz, sizeof(double)); + prez = (double *) calloc(nz, sizeof(double)); + } + if (!x || !xdot || nz>0 && (!z || !prez)) return error("out of memory"); + + // open result file + if (!(file=fopen(RESULT_FILE, "w"))) { + printf("could not write %s because:\n", RESULT_FILE); + printf(" %s\n", strerror(errno)); + return 0; // failure + } + + // set the start time and initialize + time = t0; + fmiFlag = fmu->setTime(c, t0); + if (fmiFlag > fmiWarning) return error("could not set time"); + fmiFlag = fmu->initialize(c, toleranceControlled, t0, &eventInfo); + if (fmiFlag > fmiWarning) return error("could not initialize model"); + if (eventInfo.terminateSimulation) { + printf("model requested termination at init"); + tEnd = time; + } + + // output solution for time t0 + outputRow(fmu, c, t0, file, separator, TRUE); // output column names + outputRow(fmu, c, t0, file, separator, FALSE); // output values + + // enter the simulation loop + while (time < tEnd) { + // get current state and derivatives + fmiFlag = fmu->getContinuousStates(c, x, nx); + if (fmiFlag > fmiWarning) return error("could not retrieve states"); + fmiFlag = fmu->getDerivatives(c, xdot, nx); + if (fmiFlag > fmiWarning) return error("could not retrieve derivatives"); + + // advance time + tPre = time; + time = min(time+h, tEnd); + timeEvent = eventInfo.upcomingTimeEvent && eventInfo.nextEventTime < time; + if (timeEvent) time = eventInfo.nextEventTime; + dt = time - tPre; + fmiFlag = fmu->setTime(c, time); + if (fmiFlag > fmiWarning) error("could not set time"); + + // perform one step + for (i=0; isetContinuousStates(c, x, nx); + if (fmiFlag > fmiWarning) return error("could not set states"); + if (loggingOn) printf("Step %d to t=%.16g\n", nSteps, time); + + // Check for step event, e.g. dynamic state selection + fmiFlag = fmu->completedIntegratorStep(c, &stepEvent); + if (fmiFlag > fmiWarning) return error("could not complete intgrator step"); + + // Check for state event + for (i=0; igetEventIndicators(c, z, nz); + if (fmiFlag > fmiWarning) return error("could not retrieve event indicators"); + stateEvent = FALSE; + for (i=0; i0 && z[i]<0) ? "-\\-" : "-/-", i, time); + } + if (stepEvent) { + nStepEvents++; + if (loggingOn) printf("step event at t=%.16g\n", time); + } + + // event iteration in one step, ignoring intermediate results + fmiFlag = fmu->eventUpdate(c, fmiFalse, &eventInfo); + if (fmiFlag > fmiWarning) return error("could not perform event update"); + + // terminate simulation, if requested by the model + if (eventInfo.terminateSimulation) { + printf("model requested termination at t=%.16g\n", time); + break; // success + } + + // check for change of value of states + if (eventInfo.stateValuesChanged && loggingOn) { + printf("state values changed at t=%.16g\n", time); + } + + // check for selection of new state variables + if (eventInfo.stateValueReferencesChanged && loggingOn) { + printf("new state variables selected at t=%.16g\n", time); + } + + } // if event + outputRow(fmu, c, time, file, separator, FALSE); // output values for this step + nSteps++; + } // while + + // cleanup + if(! eventInfo.terminateSimulation) fmu->terminate(c); + fmu->freeModelInstance(c); + fclose(file); + if (x!=NULL) free(x); + if (xdot!= NULL) free(xdot); + if (z!= NULL) free(z); + if (prez!= NULL) free(prez); + + // print simulation summary + printf("Simulation from %g to %g terminated successful\n", t0, tEnd); + printf(" steps ............ %d\n", nSteps); + printf(" fixed step size .. %g\n", h); + printf(" time events ...... %d\n", nTimeEvents); + printf(" state events ..... %d\n", nStateEvents); + printf(" step events ...... %d\n", nStepEvents); + + return 1; // success +} + +int main(int argc, char *argv[]) { + const char* fmuFileName; + + // parse command line arguments and load the FMU + double tEnd = 1.0; + double h=0.1; + int loggingOn = 0; + char csv_separator = ';'; + parseArguments(argc, argv, &fmuFileName, &tEnd, &h, &loggingOn, &csv_separator); + loadFMU(fmuFileName); + + // run the simulation + printf("FMU Simulator: run '%s' from t=0..%g with step size h=%g, loggingOn=%d, csv separator='%c'\n", + fmuFileName, tEnd, h, loggingOn, csv_separator); + simulate(&fmu, tEnd, h, loggingOn, csv_separator); + printf("CSV file '%s' written\n", RESULT_FILE); + + // release FMU + FreeLibrary(fmu.dllHandle); + freeElement(fmu.modelDescription); + return EXIT_SUCCESS; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/include/fmiModelFunctions.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/include/fmiModelFunctions.h new file mode 100644 index 00000000..e2047724 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/include/fmiModelFunctions.h @@ -0,0 +1,210 @@ +#ifndef fmiModelFunctions_h +#define fmiModelFunctions_h + +/* This header file must be utilized when compiling a model. + It defines all functions of the Model Execution Interface. + In order to have unique function names even if several models + are compiled together (e.g. for embedded systems), every "real" function name + is constructed by prepending the function name by + "MODEL_IDENTIFIER" + "_" where "MODEL_IDENTIFIER" is the short name + of the model used as the name of the zip-file where the model is stored. + Therefore, the typical usage is: + + #define MODEL_IDENTIFIER MyModel + #include "fmiModelFunctions.h" + + As a result, a function that is defined as "fmiGetDerivatives" in this header file, + is actually getting the name "MyModel_fmiGetDerivatives". + + Revisions: + - Jan. 20, 2010: stateValueReferencesChanged added to struct fmiEventInfo (ticket #27) + (by M. Otter, DLR) + Added WIN32 pragma to define the struct layout (ticket #34) + (by J. Mauss, QTronic) + - Jan. 4, 2010: Removed argument intermediateResults from fmiInitialize + Renamed macro fmiGetModelFunctionsVersion to fmiGetVersion + Renamed macro fmiModelFunctionsVersion to fmiVersion + Replaced fmiModel by fmiComponent in decl of fmiInstantiateModel + (by J. Mauss, QTronic) + - Dec. 17, 2009: Changed extension "me" to "fmi" (by Martin Otter, DLR). + - Dez. 14, 2009: Added eventInfo to meInitialize and added + meGetNominalContinuousStates (by Martin Otter, DLR) + - Sept. 9, 2009: Added DllExport (according to Peter Nilsson's suggestion) + (by A. Junghanns, QTronic) + - Sept. 9, 2009: Changes according to FMI-meeting on July 21: + meInquireModelTypesVersion -> meGetModelTypesPlatform + meInquireModelFunctionsVersion -> meGetModelFunctionsVersion + meSetStates -> meSetContinuousStates + meGetStates -> meGetContinuousStates + removal of meInitializeModelClass + removal of meGetTime + change of arguments of meInstantiateModel + change of arguments of meCompletedIntegratorStep + (by Martin Otter, DLR): + - July 19, 2009: Added "me" as prefix to file names (by Martin Otter, DLR). + - March 2, 2009: Changed function definitions according to the last design + meeting with additional improvements (by Martin Otter, DLR). + - Dec. 3 , 2008: First version by Martin Otter (DLR) and Hans Olsson (Dynasim). + + + Copyright © 2008-2009, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html): + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- + + with the extension: + + You may distribute or publicly perform any modification only under the + terms of this license. +*/ + +#include "fmiModelTypes.h" +#include + +/* Export fmi functions on Windows */ +#ifdef _MSC_VER +#define DllExport __declspec( dllexport ) +#else +#define DllExport +#endif + +/* Macros to construct the real function name + (prepend function name by MODEL_IDENTIFIER + "_") */ + +#define fmiPaste(a,b) a ## b +#define fmiPasteB(a,b) fmiPaste(a,b) +#define fmiFullName(name) fmiPasteB(MODEL_IDENTIFIER, name) + +#define fmiGetModelTypesPlatform fmiFullName(_fmiGetModelTypesPlatform) +#define fmiGetVersion fmiFullName(_fmiGetVersion) +#define fmiInstantiateModel fmiFullName(_fmiInstantiateModel) +#define fmiFreeModelInstance fmiFullName(_fmiFreeModelInstance) +#define fmiSetDebugLogging fmiFullName(_fmiSetDebugLogging) +#define fmiSetTime fmiFullName(_fmiSetTime) +#define fmiSetContinuousStates fmiFullName(_fmiSetContinuousStates) +#define fmiCompletedIntegratorStep fmiFullName(_fmiCompletedIntegratorStep) +#define fmiSetReal fmiFullName(_fmiSetReal) +#define fmiSetInteger fmiFullName(_fmiSetInteger) +#define fmiSetBoolean fmiFullName(_fmiSetBoolean) +#define fmiSetString fmiFullName(_fmiSetString) +#define fmiInitialize fmiFullName(_fmiInitialize) +#define fmiGetDerivatives fmiFullName(_fmiGetDerivatives) +#define fmiGetEventIndicators fmiFullName(_fmiGetEventIndicators) +#define fmiGetReal fmiFullName(_fmiGetReal) +#define fmiGetInteger fmiFullName(_fmiGetInteger) +#define fmiGetBoolean fmiFullName(_fmiGetBoolean) +#define fmiGetString fmiFullName(_fmiGetString) +#define fmiEventUpdate fmiFullName(_fmiEventUpdate) +#define fmiGetContinuousStates fmiFullName(_fmiGetContinuousStates) +#define fmiGetNominalContinuousStates fmiFullName(_fmiGetNominalContinuousStates) +#define fmiGetStateValueReferences fmiFullName(_fmiGetStateValueReferences) +#define fmiTerminate fmiFullName(_fmiTerminate) + + +/* Version number */ +#define fmiVersion "1.0" + +/* Inquire version numbers of header files */ + DllExport const char* fmiGetModelTypesPlatform(); + DllExport const char* fmiGetVersion(); + +/* make sure all compiler use the same alignment policies for structures */ +#ifdef WIN32 +#pragma pack(push,8) +#endif + +/* Type definitions */ + typedef enum {fmiOK, + fmiWarning, + fmiDiscard, + fmiError, + fmiFatal} fmiStatus; + + typedef void (*fmiCallbackLogger) (fmiComponent c, fmiString instanceName, fmiStatus status, + fmiString category, fmiString message, ...); + typedef void* (*fmiCallbackAllocateMemory)(size_t nobj, size_t size); + typedef void (*fmiCallbackFreeMemory) (void* obj); + + typedef struct { + fmiCallbackLogger logger; + fmiCallbackAllocateMemory allocateMemory; + fmiCallbackFreeMemory freeMemory; + } fmiCallbackFunctions; + + typedef struct { + fmiBoolean iterationConverged; + fmiBoolean stateValueReferencesChanged; + fmiBoolean stateValuesChanged; + fmiBoolean terminateSimulation; + fmiBoolean upcomingTimeEvent; + fmiReal nextEventTime; + } fmiEventInfo; + +/* reset alignment policy to the one set before reading this file */ +#ifdef WIN32 +#pragma pack(pop) +#endif + +/* Creation and destruction of model instances and setting debug status */ + DllExport fmiComponent fmiInstantiateModel (fmiString instanceName, + fmiString GUID, + fmiCallbackFunctions functions, + fmiBoolean loggingOn); + DllExport void fmiFreeModelInstance(fmiComponent c); + DllExport fmiStatus fmiSetDebugLogging (fmiComponent c, fmiBoolean loggingOn); + + +/* Providing independent variables and re-initialization of caching */ + DllExport fmiStatus fmiSetTime (fmiComponent c, fmiReal time); + DllExport fmiStatus fmiSetContinuousStates (fmiComponent c, const fmiReal x[], size_t nx); + DllExport fmiStatus fmiCompletedIntegratorStep(fmiComponent c, fmiBoolean* callEventUpdate); + DllExport fmiStatus fmiSetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); + DllExport fmiStatus fmiSetInteger (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); + DllExport fmiStatus fmiSetBoolean (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); + DllExport fmiStatus fmiSetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); + + +/* Evaluation of the model equations */ + DllExport fmiStatus fmiInitialize(fmiComponent c, fmiBoolean toleranceControlled, + fmiReal relativeTolerance, fmiEventInfo* eventInfo); + + DllExport fmiStatus fmiGetDerivatives (fmiComponent c, fmiReal derivatives[] , size_t nx); + DllExport fmiStatus fmiGetEventIndicators(fmiComponent c, fmiReal eventIndicators[], size_t ni); + + DllExport fmiStatus fmiGetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); + DllExport fmiStatus fmiGetInteger(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); + DllExport fmiStatus fmiGetBoolean(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); + DllExport fmiStatus fmiGetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); + + DllExport fmiStatus fmiEventUpdate (fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo); + DllExport fmiStatus fmiGetContinuousStates (fmiComponent c, fmiReal states[], size_t nx); + DllExport fmiStatus fmiGetNominalContinuousStates(fmiComponent c, fmiReal x_nominal[], size_t nx); + DllExport fmiStatus fmiGetStateValueReferences (fmiComponent c, fmiValueReference vrx[], size_t nx); + DllExport fmiStatus fmiTerminate (fmiComponent c); + +#endif // fmiModelFunctions_h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/include/fmiModelTypes.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/include/fmiModelTypes.h new file mode 100644 index 00000000..17e9e300 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/model_exchange/include/fmiModelTypes.h @@ -0,0 +1,91 @@ +#ifndef fmiModelTypes_h +#define fmiModelTypes_h + +/* Standard header file to define the argument types of the + functions of the Model Execution Interface. + This header file must be utilized both by the model and + by the simulation engine. + + Revisions: + - Jan. 4, 2010: Renamed meModelTypes_h to fmiModelTypes_h (by Mauss, QTronic) + - Dec. 21, 2009: Changed "me" to "fmi" and "meModel" to "fmiComponent" + according to meeting on Dec. 18 (by Martin Otter, DLR) + - Dec. 6, 2009: Added meUndefinedValueReference (by Martin Otter, DLR) + - Sept. 9, 2009: Changes according to FMI-meeting on July 21: + Changed "version" to "platform", "standard" to "standard32", + Added a precise definition of "standard32" as comment + (by Martin Otter, DLR) + - July 19, 2009: Added "me" as prefix to file names, added meTrue/meFalse, + and changed meValueReferenced from int to unsigned int + (by Martin Otter, DLR). + - March 2, 2009: Moved enums and function pointer definitions to + ModelFunctions.h (by Martin Otter, DLR). + - Dec. 3, 2008 : First version by Martin Otter (DLR) and + Hans Olsson (Dynasim). + + + Copyright © 2008-2010, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html) + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- + + with the extension: + + You may distribute or publicly perform any modification only under the + terms of this license. +*/ + +/* Platform (combination of machine, compiler, operating system) */ +#define fmiModelTypesPlatform "standard32" + +/* Type definitions of variables passed as arguments + Version "standard32" means: + + fmiComponent : 32 bit pointer + fmiValueReference: 32 bit + fmiReal : 64 bit + fmiInteger : 32 bit + fmiBoolean : 8 bit + fmiString : 32 bit pointer + +*/ + typedef void* fmiComponent; + typedef unsigned int fmiValueReference; + typedef double fmiReal ; + typedef int fmiInteger; + typedef char fmiBoolean; + typedef const char* fmiString ; + +/* Values for fmiBoolean */ +#define fmiTrue 1 +#define fmiFalse 0 + +/* Undefined value for fmiValueReference (largest unsigned int value) */ +#define fmiUndefinedValueReference (fmiValueReference)(-1) + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/_main.html new file mode 100644 index 00000000..fff15c6a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/_main.html @@ -0,0 +1,52 @@ + + + Documentation for bouncingBall.fmu + + + +

bouncingBall.fmu

+The bouncingBall implements the following equation: +
    +
  • der(h) = v; +
  • der(v) = -g; +
  • when h<0 then v := -e* v +
+with start values h=1, e=0.7, g = 9.81 and +
    +
  • h: height [m], used as state +
  • v: velocity of ball [m/s], used as state +
  • der(h): velocity of ball [m/s] +
  • der(v): acceleration of ball [m/s2] +
  • g: acceleration of gravity [m/s2], a parameter +
  • e: a dimensionless parameter +
+ +
+ +
+The figure shows the solution computed with Silver +for height h of the ball for the start values given above. + +

+The chain of events during simulation is as follows +

    +
  1. intitially h>0 and pos(0)=true
  2. +
  3. continuous integration until a state event is detected, i.e. + until h + EPS_INDICATORS = 0. + At this time h < 0, the EPS_INDICATORS adds hysteresis.
  4. +
  5. the simulator calls eventUpdate once which reverses the speed direction + v of the ball: v = -e * v, and sets pos(0)=false
  6. +
  7. continuous integration until state event is detected, i.e. + until h - EPS_INDICATORS = 0. + At this time h > 0, the EPS_INDICATORS adds hysteresis.
  8. +
  9. the simulator calls eventUpdate once more which sets pos(0)=true.
  10. +
  11. goto 2
  12. +
+The above description refers to the variables used +in file bouncingBall.c. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/bouncingBall.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/bouncingBall.c new file mode 100644 index 00000000..7f6c3037 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/bouncingBall.c @@ -0,0 +1,103 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU - a bouncing ball. + * This demonstrates the use of state events and reinit of states. + * Equations: + * der(h) = v; + * der(v) = -g; + * when h<0 then v := -e * v; + * where + * h height [m], used as state, start = 1 + * v velocity of ball [m/s], used as state + * der(h) velocity of ball [m/s] + * der(v) acceleration of ball [m/s2] + * g acceleration of gravity [m/s2], a parameter, start = 9.81 + * e a dimensionless parameter, start = 0.7 + * + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER bouncingBall +#define MODEL_GUID "{8c4e810f-3df3-4a00-8276-176fa3c9f003}" + +// define model size +#define NUMBER_OF_REALS 5 +#define NUMBER_OF_INTEGERS 0 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_STATES 2 +#define NUMBER_OF_EVENT_INDICATORS 1 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define h_ 0 +#define der_h_ 1 +#define v_ 2 +#define der_v_ 3 +#define g_ 3 // negated alias +#define e_ 4 + +// define initial state vector as vector of value references +#define STATES { h_, v_ } + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + r(h_) = 1; + r(v_) = 0; + r(der_v_) = -9.81; + r(e_) = 0.7; + pos(0) = r(h_) > 0; +} + +// called by fmiGetReal, fmiGetContinuousStates and fmiGetDerivatives +fmiReal getReal(ModelInstance* comp, fmiValueReference vr){ + switch (vr) { + case h_ : return r(h_); + case der_h_ : return r(v_); + case v_ : return r(v_); + case der_v_ : return r(der_v_); + case e_ : return r(e_); + default: return 0; + } +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +// offset for event indicator, adds hysteresis and prevents z=0 at restart +#define EPS_INDICATORS 1e-14 + +fmiReal getEventIndicator(ModelInstance* comp, int z) { + switch (z) { + case 0 : return r(h_) + (pos(0) ? EPS_INDICATORS : -EPS_INDICATORS); + default: return 0; + } +} + +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { + if (pos(0)) { + r(v_) = - r(e_) * r(v_); + } + pos(0) = r(h_) > 0; + eventInfo->iterationConverged = fmiTrue; + eventInfo->stateValueReferencesChanged = fmiFalse; + eventInfo->stateValuesChanged = fmiTrue; + eventInfo->terminateSimulation = fmiFalse; + eventInfo->upcomingTimeEvent = fmiFalse; + } + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/modelDescription.xml new file mode 100644 index 00000000..4cb345e7 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/modelDescription.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/plot_h.PNG b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/plot_h.PNG new file mode 100644 index 00000000..ced85c46 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/bouncingBall/plot_h.PNG differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/build_fmu.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/build_fmu.bat new file mode 100644 index 00000000..9d014581 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/build_fmu.bat @@ -0,0 +1,80 @@ +@echo off +rem ------------------------------------------------------------ +rem This batch builds an FMU of the FMU SDK +rem Usage: build_fmu (me|cs) +rem (c) 2011 QTronic GmbH +rem ------------------------------------------------------------ + +echo ----------------------------------------------------------- +if %1==cs (^ +echo building FMU %2 - FMI for Co-Simulation 1.0) else ^ +echo building FMU %2 - FMI for Model Exchange 1.0 + +rem save env variable settings +set PREV_PATH=%PATH% +if defined INCLUDE set PREV_INCLUDE=%INLUDE% +if defined LIB set PREV_LIB=%LIB% +if defined LIBPATH set PREV_LIBPATH=%LIBPATH% + +rem setup the compiler +if defined VS90COMNTOOLS (call "%VS90COMNTOOLS%\vsvars32.bat") else ^ +if defined VS80COMNTOOLS (call "%VS80COMNTOOLS%\vsvars32.bat") else ^ +goto noCompiler + +rem create the %2.dll in the temp dir +if not exist temp mkdir temp +pushd temp +if exist *.dll del /Q *.dll + +rem /wd4090 disables warnings about different 'const' qualifiers +if %1==cs (set FMI_DIR=co_simulation) else set FMI_DIR=model_exchange +if %1==cs (set DEF=/DFMI_COSIMULATION) else set DEF= +cl /LD /wd4090 /nologo %DEF% ..\%2\%2.c /I ..\. /I ..\..\%FMI_DIR%\include +if not exist %2.dll goto compileError + +rem create FMU dir structure with root 'fmu' +set BIN_DIR=fmu\binaries\win32 +set SRC_DIR=fmu\sources +set DOC_DIR=fmu\documentation +if not exist %BIN_DIR% mkdir %BIN_DIR% +if not exist %SRC_DIR% mkdir %SRC_DIR% +if not exist %DOC_DIR% mkdir %DOC_DIR% +move /Y %2.dll %BIN_DIR% +if exist ..\%2\*~ del /Q ..\%2\*~ +copy ..\%2\%2.c %SRC_DIR% +type ..\%2\modelDescription.xml ..\%1.xml > fmu\modelDescription.xml +copy ..\%2\model.png fmu +copy ..\fmuTemplate.c %SRC_DIR% +copy ..\fmuTemplate.h %SRC_DIR% +copy ..\%2\*.html %DOC_DIR% +copy ..\%2\*.png %DOC_DIR% +del %DOC_DIR%\model.png + +rem zip the directory tree and move to fmu directory +cd fmu +set FMU_FILE=..\..\..\..\fmu\%1\%2.fmu +if exist %ZIP_FILE% del %FMU_FILE% +..\..\..\..\bin\7z.exe a -tzip -xr!.svn %FMU_FILE% ^ + modelDescription.xml model.png binaries sources documentation +goto cleanup + +:noCompiler +echo No Microsoft Visual C compiler found +exit + +:compileError +echo build of %2 failed + +:cleanup +popd +if exist temp rmdir /S /Q temp + +rem undo variable settings performed by vsvars32.bat +set PATH=%PREV_PATH% +if defined PREV_INCLUDE set INCLUDE=%PREV_INLUDE% +if defined PREV_LIB set LIB=%PREV_LIB% +if defined PREV_LIBPATH set LIBPATH=%PREV_LIBPATH% +echo done. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/cs.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/cs.xml new file mode 100644 index 00000000..9e38bc40 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/cs.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/_main.html new file mode 100644 index 00000000..f981d0fe --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/_main.html @@ -0,0 +1,29 @@ + + +Documentation for dq.fmu + + + +

dq.fmu

+This FMU implements the equation +
    +
  • der(x) = -k * x
  • +
+The analytical solution of this system is +
    +
  • x(t) = exp(-k*t)
  • +
+The above equation is also known as +Dahlquist +test equation. +
+ +
+The figure shows the solution for x computed with Silver +for start values k = 1 and x = 1. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/dq.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/dq.c new file mode 100644 index 00000000..bb8df472 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/dq.c @@ -0,0 +1,67 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU - the Dahlquist test equation. + * + * der(x) = - k * x and x(0) = 1. + * Analytical solution: x(t) = exp(-k*t). + * + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER dq +#define MODEL_GUID "{8c4e810f-3df3-4a00-8276-176fa3c9f000}" + +// define model size +#define NUMBER_OF_REALS 3 +#define NUMBER_OF_INTEGERS 0 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_STATES 1 +#define NUMBER_OF_EVENT_INDICATORS 0 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define x_ 0 +#define der_x_ 1 +#define k_ 2 + +// define state vector as vector of value references +#define STATES { x_ } + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + r(x_) = 1; + r(k_) = 1; +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +// called by fmiGetReal, fmiGetContinuousStates and fmiGetDerivatives +fmiReal getReal(ModelInstance* comp, fmiValueReference vr){ + switch (vr) { + case x_ : return r(x_); + case der_x_ : return - r(k_) * r(x_); + case k_ : return r(k_); + default: return 0; + } +} + +// Used to set the next time event, if any. +void eventUpdate(fmiComponent comp, fmiEventInfo* eventInfo) { +} + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/modelDescription.xml new file mode 100644 index 00000000..daf9fbf0 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/modelDescription.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/plot_x.PNG b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/plot_x.PNG new file mode 100644 index 00000000..b28fa66c Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/dq/plot_x.PNG differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/fmuTemplate.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/fmuTemplate.c new file mode 100644 index 00000000..e64b47e3 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/fmuTemplate.c @@ -0,0 +1,765 @@ +/* ---------------------------------------------------------------------------* + * Implementation of the FMI interface based on functions and macros to + * be defined by the includer of this file. + * If FMI_COSIMULATION is defined, this implements "FMI for Co-Simulation 1.0", + * otherwise "FMI for Model Exchange 1.0". + * The "FMI for Co-Simulation 1.0", implementation assumes that exactly the + * following capability flags are set to fmiTrue: + * canHandleVariableCommunicationStepSize, i.e. fmiDoStep step size can vary + * canHandleEvents, i.e. fmiDoStep step size can be zero + * and all other capability flags are set to default, i.e. to fmiFalse or 0. + * + * Revision history + * 07.02.2010 initial version for "Model Exchange 1.0" released in FMU SDK 1.0 + * 05.03.2010 bug fix: fmiSetString now copies the passed string argument + * and fmiFreeModelInstance frees all string copies + * 11.12.2010 replaced calloc by functions.allocateMemory in fmiInstantiateModel + * 04.08.2011 added support for "FMI for Co-Simulation 1.0" + * + * (c) 2011 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// array of value references of states +#if NUMBER_OF_REALS>0 +fmiValueReference vrStates[NUMBER_OF_STATES] = STATES; +#endif + +// --------------------------------------------------------------------------- +// Private helpers used below to validate function arguments +// --------------------------------------------------------------------------- + +static fmiBoolean invalidNumber(ModelInstance* comp, const char* f, const char* arg, int n, int nExpected){ + if (n != nExpected) { + comp->state = modelError; + comp->functions.logger(comp, comp->instanceName, fmiError, "error", + "%s: Invalid argument %s = %d. Expected %d.", f, arg, n, nExpected); + return fmiTrue; + } + return fmiFalse; +} + +static fmiBoolean invalidState(ModelInstance* comp, const char* f, int statesExpected){ + if (!comp) + return fmiTrue; + if (!(comp->state & statesExpected)) { + comp->state = modelError; + comp->functions.logger(comp, comp->instanceName, fmiError, "error", + "%s: Illegal call sequence.", f); + return fmiTrue; + } + return fmiFalse; +} + +static fmiBoolean nullPointer(ModelInstance* comp, const char* f, const char* arg, const void* p){ + if (!p) { + comp->state = modelError; + comp->functions.logger(comp, comp->instanceName, fmiError, "error", + "%s: Invalid argument %s = NULL.", f, arg); + return fmiTrue; + } + return fmiFalse; +} + +static fmiBoolean vrOutOfRange(ModelInstance* comp, const char* f, fmiValueReference vr, int end) { + if (vr >= end) { + comp->functions.logger(comp, comp->instanceName, fmiError, "error", + "%s: Illegal value reference %u.", f, vr); + comp->state = fmiError; + return fmiTrue; + } + return fmiFalse; +} + +// --------------------------------------------------------------------------- +// Private helpers used below to implement functions +// --------------------------------------------------------------------------- + +fmiStatus setString(fmiComponent comp, fmiValueReference vr, fmiString value){ + return fmiSetString(comp, &vr, 1, &value); +} + +// fname is fmiInstantiateModel or fmiInstantiateSlave +static fmiComponent instantiateModel(char* fname, fmiString instanceName, fmiString GUID, + fmiCallbackFunctions functions, fmiBoolean loggingOn) { + ModelInstance* comp; + if (!functions.logger) + return NULL; + if (!functions.allocateMemory || !functions.freeMemory){ + functions.logger(NULL, instanceName, fmiError, "error", + "%s: Missing callback function.", fname); + return NULL; + } + if (!instanceName || strlen(instanceName)==0) { + functions.logger(NULL, instanceName, fmiError, "error", + "%s: Missing instance name.", fname); + return NULL; + } + if (strcmp(GUID, MODEL_GUID)) { + functions.logger(NULL, instanceName, fmiError, "error", + "%s: Wrong GUID %s. Expected %s.", fname, GUID, MODEL_GUID); + return NULL; + } + comp = (ModelInstance *)functions.allocateMemory(1, sizeof(ModelInstance)); + if (comp) { + comp->r = functions.allocateMemory(NUMBER_OF_REALS, sizeof(fmiReal)); + comp->i = functions.allocateMemory(NUMBER_OF_INTEGERS, sizeof(fmiInteger)); + comp->b = functions.allocateMemory(NUMBER_OF_BOOLEANS, sizeof(fmiBoolean)); + comp->s = functions.allocateMemory(NUMBER_OF_STRINGS, sizeof(fmiString)); + comp->isPositive = functions.allocateMemory(NUMBER_OF_EVENT_INDICATORS, sizeof(fmiBoolean)); + } + if (!comp || !comp->r || !comp->i || !comp->b || !comp->s || !comp->isPositive) { + functions.logger(NULL, instanceName, fmiError, "error", + "%s: Out of memory.", fname); + return NULL; + } + if (comp->loggingOn) comp->functions.logger(NULL, instanceName, fmiOK, "log", + "%s: GUID=%s", fname, GUID); + comp->instanceName = instanceName; + comp->GUID = GUID; + comp->functions = functions; + comp->loggingOn = loggingOn; + comp->state = modelInstantiated; + setStartValues(comp); // to be implemented by the includer of this file + return comp; +} + +// fname is fmiInitialize or fmiInitializeSlave +static fmiStatus init(char* fname, fmiComponent c, fmiBoolean toleranceControlled, fmiReal relativeTolerance, + fmiEventInfo* eventInfo) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, fname, modelInstantiated)) + return fmiError; + if (nullPointer(comp, fname, "eventInfo", eventInfo)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "%s: toleranceControlled=%d relativeTolerance=%g", + fname, toleranceControlled, relativeTolerance); + eventInfo->iterationConverged = fmiTrue; + eventInfo->stateValueReferencesChanged = fmiFalse; + eventInfo->stateValuesChanged = fmiFalse; + eventInfo->terminateSimulation = fmiFalse; + eventInfo->upcomingTimeEvent = fmiFalse; + initialize(comp, eventInfo); // to be implemented by the includer of this file + comp->state = modelInitialized; + return fmiOK; +} + +// fname is fmiTerminate or fmiTerminateSlave +static fmiStatus terminate(char* fname, fmiComponent c){ + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, fname, modelInitialized)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", fname); + comp->state = modelTerminated; + return fmiOK; +} + +// fname is freeModelInstance of freeSlaveInstance +void freeInstance(char* fname, fmiComponent c) { + ModelInstance* comp = (ModelInstance *)c; + if (!comp) return; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", fname); + if (comp->r) comp->functions.freeMemory(comp->r); + if (comp->i) comp->functions.freeMemory(comp->i); + if (comp->b) comp->functions.freeMemory(comp->b); + if (comp->s) { + int i; + for (i=0; is[i]) comp->functions.freeMemory(comp->s[i]); + } + comp->functions.freeMemory(comp->s); + } + comp->functions.freeMemory(comp); +} + +// --------------------------------------------------------------------------- +// FMI functions: class methods not depending of a specific model instance +// --------------------------------------------------------------------------- + +const char* fmiGetVersion() { + return fmiVersion; +} + +// --------------------------------------------------------------------------- +// FMI functions: for FMI Model Exchange 1.0 and for FMI Co-Simulation 1.0 +// logging control, setters and getters for Real, Integer, Boolean, String +// --------------------------------------------------------------------------- + +fmiStatus fmiSetDebugLogging(fmiComponent c, fmiBoolean loggingOn) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetDebugLogging", not_modelError)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetDebugLogging: loggingOn=%d", loggingOn); + comp->loggingOn = loggingOn; + return fmiOK; +} + +fmiStatus fmiSetReal(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetReal", modelInstantiated|modelInitialized)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetReal", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetReal", "value[]", value)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetReal: nvr = %d", nvr); + // no check wether setting the value is allowed in the current state + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetReal: #r%d# = %.16g", vr[i], value[i]); + comp->r[vr[i]] = value[i]; + } + return fmiOK; +} + +fmiStatus fmiSetInteger(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetInteger", modelInstantiated|modelInitialized)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetInteger", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetInteger", "value[]", value)) + return fmiError; + if (comp->loggingOn) + comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiSetInteger: nvr = %d", nvr); + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetInteger: #i%d# = %d", vr[i], value[i]); + comp->i[vr[i]] = value[i]; + } + return fmiOK; +} + +fmiStatus fmiSetBoolean(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetBoolean", modelInstantiated|modelInitialized)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetBoolean", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetBoolean", "value[]", value)) + return fmiError; + if (comp->loggingOn) + comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiSetBoolean: nvr = %d", nvr); + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetBoolean: #b%d# = %s", vr[i], value[i] ? "true" : "false"); + comp->b[vr[i]] = value[i]; + } + return fmiOK; +} + +fmiStatus fmiSetString(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]){ + int i, n; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetString", modelInstantiated|modelInitialized)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetString", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetString", "value[]", value)) + return fmiError; + if (comp->loggingOn) + comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiSetString: nvr = %d", nvr); + for (i=0; is[vr[i]]; + if (vrOutOfRange(comp, "fmiSetString", vr[i], NUMBER_OF_STRINGS)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetString: #s%d# = '%s'", vr[i], value[i]); + if (nullPointer(comp, "fmiSetString", "value[i]", value[i])) + return fmiError; + if (string==NULL || strlen(string) < strlen(value[i])) { + if (string) comp->functions.freeMemory(string); + comp->s[vr[i]] = comp->functions.allocateMemory(1+strlen(value[i]), sizeof(char)); + if (!comp->s[vr[i]]) { + comp->state = modelError; + comp->functions.logger(NULL, comp->instanceName, fmiError, "error", "fmiSetString: Out of memory."); + return fmiError; + } + } + strcpy(comp->s[vr[i]], value[i]); + } + return fmiOK; +} + +fmiStatus fmiGetReal(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetReal", not_modelError)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetReal", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetReal", "value[]", value)) + return fmiError; +#if NUMBER_OF_REALS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetReal: #r%u# = %.16g", vr[i], value[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiGetInteger(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetInteger", not_modelError)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetInteger", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetInteger", "value[]", value)) + return fmiError; + for (i=0; ii[vr[i]]; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetInteger: #i%u# = %d", vr[i], value[i]); + } + return fmiOK; +} + +fmiStatus fmiGetBoolean(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetBoolean", not_modelError)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetBoolean", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetBoolean", "value[]", value)) + return fmiError; + for (i=0; ib[vr[i]]; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetBoolean: #b%u# = %s", vr[i], value[i]? "true" : "false"); + } + return fmiOK; +} + +fmiStatus fmiGetString(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetString", not_modelError)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetString", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetString", "value[]", value)) + return fmiError; + for (i=0; is[vr[i]]; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetString: #s%u# = '%s'", vr[i], value[i]); + } + return fmiOK; +} + +#ifdef FMI_COSIMULATION +// --------------------------------------------------------------------------- +// FMI functions: only for FMI Co-Simulation 1.0 +// --------------------------------------------------------------------------- + +const char* fmiGetTypesPlatform() { + return fmiPlatform; +} + +fmiComponent fmiInstantiateSlave(fmiString instanceName, fmiString GUID, + fmiString fmuLocation, fmiString mimeType, fmiReal timeout, fmiBoolean visible, + fmiBoolean interactive, fmiCallbackFunctions functions, fmiBoolean loggingOn) { + // ignoring arguments: fmuLocation, mimeType, timeout, visible, interactive + return instantiateModel("fmiInstantiateSlave", instanceName, GUID, functions, loggingOn); +} + +fmiStatus fmiInitializeSlave(fmiComponent c, fmiReal tStart, fmiBoolean StopTimeDefined, fmiReal tStop) { + ModelInstance* comp = (ModelInstance *)c; + fmiBoolean toleranceControlled = fmiFalse; + fmiReal relativeTolerance = 0; + fmiStatus flag = fmiOK; + comp->eventInfo.iterationConverged = 0; + while (flag==fmiOK && !comp->eventInfo.iterationConverged) { + // ignoring arguments: tStart, StopTimeDefined, tStop + flag = init("fmiInitializeSlave", c, toleranceControlled, relativeTolerance, &comp->eventInfo); + } + return flag; +} + +fmiStatus fmiTerminateSlave(fmiComponent c) { + return terminate("fmiTerminateSlave", c); +} + +fmiStatus fmiResetSlave(fmiComponent c) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiResetSlave", modelInitialized)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiResetSlave"); + comp->state = modelInstantiated; + setStartValues(comp); // to be implemented by the includer of this file + return fmiOK; +} + +void fmiFreeSlaveInstance(fmiComponent c) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiFreeSlaveInstance", modelTerminated)) + return; + freeInstance("fmiFreeSlaveInstance", c); +} + +fmiStatus fmiSetRealInputDerivatives(fmiComponent c, const fmiValueReference vr[], size_t nvr, + const fmiInteger order[], const fmiReal value[]) { + ModelInstance* comp = (ModelInstance *)c; + fmiCallbackLogger log = comp->functions.logger; + if (invalidState(comp, "fmiSetRealInputDerivatives", modelInitialized)) + return fmiError; + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "fmiSetRealInputDerivatives: nvr= %d", nvr); + log(NULL, comp->instanceName, fmiError, "warning", "fmiSetRealInputDerivatives: ignoring function call." + " This model cannot interpolate inputs: canInterpolateInputs=\"fmiFalse\""); + return fmiWarning; +} + +fmiStatus fmiGetRealOutputDerivatives(fmiComponent c, const fmiValueReference vr[], size_t nvr, + const fmiInteger order[], fmiReal value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + fmiCallbackLogger log = comp->functions.logger; + if (invalidState(comp, "fmiGetRealOutputDerivatives", modelInitialized)) + return fmiError; + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "fmiGetRealOutputDerivatives: nvr= %d", nvr); + log(NULL, comp->instanceName, fmiError, "warning", "fmiGetRealOutputDerivatives: ignoring function call." + " This model cannot compute derivatives of outputs: MaxOutputDerivativeOrder=\"0\""); + for (i=0; ifunctions.logger; + if (invalidState(comp, "fmiCancelStep", modelInitialized)) + return fmiError; + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "fmiCancelStep"); + log(NULL, comp->instanceName, fmiError, "error", + "fmiCancelStep: Can be called when fmiDoStep returned fmiPending." + " This is not the case."); + return fmiError; +} + +fmiStatus fmiDoStep(fmiComponent c, fmiReal currentCommunicationPoint, + fmiReal communicationStepSize, fmiBoolean newStep) { + ModelInstance* comp = (ModelInstance *)c; + fmiCallbackLogger log = comp->functions.logger; + double h = communicationStepSize / 10; + int k,i; + const int n = 10; // how many Euler steps to perform for one do step + double prevState[max(NUMBER_OF_STATES, 1)]; + double prevEventIndicators[max(NUMBER_OF_EVENT_INDICATORS, 1)]; + int stateEvent = 0; + + if (invalidState(comp, "fmiDoStep", modelInitialized)) + return fmiError; + + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "fmiDoStep: " + "currentCommunicationPoint = %g, ", + "communicationStepSize = %g, ", + "newStep = fmi%s", + currentCommunicationPoint, communicationStepSize, newStep ? "True" : "False"); + + // Treat also case of zero step, i.e. during an event iteration + if (communicationStepSize == 0) { + return fmiOK; + } + +#if NUMBER_OF_EVENT_INDICATORS>0 + // initialize previous event indcators with current values + for (i=0; itime = currentCommunicationPoint; + for (k=0; ktime += h; + +#if NUMBER_OF_REALS>0 + for (i=0; i0 + // check for state event + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiDoStep: state event at %g, z%d crosses zero -%c-", comp->time, i, ei<0 ? '\\' : '/'); + stateEvent++; + } + prevEventIndicators[i] = ei; + } + if (stateEvent) { + eventUpdate(comp, &comp->eventInfo); + stateEvent = 0; + } +#endif + // check for time event + if (comp->eventInfo.upcomingTimeEvent && comp->time > comp->eventInfo.nextEventTime) { + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiDoStep: time event detected at %g", comp->time); + eventUpdate(comp, &comp->eventInfo); + } + + // terminate simulation, if requested by the model + if (comp->eventInfo.terminateSimulation) { + comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiDoStep: model requested termination at t=%g", comp->time); + return fmiError; // enforce termination of the simulation loop + } + } + return fmiOK; +} + +static fmiStatus getStatus(char* fname, fmiComponent c, const fmiStatusKind s) { + const char* statusKind[3] = {"fmiDoStepStatus","fmiPendingStatus","fmiLastSuccessfulTime"}; + ModelInstance* comp = (ModelInstance *)c; + fmiCallbackLogger log = comp->functions.logger; + if (invalidState(comp, fname, modelInstantiated|modelInitialized)) + return fmiError; + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "$s: fmiStatusKind = %s", fname, statusKind[s]); + switch(s) { + case fmiDoStepStatus: log(NULL, comp->instanceName, fmiError, "error", + "%s: Can be called with fmiDoStepStatus when fmiDoStep returned fmiPending." + " This is not the case.", fname); + break; + case fmiPendingStatus: log(NULL, comp->instanceName, fmiError, "error", + "%s: Can be called with fmiPendingStatus when fmiDoStep returned fmiPending." + " This is not the case.", fname); + break; + case fmiLastSuccessfulTime: log(NULL, comp->instanceName, fmiError, "error", + "%s: Can be called with fmiLastSuccessfulTime when fmiDoStep returned fmiDiscard." + " This is not the case.", fname); + break; + } + return fmiError; +} + +fmiStatus fmiGetStatus(fmiComponent c, const fmiStatusKind s, fmiStatus* value) { + return getStatus("fmiGetStatus", c, s); +} + +fmiStatus fmiGetRealStatus(fmiComponent c, const fmiStatusKind s, fmiReal* value){ + return getStatus("fmiGetRealStatus", c, s); +} + +fmiStatus fmiGetIntegerStatus(fmiComponent c, const fmiStatusKind s, fmiInteger* value){ + return getStatus("fmiGetIntegerStatus", c, s); +} + +fmiStatus fmiGetBooleanStatus(fmiComponent c, const fmiStatusKind s, fmiBoolean* value){ + return getStatus("fmiGetBooleanStatus", c, s); +} + +fmiStatus fmiGetStringStatus(fmiComponent c, const fmiStatusKind s, fmiString* value){ + return getStatus("fmiGetStringStatus", c, s); +} + +#else +// --------------------------------------------------------------------------- +// FMI functions: only for Model Exchange 1.0 +// --------------------------------------------------------------------------- + +const char* fmiGetModelTypesPlatform() { + return fmiModelTypesPlatform; +} + +fmiComponent fmiInstantiateModel(fmiString instanceName, fmiString GUID, + fmiCallbackFunctions functions, fmiBoolean loggingOn) { + return instantiateModel("fmiInstantiateModel", instanceName, GUID, functions, loggingOn); +} + +fmiStatus fmiInitialize(fmiComponent c, fmiBoolean toleranceControlled, fmiReal relativeTolerance, + fmiEventInfo* eventInfo) { + return init("fmiInitialize", c, toleranceControlled, relativeTolerance, eventInfo); +} + +fmiStatus fmiSetTime(fmiComponent c, fmiReal time) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetTime", modelInstantiated|modelInitialized)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetTime: time=%.16g", time); + comp->time = time; + return fmiOK; +} + +fmiStatus fmiSetContinuousStates(fmiComponent c, const fmiReal x[], size_t nx){ + ModelInstance* comp = (ModelInstance *)c; + int i; + if (invalidState(comp, "fmiSetContinuousStates", modelInitialized)) + return fmiError; + if (invalidNumber(comp, "fmiSetContinuousStates", "nx", nx, NUMBER_OF_STATES)) + return fmiError; + if (nullPointer(comp, "fmiSetContinuousStates", "x[]", x)) + return fmiError; +#if NUMBER_OF_REALS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetContinuousStates: #r%d#=%.16g", vr, x[i]); + assert(vr>=0 && vrr[vr] = x[i]; + } +#endif + return fmiOK; +} + +fmiStatus fmiEventUpdate(fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiEventUpdate", modelInitialized)) + return fmiError; + if (nullPointer(comp, "fmiEventUpdate", "eventInfo", eventInfo)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiEventUpdate: intermediateResults = %d", intermediateResults); + eventInfo->iterationConverged = fmiTrue; + eventInfo->stateValueReferencesChanged = fmiFalse; + eventInfo->stateValuesChanged = fmiFalse; + eventInfo->terminateSimulation = fmiFalse; + eventInfo->upcomingTimeEvent = fmiFalse; + eventUpdate(comp, eventInfo); // to be implemented by the includer of this file + return fmiOK; +} + +fmiStatus fmiCompletedIntegratorStep(fmiComponent c, fmiBoolean* callEventUpdate){ + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiCompletedIntegratorStep", modelInitialized)) + return fmiError; + if (nullPointer(comp, "fmiCompletedIntegratorStep", "callEventUpdate", callEventUpdate)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiCompletedIntegratorStep"); + *callEventUpdate = fmiFalse; + return fmiOK; +} + +fmiStatus fmiGetStateValueReferences(fmiComponent c, fmiValueReference vrx[], size_t nx){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetStateValueReferences", not_modelError)) + return fmiError; + if (invalidNumber(comp, "fmiGetStateValueReferences", "nx", nx, NUMBER_OF_STATES)) + return fmiError; + if (nullPointer(comp, "fmiGetStateValueReferences", "vrx[]", vrx)) + return fmiError; +#if NUMBER_OF_REALS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetStateValueReferences: vrx[%d] = %d", i, vrx[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiGetContinuousStates(fmiComponent c, fmiReal states[], size_t nx){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetContinuousStates", not_modelError)) + return fmiError; + if (invalidNumber(comp, "fmiGetContinuousStates", "nx", nx, NUMBER_OF_STATES)) + return fmiError; + if (nullPointer(comp, "fmiGetContinuousStates", "states[]", states)) + return fmiError; +#if NUMBER_OF_REALS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetContinuousStates: #r%u# = %.16g", vr, states[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiGetNominalContinuousStates(fmiComponent c, fmiReal x_nominal[], size_t nx){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetNominalContinuousStates", not_modelError)) + return fmiError; + if (invalidNumber(comp, "fmiGetNominalContinuousStates", "nx", nx, NUMBER_OF_STATES)) + return fmiError; + if (nullPointer(comp, "fmiGetNominalContinuousStates", "x_nominal[]", x_nominal)) + return fmiError; + x_nominal[0] = 1; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetNominalContinuousStates: x_nominal[0..%d] = 1.0", nx-1); + for (i=0; i0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetDerivatives: #r%d# = %.16g", vr, derivatives[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiGetEventIndicators(fmiComponent c, fmiReal eventIndicators[], size_t ni) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetEventIndicators", not_modelError)) + return fmiError; + if (invalidNumber(comp, "fmiGetEventIndicators", "ni", ni, NUMBER_OF_EVENT_INDICATORS)) + return fmiError; +#if NUMBER_OF_EVENT_INDICATORS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetEventIndicators: z%d = %.16g", i, eventIndicators[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiTerminate(fmiComponent c){ + return terminate("fmiTerminate", c); +} + +void fmiFreeModelInstance(fmiComponent c) { + freeInstance("fmiFreeModelInstance", c); +} + +#endif // Model Exchange 1.0 diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/fmuTemplate.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/fmuTemplate.h new file mode 100644 index 00000000..486bd406 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/fmuTemplate.h @@ -0,0 +1,49 @@ +/* ---------------------------------------------------------------------------* + * fmuTemplate.h + * Definitions used in fmiModelFunctions.c and by the includer of this file + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +#include +#include +#include + +#ifdef FMI_COSIMULATION +#include "fmiFunctions.h" +#else +#include "fmiModelFunctions.h" +#endif + +// macros used to define variables +#define r(vr) comp->r[vr] +#define i(vr) comp->i[vr] +#define b(vr) comp->b[vr] +#define s(vr) comp->s[vr] +#define pos(z) comp->isPositive[z] +#define copy(vr, value) setString(comp, vr, value) + +#define not_modelError (modelInstantiated|modelInitialized|modelTerminated) + +typedef enum { + modelInstantiated = 1<<0, + modelInitialized = 1<<1, + modelTerminated = 1<<2, + modelError = 1<<3 +} ModelState; + +typedef struct { + fmiReal *r; + fmiInteger *i; + fmiBoolean *b; + fmiString *s; + fmiBoolean *isPositive; + fmiReal time; + fmiString instanceName; + fmiString GUID; + fmiCallbackFunctions functions; + fmiBoolean loggingOn; + ModelState state; +#ifdef FMI_COSIMULATION + fmiEventInfo eventInfo; +#endif +} ModelInstance; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/_main.html new file mode 100644 index 00000000..8850b0d8 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/_main.html @@ -0,0 +1,18 @@ + + + Documentation for inc.fmu + + + +

inc.fmu

+This FMU generates time events to increment an integer counter every second and terminates simulation at t=12 sec. +
+ +
+The figure shows the solution computed with Silver. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/inc.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/inc.c new file mode 100644 index 00000000..8440dcd5 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/inc.c @@ -0,0 +1,56 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU - increments an int counter every second. + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER inc +#define MODEL_GUID "{8c4e810f-3df3-4a00-8276-176fa3c9f008}" + +// define model size +#define NUMBER_OF_REALS 0 +#define NUMBER_OF_INTEGERS 1 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_STATES 0 +#define NUMBER_OF_EVENT_INDICATORS 0 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define counter_ 0 + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + i(counter_) = 1; +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { + eventInfo->upcomingTimeEvent = fmiTrue; + eventInfo->nextEventTime = 1 + comp->time; +} + +// called by fmiEventUpdate() after setting eventInfo to defaults +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { + i(counter_) += 1; + if (i(counter_) == 13) + eventInfo->terminateSimulation = fmiTrue; + else { + eventInfo->upcomingTimeEvent = fmiTrue; + eventInfo->nextEventTime = 1 + comp->time; + } +} + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/modelDescription.xml new file mode 100644 index 00000000..58ce6f81 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/modelDescription.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/plot_counter.PNG b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/plot_counter.PNG new file mode 100644 index 00000000..d3ec25da Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/inc/plot_counter.PNG differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/me.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/me.xml new file mode 100644 index 00000000..5ecace66 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/me.xml @@ -0,0 +1 @@ + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/_main.html new file mode 100644 index 00000000..082d5145 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/_main.html @@ -0,0 +1,19 @@ + + + Documentation for values.fmu + + + +

values.fmu

+ This FMU demonstrates the use of all four scalar FMU data types + and terminates simulation at t=12 sec. + +
+The figure shows the solution computed with fmusim using the command +fmusim me fmu\me\values.fmu 12 12. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/modelDescription.xml new file mode 100644 index 00000000..3673a616 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/modelDescription.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/values.PNG b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/values.PNG new file mode 100644 index 00000000..45eaf966 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/values.PNG differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/values.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/values.c new file mode 100644 index 00000000..536a2904 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/values/values.c @@ -0,0 +1,85 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU + * This demonstrates the use of all FMU variable types. + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER values +#define MODEL_GUID "{8c4e810f-3df3-4a00-8276-176fa3c9f004}" + +// define model size +#define NUMBER_OF_REALS 2 +#define NUMBER_OF_INTEGERS 2 +#define NUMBER_OF_BOOLEANS 2 +#define NUMBER_OF_STRINGS 2 +#define NUMBER_OF_STATES 1 +#define NUMBER_OF_EVENT_INDICATORS 0 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define x_ 0 +#define der_x_ 1 +#define int_in_ 0 +#define int_out_ 1 +#define bool_in_ 0 +#define bool_out_ 1 +#define string_in_ 0 +#define string_out_ 1 + +// define state vector as vector of value references +#define STATES { x_ } + +const char* month[] = { + "jan","feb","march","april","may","june","july", + "august","sept","october","november","december" +}; + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + r(x_) = 1; + i(int_in_) = 2; + i(int_out_) = 0; + b(bool_in_) = fmiTrue; + b(bool_out_) = fmiFalse; + copy(string_in_, "a string"); + copy(string_out_, month[0]); +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { + eventInfo->upcomingTimeEvent = fmiTrue; + eventInfo->nextEventTime = 1 + comp->time; +} + +// called by fmiGetReal, fmiGetContinuousStates and fmiGetDerivatives +fmiReal getReal(ModelInstance* comp, fmiValueReference vr){ + switch (vr) { + case x_ : return r(x_); + case der_x_ : return - r(x_); + default: return 0; + } +} + +// called by fmiEventUpdate() after setting eventInfo to defaults +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { + eventInfo->upcomingTimeEvent = fmiTrue; + eventInfo->nextEventTime = 1 + comp->time; + i(int_out_) += 1; + b(bool_out_) = !b(bool_out_); + if (i(int_out_)<12) copy(string_out_, month[i(int_out_)]); + else eventInfo->terminateSimulation = fmiTrue; +} + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/_main.html new file mode 100644 index 00000000..07875f40 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/_main.html @@ -0,0 +1,23 @@ + + +Documentation for vanDerPol.fmu + + + +

vanDerPol.fmu

+This FMU implements the famous +Van der Pol oscillator. +
    +
  • der(x0) = x1
  • +
  • der(x1) = mu * ((1 - x0 * x0) * x1) - x0
  • +
+ +
+The figure shows the solution computed with Silver +for start values x0 = 2, x1 = 0, mu = 1. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/modelDescription.xml new file mode 100644 index 00000000..ca44c3f3 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/modelDescription.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/plot_states.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/plot_states.png new file mode 100644 index 00000000..05761cd2 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/plot_states.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/vanDerPol.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/vanDerPol.c new file mode 100644 index 00000000..c4945207 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/models/vanDerPol/vanDerPol.c @@ -0,0 +1,75 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU - the Van der Pol oscillator. + * See http://en.wikipedia.org/wiki/Van_der_Pol_oscillator + * + * der(x0) = x1 + * der(x1) = mu * ((1 - x0 ^ 2) * x1) - x0; + * + * start values: x0=2, x1=0, mue=1 + * + * (c) 2011 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER vanDerPol +#define MODEL_GUID "{8c4e810f-3da3-4a00-8276-176fa3c9f000}" + +// define model size +#define NUMBER_OF_REALS 5 +#define NUMBER_OF_INTEGERS 0 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_STATES 2 +#define NUMBER_OF_EVENT_INDICATORS 0 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define x0_ 0 +#define der_x0_ 1 +#define x1_ 2 +#define der_x1_ 3 +#define mu_ 4 + +// define state vector as vector of value references +#define STATES { x0_, x1_ } + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + r(x0_) = 2; + r(x1_) = 0; + r(mu_) = 1; +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +// called by fmiGetReal, fmiGetContinuousStates and fmiGetDerivatives +fmiReal getReal(ModelInstance* comp, fmiValueReference vr){ + switch (vr) { + case x0_ : return r(x0_); + case x1_ : return r(x1_); + case der_x0_ : return r(x1_); + case der_x1_ : return r(mu_) * ((1.0-r(x0_)*r(x0_))*r(x1_)) - r(x0_); + case mu_ : return r(mu_); + default: return 0; + } +} + +// Used to set the next time event, if any. +void eventUpdate(fmiComponent comp, fmiEventInfo* eventInfo) { +} + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/COPYING.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/COPYING.txt new file mode 100644 index 00000000..90422175 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/COPYING.txt @@ -0,0 +1,24 @@ +Files expat.h, expat_external.h and libexpatMT.lib + +Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + and Clark Cooper +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/expat.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/expat.h new file mode 100644 index 00000000..6c2b6ff5 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/expat.h @@ -0,0 +1,1014 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_INCLUDED +#define Expat_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include +#include "expat_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, + /* Added in 2.0. */ + XML_ERROR_RESERVED_PREFIX_XML, + XML_ERROR_RESERVED_PREFIX_XMLNS, + XML_ERROR_RESERVED_NAMESPACE_URI +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, + void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { + XML_INITIALIZED, + XML_PARSING, + XML_FINISHED, + XML_SUSPENDED +}; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR, + XML_FEATURE_NS, + XML_FEATURE_LARGE_SIZE + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 0 +#define XML_MICRO_VERSION 1 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/expat_external.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/expat_external.h new file mode 100644 index 00000000..bb83a995 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/expat_external.h @@ -0,0 +1,115 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(_MSC_VER) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +typedef __int64 XML_Index; +typedef unsigned __int64 XML_Size; +#else +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#endif +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/libexpatMT.lib b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/libexpatMT.lib new file mode 100644 index 00000000..2436f617 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/libexpatMT.lib differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/sim_support.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/sim_support.c new file mode 100644 index 00000000..32b5439b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/sim_support.c @@ -0,0 +1,476 @@ +/* ------------------------------------------------------------------------- + * sim_support.c + * Functions used by both FMU simulators fmusim_me and fmusim_cs + * to parse command-line arguments, to unzip and load an fmu, + * to write CSV file, and more. + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +#ifdef FMI_COSIMULATION +#include "fmi_cs.h" +#else +#include "fmi_me.h" +#endif + +#include "sim_support.h" + +extern FMU fmu; + +int unzip(const char *zipPath, const char *outPath) { + int code; + char cwd[BUFSIZE]; + char binPath[BUFSIZE]; + int n = strlen(UNZIP_CMD) + strlen(outPath) + 1 + strlen(zipPath) + 9; + char* cmd = (char*)calloc(sizeof(char), n); + + // remember current directory + if (!GetCurrentDirectory(BUFSIZE, cwd)) { + printf ("error: Could not get current directory\n"); + return 0; // error + } + + // change to %FMUSDK_HOME%\bin to find 7z.dll and 7z.exe + if (!GetEnvironmentVariable("FMUSDK_HOME", binPath, BUFSIZE)) { + if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + printf ("error: Environment variable FMUSDK_HOME not defined\n"); + } + else { + printf ("error: Could not get value of FMUSDK_HOME\n"); + } + return 0; // error + } + strcat(binPath, "\\bin"); + if (!SetCurrentDirectory(binPath)) { + printf ("error: could not change to directory '%s'\n", binPath); + return 0; // error + } + + // run the unzip command + // remove "> NUL" to see the unzip protocol + sprintf(cmd, "%s%s \"%s\" > NUL", UNZIP_CMD, outPath, zipPath); + // printf("cmd='%s'\n", cmd); + code = system(cmd); + free(cmd); + if (code!=SEVEN_ZIP_NO_ERROR) { + switch (code) { + printf("7z: "); + case SEVEN_ZIP_WARNING: printf("warning\n"); break; + case SEVEN_ZIP_ERROR: printf("error\n"); break; + case SEVEN_ZIP_COMMAND_LINE_ERROR: printf("command line error\n"); break; + case SEVEN_ZIP_OUT_OF_MEMORY: printf("out of memory\n"); break; + case SEVEN_ZIP_STOPPED_BY_USER: printf("stopped by user\n"); break; + default: printf("unknown problem\n"); + } + } + + // restore current directory + SetCurrentDirectory(cwd); + + return (code==SEVEN_ZIP_NO_ERROR || code==SEVEN_ZIP_WARNING) ? 1 : 0; +} + +// fileName is an absolute path, e.g. C:\test\a.fmu +// or relative to the current dir, e.g. ..\test\a.fmu +// Does not check for existence of the file +static char* getFmuPath(const char* fileName){ + char pathName[MAX_PATH]; + int n = GetFullPathName(fileName, MAX_PATH, pathName, NULL); + return n ? strdup(pathName) : NULL; +} + +static char* getTmpPath() { + char tmpPath[BUFSIZE]; + if(! GetTempPath(BUFSIZE, tmpPath)) { + printf ("error: Could not find temporary disk space\n"); + return NULL; + } + strcat(tmpPath, "fmu\\"); + return strdup(tmpPath); +} + +static void* getAdr(int* s, FMU *fmu, const char* functionName){ + char name[BUFSIZE]; + void* fp; + sprintf(name, "%s_%s", getModelIdentifier(fmu->modelDescription), functionName); + fp = GetProcAddress(fmu->dllHandle, name); + if (!fp) { + printf ("warning: Function %s not found in dll\n", name); + *s = 0; // mark dll load as 'failed' + } + return fp; +} + +// Load the given dll and set function pointers in fmu +// Return 0 to indicate failure +static int loadDll(const char* dllPath, FMU *fmu) { + int x = 1, s = 1; + HANDLE h = LoadLibrary(dllPath); + if (!h) { + printf("error: Could not load %s\n", dllPath); + return 0; // failure + } + fmu->dllHandle = h; + +#ifdef FMI_COSIMULATION + fmu->getTypesPlatform = (fGetTypesPlatform) getAdr(&s, fmu, "fmiGetTypesPlatform"); + if (s==0) { + s = 1; // work around bug for FMUs exported using Dymola 2012 and SimulationX 3.x + fmu->getTypesPlatform = (fGetTypesPlatform) getAdr(&s, fmu, "fmiGetModelTypesPlatform"); + if (s==1) printf(" using fmiGetModelTypesPlatform instead\n", dllPath); + } + fmu->instantiateSlave = (fInstantiateSlave) getAdr(&s, fmu, "fmiInstantiateSlave"); + fmu->initializeSlave = (fInitializeSlave) getAdr(&s, fmu, "fmiInitializeSlave"); + fmu->terminateSlave = (fTerminateSlave) getAdr(&s, fmu, "fmiTerminateSlave"); + fmu->resetSlave = (fResetSlave) getAdr(&s, fmu, "fmiResetSlave"); + fmu->freeSlaveInstance = (fFreeSlaveInstance) getAdr(&s, fmu, "fmiFreeSlaveInstance"); + fmu->setRealInputDerivatives = (fSetRealInputDerivatives) getAdr(&s, fmu, "fmiSetRealInputDerivatives"); + fmu->getRealOutputDerivatives = (fGetRealOutputDerivatives) getAdr(&s, fmu, "fmiGetRealOutputDerivatives"); + fmu->cancelStep = (fCancelStep) getAdr(&s, fmu, "fmiCancelStep"); + fmu->doStep = (fDoStep) getAdr(&s, fmu, "fmiDoStep"); + // SimulationX 3.4 and 3.5 do not yet export getStatus and getXStatus: do not count this as failure here + fmu->getStatus = (fGetStatus) getAdr(&x, fmu, "fmiGetStatus"); + fmu->getRealStatus = (fGetRealStatus) getAdr(&x, fmu, "fmiGetRealStatus"); + fmu->getIntegerStatus = (fGetIntegerStatus) getAdr(&x, fmu, "fmiGetIntegerStatus"); + fmu->getBooleanStatus = (fGetBooleanStatus) getAdr(&x, fmu, "fmiGetBooleanStatus"); + fmu->getStringStatus = (fGetStringStatus) getAdr(&x, fmu, "fmiGetStringStatus"); + +#else // FMI for Model Exchange 1.0 + fmu->getModelTypesPlatform = (fGetModelTypesPlatform) getAdr(&s, fmu, "fmiGetModelTypesPlatform"); + fmu->instantiateModel = (fInstantiateModel) getAdr(&s, fmu, "fmiInstantiateModel"); + fmu->freeModelInstance = (fFreeModelInstance) getAdr(&s, fmu, "fmiFreeModelInstance"); + fmu->setTime = (fSetTime) getAdr(&s, fmu, "fmiSetTime"); + fmu->setContinuousStates = (fSetContinuousStates)getAdr(&s, fmu, "fmiSetContinuousStates"); + fmu->completedIntegratorStep = (fCompletedIntegratorStep)getAdr(&s, fmu, "fmiCompletedIntegratorStep"); + fmu->initialize = (fInitialize) getAdr(&s, fmu, "fmiInitialize"); + fmu->getDerivatives = (fGetDerivatives) getAdr(&s, fmu, "fmiGetDerivatives"); + fmu->getEventIndicators = (fGetEventIndicators) getAdr(&s, fmu, "fmiGetEventIndicators"); + fmu->eventUpdate = (fEventUpdate) getAdr(&s, fmu, "fmiEventUpdate"); + fmu->getContinuousStates = (fGetContinuousStates)getAdr(&s, fmu, "fmiGetContinuousStates"); + fmu->getNominalContinuousStates = (fGetNominalContinuousStates)getAdr(&s, fmu, "fmiGetNominalContinuousStates"); + fmu->getStateValueReferences = (fGetStateValueReferences)getAdr(&s, fmu, "fmiGetStateValueReferences"); + fmu->terminate = (fTerminate) getAdr(&s, fmu, "fmiTerminate"); +#endif + fmu->getVersion = (fGetVersion) getAdr(&s, fmu, "fmiGetVersion"); + fmu->setDebugLogging = (fSetDebugLogging) getAdr(&s, fmu, "fmiSetDebugLogging"); + fmu->setReal = (fSetReal) getAdr(&s, fmu, "fmiSetReal"); + fmu->setInteger = (fSetInteger) getAdr(&s, fmu, "fmiSetInteger"); + fmu->setBoolean = (fSetBoolean) getAdr(&s, fmu, "fmiSetBoolean"); + fmu->setString = (fSetString) getAdr(&s, fmu, "fmiSetString"); + fmu->getReal = (fGetReal) getAdr(&s, fmu, "fmiGetReal"); + fmu->getInteger = (fGetInteger) getAdr(&s, fmu, "fmiGetInteger"); + fmu->getBoolean = (fGetBoolean) getAdr(&s, fmu, "fmiGetBoolean"); + fmu->getString = (fGetString) getAdr(&s, fmu, "fmiGetString"); + return s; +} + +static void printModelDescription(ModelDescription* md){ + Element* e = (Element*)md; + int i; + printf("%s\n", elmNames[e->type]); + for (i=0; in; i+=2) + printf(" %s=%s\n", e->attributes[i], e->attributes[i+1]); +#ifdef FMI_COSIMULATION + if (!md->cosimulation) { + printf("error: No Implementation element found in model description. This FMU is not for Co-Simulation.\n"); + exit(EXIT_FAILURE); + } + e = md->cosimulation->capabilities; + printf("%s\n", elmNames[e->type]); + for (i=0; in; i+=2) + printf(" %s=%s\n", e->attributes[i], e->attributes[i+1]); +#endif // FMI_COSIMULATION +} + +void loadFMU(const char* fmuFileName) { + char* fmuPath; + char* tmpPath; + char* xmlPath; + char* dllPath; + + // get absolute path to FMU, NULL if not found + fmuPath = getFmuPath(fmuFileName); + if (!fmuPath) exit(EXIT_FAILURE); + + // unzip the FMU to the tmpPath directory + tmpPath = getTmpPath(); + if (!unzip(fmuPath, tmpPath)) exit(EXIT_FAILURE); + + // parse tmpPath\modelDescription.xml + xmlPath = calloc(sizeof(char), strlen(tmpPath) + strlen(XML_FILE) + 1); + sprintf(xmlPath, "%s%s", tmpPath, XML_FILE); + fmu.modelDescription = parse(xmlPath); + free(xmlPath); + if (!fmu.modelDescription) exit(EXIT_FAILURE); + printModelDescription(fmu.modelDescription); + + // load the FMU dll + dllPath = calloc(sizeof(char), strlen(tmpPath) + strlen(DLL_DIR) + + strlen( getModelIdentifier(fmu.modelDescription)) + strlen(".dll") + 1); + sprintf(dllPath,"%s%s%s.dll", tmpPath, DLL_DIR, getModelIdentifier(fmu.modelDescription)); + if (!loadDll(dllPath, &fmu)) exit(EXIT_FAILURE); + free(dllPath); + free(fmuPath); + free(tmpPath); +} + +static void doubleToCommaString(char* buffer, double r){ + char* comma; + sprintf(buffer, "%.16g", r); + comma = strchr(buffer, '.'); + if (comma) *comma = ','; +} + +// output time and all non-alias variables in CSV format +// if separator is ',', columns are separated by ',' and '.' is used for floating-point numbers. +// otherwise, the given separator (e.g. ';' or '\t') is to separate columns, and ',' is used +// as decimal dot in floating-point numbers. +void outputRow(FMU *fmu, fmiComponent c, double time, FILE* file, char separator, boolean header) { + int k; + fmiReal r; + fmiInteger i; + fmiBoolean b; + fmiString s; + fmiValueReference vr; + ScalarVariable** vars = fmu->modelDescription->modelVariables; + char buffer[32]; + + // print first column + if (header) + fprintf(file, "time"); + else { + if (separator==',') + fprintf(file, "%.16g", time); + else { + // separator is e.g. ';' or '\t' + doubleToCommaString(buffer, time); + fprintf(file, "%s", buffer); + } + } + + // print all other columns + for (k=0; vars[k]; k++) { + ScalarVariable* sv = vars[k]; + if (getAlias(sv)!=enu_noAlias) continue; + if (header) { + // output names only + if (separator==',') { + // treat array element, e.g. print a[1, 2] as a[1.2] + char* s = getName(sv); + fprintf(file, "%c", separator); + while (*s) { + if (*s!=' ') fprintf(file, "%c", *s==',' ? '.' : *s); + s++; + } + } + else + fprintf(file, "%c%s", separator, getName(sv)); + } + else { + // output values + vr = getValueReference(sv); + switch (sv->typeSpec->type){ + case elm_Real: + fmu->getReal(c, &vr, 1, &r); + if (separator==',') + fprintf(file, ",%.16g", r); + else { + // separator is e.g. ';' or '\t' + doubleToCommaString(buffer, r); + fprintf(file, "%c%s", separator, buffer); + } + break; + case elm_Integer: + case elm_Enumeration: + fmu->getInteger(c, &vr, 1, &i); + fprintf(file, "%c%d", separator, i); + break; + case elm_Boolean: + fmu->getBoolean(c, &vr, 1, &b); + fprintf(file, "%c%d", separator, b); + break; + case elm_String: + fmu->getString(c, &vr, 1, &s); + fprintf(file, "%c%s", separator, s); + break; + default: + fprintf(file, "%cNoValueForType=%d", separator,sv->typeSpec->type); + } + } + } // for + + // terminate this row + fprintf(file, "\n"); +} + +static const char* fmiStatusToString(fmiStatus status){ + switch (status){ + case fmiOK: return "ok"; + case fmiWarning: return "warning"; + case fmiDiscard: return "discard"; + case fmiError: return "error"; + case fmiFatal: return "fatal"; +#ifdef FMI_COSIMULATION + case fmiPending: return "fmiPending"; +#endif + default: return "?"; + } +} + +// search a fmu for the given variable +// return NULL if not found or vr = fmiUndefinedValueReference +static ScalarVariable* getSV(FMU* fmu, char type, fmiValueReference vr) { + int i; + Elm tp; + ScalarVariable** vars = fmu->modelDescription->modelVariables; + if (vr==fmiUndefinedValueReference) return NULL; + switch (type) { + case 'r': tp = elm_Real; break; + case 'i': tp = elm_Integer; break; + case 'b': tp = elm_Boolean; break; + case 's': tp = elm_String; break; + } + for (i=0; vars[i]; i++) { + ScalarVariable* sv = vars[i]; + if (vr==getValueReference(sv) && tp==sv->typeSpec->type) + return sv; + } + return NULL; +} + +// replace e.g. #r1365# by variable name and ## by # in message +// copies the result to buffer +static void replaceRefsInMessage(const char* msg, char* buffer, int nBuffer, FMU* fmu){ + int i=0; // position in msg + int k=0; // position in buffer + int n; + char c = msg[i]; + while (c!='\0' && k < nBuffer) { + if (c!='#') { + buffer[k++]=c; + i++; + c = msg[i]; + } + else { + char* end = strchr(msg+i+1, '#'); + if (!end) { + printf("unmatched '#' in '%s'\n", msg); + buffer[k++]='#'; + break; + } + n = end - (msg+i); + if (n==1) { + // ## detected, output # + buffer[k++]='#'; + i += 2; + c = msg[i]; + } + else { + char type = msg[i+1]; // one of ribs + fmiValueReference vr; + int nvr = sscanf(msg+i+2, "%u", &vr); + if (nvr==1) { + // vr of type detected, e.g. #r12# + ScalarVariable* sv = getSV(fmu, type, vr); + const char* name = sv ? getName(sv) : "?"; + sprintf(buffer+k, "%s", name); + k += strlen(name); + i += (n+1); + c = msg[i]; + } + else { + // could not parse the number + printf("illegal value reference at position %d in '%s'\n", i+2, msg); + buffer[k++]='#'; + break; + } + } + } + } // while + buffer[k] = '\0'; +} + +#define MAX_MSG_SIZE 1000 +void fmuLogger(fmiComponent c, fmiString instanceName, fmiStatus status, + fmiString category, fmiString message, ...) { + char msg[MAX_MSG_SIZE]; + char* copy; + va_list argp; + + // replace C format strings + va_start(argp, message); + vsprintf(msg, message, argp); + + // replace e.g. ## and #r12# + copy = strdup(msg); + replaceRefsInMessage(copy, msg, MAX_MSG_SIZE, &fmu); + free(copy); + + // print the final message + if (!instanceName) instanceName = "?"; + if (!category) category = "?"; + printf("%s %s (%s): %s\n", fmiStatusToString(status), instanceName, category, msg); +} + +int error(const char* message){ + printf("%s\n", message); + return 0; +} + +void parseArguments(int argc, char *argv[], char** fmuFileName, double* tEnd, double* h, int* loggingOn, char* csv_separator) { + // parse command line arguments + if (argc>1) { + *fmuFileName = argv[1]; + } + else { + printf("error: no fmu file\n"); + printHelp(argv[0]); + exit(EXIT_FAILURE); + } + if (argc>2) { + if (sscanf(argv[2],"%lf", tEnd) != 1) { + printf("error: The given end time (%s) is not a number\n", argv[2]); + exit(EXIT_FAILURE); + } + } + if (argc>3) { + if (sscanf(argv[3],"%lf", h) != 1) { + printf("error: The given stepsize (%s) is not a number\n", argv[3]); + exit(EXIT_FAILURE); + } + } + if (argc>4) { + if (sscanf(argv[4],"%d", loggingOn) != 1 || *loggingOn<0 || *loggingOn>1) { + printf("error: The given logging flag (%s) is not boolean\n", argv[4]); + exit(EXIT_FAILURE); + } + } + if (argc>5) { + if (strlen(argv[5]) != 1) { + printf("error: The given CSV separator char (%s) is not valid\n", argv[5]); + exit(EXIT_FAILURE); + } + switch (argv[5][0]) { + case 'c': *csv_separator = ','; break; // comma + case 's': *csv_separator = ';'; break; // semicolon + default: *csv_separator = argv[5][0]; break; // any other char + } + } + if (argc>6) { + printf("warning: Ignoring %d additional arguments: %s ...\n", argc-6, argv[6]); + printHelp(argv[0]); + } +} + +void printHelp(const char* fmusim) { + printf("command syntax: %s \n", fmusim); + printf(" .... path to FMU, relative to current dir or absolute, required\n"); + printf(" ......... end time of simulation, optional, defaults to 1.0 sec\n"); + printf(" ............ step size of simulation, optional, defaults to 0.1 sec\n"); + printf(" .... 1 to activate logging, optional, defaults to 0\n"); + printf(" . separator in csv file, optional, c for ';', s for';', defaults to c\n"); +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/sim_support.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/sim_support.h new file mode 100644 index 00000000..648c8b59 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/sim_support.h @@ -0,0 +1,31 @@ +/* ------------------------------------------------------------------------- + * sim_support.h + * Functions used by the FMU simulatios fmusim_me and fmusim_cs. + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +// Used 7z options, version 4.57: +// -x Extracts files from an archive with their full paths in the current dir, or in an output dir if specified +// -aoa Overwrite All existing files without prompt +// -o Specifies a destination directory where files are to be extracted +#define UNZIP_CMD "7z x -aoa -o" +#define XML_FILE "modelDescription.xml" +#define DLL_DIR "binaries\\win32\\" +#define RESULT_FILE "result.csv" +#define BUFSIZE 4096 + +// return codes of the 7z command line tool +#define SEVEN_ZIP_NO_ERROR 0 // success +#define SEVEN_ZIP_WARNING 1 // e.g., one or more files were locked during zip +#define SEVEN_ZIP_ERROR 2 +#define SEVEN_ZIP_COMMAND_LINE_ERROR 7 +#define SEVEN_ZIP_OUT_OF_MEMORY 8 +#define SEVEN_ZIP_STOPPED_BY_USER 255 + +void fmuLogger(fmiComponent c, fmiString instanceName, fmiStatus status, fmiString category, fmiString message, ...); +int unzip(const char *zipPath, const char *outPath); +void parseArguments(int argc, char *argv[], char** fmuFileName, double* tEnd, double* h, int* loggingOn, char* csv_separator); +void loadFMU(const char* fmuFileName); +void outputRow(FMU *fmu, fmiComponent c, double time, FILE* file, char separator, boolean header); +int error(const char* message); +void printHelp(const char* fmusim); diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/stack.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/stack.c new file mode 100644 index 00000000..042b796b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/stack.c @@ -0,0 +1,85 @@ +/* ------------------------------------------------------------------------- + * stack.c + * A stack of pointers. + * Copyright 2010 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#include +#include +#include +#include "stack.h" + +Stack* stackNew(int initialSize, int inc){ + Stack* s = (Stack*)malloc(sizeof(Stack)); + s->stack = NULL; + s->stackSize = 0; + s->stackPos = -1; + s->initialSize = initialSize; + s->inc = inc; + return s; +} + +int stackIsEmpty(Stack* s) { + return s->stackPos == -1; +} + +// add an element to stack and grow stack if required +// returns 1 to indicate success and 0 for error +int stackPush(Stack* s, void* e) { + s->stackPos++; + if (s->stackPos==s->stackSize){ + s->stackSize += (s->stack ? s->inc: s->initialSize); + s->stack = (void**) realloc(s->stack, s->stackSize * sizeof(void*)); + if (!s->stack) return 0; // error; + } + s->stack[s->stackPos] = e; + return 1; // success +} + +// return top element (possibly NULL), if stack not empty +// runtime error if stack is empty +void* stackPeek(Stack* s){ + assert(!stackIsEmpty(s)); + return s->stack[s->stackPos]; +} + +// remove top element (possibly NULL) from stack and return it +// runtime error if stack is empty +void* stackPop(Stack* s){ + assert(!stackIsEmpty(s)); + return s->stack[s->stackPos--]; +} + +// return the last n elements as null terminated array, +// or NULL if memory allocation fails +void** stackLastPopedAsArray0(Stack* s, int n){ + int i; + void** array = (void**)malloc((n + 1)*sizeof(void*)); + if (! array) return NULL; // failure + for (i=0; istack[i+ s->stackPos + 1]; + } + array[n]=NULL; // terminating NULL + return array; +} + +// return stack as possibly empty array, or NULL if memory allocation fails +// On sucessful return, the stack is empty. +void** stackPopAllAsArray(Stack* s, int *size) { + int i; + void** array = (void**)malloc((s->stackPos + 1)*sizeof(void*)); + if (! array) return NULL; // failure + *size = s->stackPos + 1; + for (i=0; i<*size; i++) + array[i] = s->stack[i]; + s->stackPos = -1; + return array; +} + +// release the given stack +void stackFree(Stack* s){ + if (s->stack) free(s->stack); + free(s); +} + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/stack.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/stack.h new file mode 100644 index 00000000..a52977fa --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/stack.h @@ -0,0 +1,28 @@ +/* ------------------------------------------------------------------------- + * stack.c + * A stack of pointers. + * Copyright 2010 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#ifndef STACK_H +#define STACK_H + +typedef struct { + void** stack; + int stackSize; // allocated size of stack + int stackPos; // array index of top element, -1 if stack is empty. + int initialSize; // how many element to allocate initially + int inc; // how many elements to allocate when stack gets full +} Stack; + +Stack* stackNew(int initialSize, int inc); +int stackIsEmpty(Stack* s); +int stackPush(Stack* s, void* e); +void* stackPeek(Stack* s); +void* stackPop(Stack* s); +void** stackPopAllAsArray(Stack* s, int *size); +void** stackLastPopedAsArray0(Stack* s, int n); +void stackFree(Stack* s); + +#endif // STACK_H + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/xml_parser.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/xml_parser.c new file mode 100644 index 00000000..93e62162 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/xml_parser.c @@ -0,0 +1,860 @@ +/* ------------------------------------------------------------------------- + * xml_Parser.c + * A parser for file modelVariables.xml of an FMU. + * The parser creates an AST (abstract syntax tree) for a given XML file. + * The root node of the AST is of type ModelDescription. + * Validation already performed by this parser + * - check for match of open/close elements (performed by Expat) + * - ceck element, attribute and enum value names, all case sensitive + * - check for each element that is has the expected parent element + * - check for correct sequence of elements + * - check that all decalaredType values reference an existing Type + * Validation to be performed by this parser + * - check for each attribute value that it is of the expected type + * - check that required attributes are present + * - check that dependencies are only declared for outputs and + * refer only to inputs + * Author: Jakob Mauss + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#include +#include +#include +#include "xml_parser.h" + +const char *elmNames[SIZEOF_ELM] = { + "fmiModelDescription","UnitDefinitions","BaseUnit","DisplayUnitDefinition","TypeDefinitions", + "Type","RealType","IntegerType","BooleanType","StringType","EnumerationType","Item", + "DefaultExperiment","VendorAnnotations","Tool","Annotation", "ModelVariables","ScalarVariable", + "DirectDependency","Name","Real","Integer","Boolean","String","Enumeration", + "Implementation","CoSimulation_StandAlone","CoSimulation_Tool","Model","File","Capabilities" +}; + +const char *attNames[SIZEOF_ATT] = { + "fmiVersion","displayUnit","gain","offset","unit","name","description","quantity", "relativeQuantity", + "min","max","nominal","declaredType","start","fixed","startTime","stopTime","tolerance","value", + "valueReference","variability","causality","alias", "modelName","modelIdentifier","guid","author", + "version","generationTool","generationDateAndTime","variableNamingConvention","numberOfContinuousStates", + "numberOfEventIndicators","input", + "canHandleVariableCommunicationStepSize","canHandleEvents","canRejectSteps","canInterpolateInputs", + "maxOutputDerivativeOrder","canRunAsynchronuously","canSignalEvents","canBeInstantiatedOnlyOncePerProcess", + "canNotUseMemoryManagementFunctions","file","entryPoint","manualStart","type" +}; + +const char *enuNames[SIZEOF_ENU] = { + "flat","structured","constant","parameter","discrete","continuous", + "input","output", "internal","none","noAlias","alias","negatedAlias" +}; + +#define ANY_TYPE -1 +#define XMLBUFSIZE 1024 +char text[XMLBUFSIZE]; // XML file is parsed in chunks of length XMLBUFZIZE +XML_Parser parser = NULL; // non-NULL during parsing +Stack* stack = NULL; // the parser stack +char* data = NULL; // buffer that holds element content, see handleData +int skipData=0; // 1 to ignore element content, 0 when recordig content + +// ------------------------------------------------------------------------- +// Low-level functions for inspecting the model description + +const char* getString(void* element, Att a){ + Element* e = (Element*)element; + const char** attr = e->attributes; + int i; + for (i=0; in; i+=2) + if (attr[i]==attNames[a]) return attr[i+1]; + return NULL; +} + +double getDouble(void* element, Att a, ValueStatus* vs){ + double d = 0; + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return d; } + *vs = (1==sscanf(value, "%lf", &d)) ? valueDefined : valueIllegal; + return d; +} + +// getInt() is also used to retrieve Enumeration values from XML, +// e.g. the start value for a variable of user-defined enumeration type. +int getInt(void* element, Att a, ValueStatus* vs){ + int n = 0; + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return n; } + *vs = (1==sscanf(value, "%d", &n)) ? valueDefined : valueIllegal; + return n; +} + +unsigned int getUInt(void* element, Att a, ValueStatus* vs){ + unsigned int u = -1; + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return u; } + *vs = (1==sscanf(value, "%u", &u)) ? valueDefined : valueIllegal; + return u; +} + +char getBoolean(void* element, Att a, ValueStatus* vs){ + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return 0; }; + *vs = valueDefined; + if (!strcmp(value, "true")) return 1; + if (!strcmp(value, "false")) return 0; + *vs = valueIllegal; + return 0; +} + +static int checkEnumValue(const char* enu); + +// Retrieve the value of the given built-in enum attribute. +// If the value is missing, this is marked in the ValueStatus +// and the corresponding default is returned. +// Returns -1 or a globally unique id for the value such that +// enuNames[id] is the string representation of the enum value. +Enu getEnumValue(void* element, Att a, ValueStatus* vs) { + const char* value = getString(element, a); + Enu id = valueDefined; + if (!value) { + *vs = valueMissing; + switch (a) { + case att_variableNamingConvention: return enu_flat; + case att_variability: return enu_continuous; + case att_causality: return enu_internal; + case att_alias: return enu_noAlias; + default: return -1; + } + } + id = checkEnumValue(value); + if (id==-1) *vs = valueIllegal; + return id; +} + +// ------------------------------------------------------------------------- +// Convenience methods for accessing the model description. +// Use is only safe after the ast has been successfuly validated. + +const char* getModelIdentifier(ModelDescription* md) { + const char* modelId = getString(md, att_modelIdentifier); + assert(modelId); // this is a required attribute + return modelId; +} + +int getNumberOfStates(ModelDescription* md) { + ValueStatus vs; + int n = getUInt(md, att_numberOfContinuousStates, &vs); + assert(vs==valueDefined); // this is a required attribute + return n; +} + +int getNumberOfEventIndicators(ModelDescription* md) { + ValueStatus vs; + int n = getInt(md, att_numberOfEventIndicators, &vs); + assert(vs==valueDefined); // this is a required attribute + return n; +} + +// name is a required attribute of ScalarVariable, Type, Item, Annotation, and Tool +const char* getName(void* element) { + const char* name = getString(element, att_name); + assert(name); // this is a required attribute + return name; +} + +// returns one of: input, output, internal, none +// if value is missing, the default internal is returned +Enu getCausality(void* scalarVariable) { + ValueStatus vs; + return getEnumValue(scalarVariable, att_causality, &vs); +} + +// returns one of constant, parameter, discrete, continuous +// if value is missing, the default continuous is returned +Enu getVariability(void* scalarVariable) { + ValueStatus vs; + return getEnumValue(scalarVariable, att_variability, &vs); +} + +// returns one of noAlias, alias, negatedAlias +// if value is missing, the default noAlias is returned +Enu getAlias(void* scalarVariable) { + ValueStatus vs; + return getEnumValue(scalarVariable, att_alias, &vs); +} + +// the vr is unique only for one of the 4 base data types r,i,b,s and +// may also be fmiUndefinedValueReference = 4294967295 = 0xFFFFFFFF +// here, i means integer or enumeration +fmiValueReference getValueReference(void* scalarVariable) { + ValueStatus vs; + fmiValueReference vr = getUInt(scalarVariable, att_valueReference, &vs); + assert(((Element*)scalarVariable)->type == elm_ScalarVariable); + assert(vs==valueDefined); // this is a reqired attribute + return vr; +} + +// the name is unique within a fmu +ScalarVariable* getVariableByName(ModelDescription* md, const char* name) { + int i; + if (md->modelVariables) + for (i=0; md->modelVariables[i]; i++){ + ScalarVariable* sv = (ScalarVariable*)md->modelVariables[i]; + if (!strcmp(getName(sv), name)) return sv; + } + return NULL; +} + +// Enumeration and Integer have the same base type while +// Real, String, Boolean define own base types. +int sameBaseType(Elm t1, Elm t2){ + return t1==t2 || + t1==elm_Enumeration && t2==elm_Integer || + t2==elm_Enumeration && t1==elm_Integer; +} + +// returns NULL if variable not found or vr==fmiUndefinedValueReference +ScalarVariable* getVariable(ModelDescription* md, fmiValueReference vr, Elm type){ + int i; + if (md->modelVariables && vr!=fmiUndefinedValueReference) + for (i=0; md->modelVariables[i]; i++){ + ScalarVariable* sv = (ScalarVariable*)md->modelVariables[i]; + if (sameBaseType(type, sv->typeSpec->type) && getValueReference(sv) == vr) + return sv; + } + return NULL; +} + +Type* getDeclaredType(ModelDescription* md, const char* declaredType){ + int i; + if (declaredType && md->typeDefinitions) + for (i=0; md->typeDefinitions[i]; i++){ + Type* tp = (Type*)md->typeDefinitions[i]; + if (!strcmp(declaredType, getName(tp))) return tp; + } + return NULL; +} + +const char* getString2(ModelDescription* md, void* tp, Att a) { + Type* type; + const char* value = getString(tp, a); + if (value) return value; // found + // search declared type, if any + type = getDeclaredType(md, getString(tp, att_declaredType)); + return type ? getString(type->typeSpec, a) : NULL; +} + +// Get description from variable or from declared type, or NULL. +const char * getDescription(ModelDescription* md, ScalarVariable* sv) { + const char* value = getString(sv, att_description); + Type* type; + if (value) return value; // found + // search declared type, if any + type = getDeclaredType(md, getString(sv->typeSpec, att_declaredType)); + return type ? getString(type, att_description) : NULL; +} + +// Get attribute value from scalar variable given by vr and type, +// incl. default value provided by declared type, if any. +const char * getVariableAttributeString(ModelDescription* md, + fmiValueReference vr, Elm type, Att a){ + const char* value; + const char* declaredType; + Type* tp; + ScalarVariable* sv = getVariable(md, vr, type); + if (!sv) return NULL; + value = getString(sv->typeSpec, a); + if (value) return value; // found + // search declared type, if any + tp = getDeclaredType(md, getString(sv->typeSpec, att_declaredType)); + return tp ? getString(tp->typeSpec, a) : NULL; +} + +// Get attribute value from scalar variable given by vr and type, +// incl. default value provided by declared type, if any. +double getVariableAttributeDouble(ModelDescription* md, + fmiValueReference vr, Elm type, Att a, ValueStatus* vs){ + double d = 0; + const char* value = getVariableAttributeString(md, vr, type, a); + if (!value) { *vs = valueMissing; return d; } + *vs = (1==sscanf(value, "%lf", &d)) ? valueDefined : valueIllegal; + return d; +} + +// Get nominal value from real variable or its declared type. +// Return 1, if no nominal value is defined. +double getNominal(ModelDescription* md, fmiValueReference vr){ + ValueStatus vs; + double nominal = getVariableAttributeDouble(md, vr, elm_Real, att_nominal, &vs); + return vs==valueDefined ? nominal : 1.0; +} + +// ------------------------------------------------------------------------- +// Various checks that log an error and stop the parser + +// Returns 0 to indicate error +static int checkPointer(const void* ptr){ + if (! ptr) { + printf("Out of memory\n"); + if (parser) XML_StopParser(parser, XML_FALSE); + return 0; // error + } + return 1; // success +} + +static int checkName(const char* name, const char* kind, const char* array[], int n){ + int i; + for (i=0; itype == e) return 1; // success + logFatalTypeError(elmNames[e], elm->type); + return 0; // error +} + +// Returns 0 to indicate error +// Verify that the next stack element exists and is of the given type +// If e==ANY_TYPE, the type check is ommited +static int checkPeek(Elm e) { + if (stackIsEmpty(stack)){ + printf("Illegal document structure, expected %s\n", elmNames[e]); + XML_StopParser(parser, XML_FALSE); + return 0; // error + } + return e==ANY_TYPE ? 1 : checkElementType(stackPeek(stack), e); +} + +// Returns NULL to indicate error +// Get the next stack element, it is of the given type. +// If e==ANY_TYPE, the type check is ommited +static void* checkPop(Elm e){ + return checkPeek(e) ? stackPop(stack) : NULL; +} + +// ------------------------------------------------------------------------- +// Helper + +AstNodeType getAstNodeType(Elm e){ + switch (e) { + case elm_fmiModelDescription: + return astModelDescription; + case elm_Type: + return astType; + case elm_ScalarVariable: + return astScalarVariable; + case elm_CoSimulation_StandAlone: + case elm_CoSimulation_Tool: + return astCoSimulation; + case elm_BaseUnit: + case elm_EnumerationType: + case elm_Tool: + case elm_UnitDefinitions: + case elm_TypeDefinitions: + case elm_VendorAnnotations: + case elm_ModelVariables: + case elm_DirectDependency: + case elm_Model: + return astListElement; + default: + return astElement; + } +} + +// Returns 0 to indicate error +// Copies the attr array and all values. +// Replaces all attribute names by constant literal strings. +// Converts the null-terminated array into an array of known size n. +int addAttributes(Element* el, const char** attr) { + int n, a; + const char** att = NULL; + for (n=0; attr[n]; n+=2); + if (n>0) { + att = calloc(n, sizeof(char*)); + if (!checkPointer(att)) return 0; + } + for (n=0; attr[n]; n+=2) { + char* value = strdup(attr[n+1]); + if (!checkPointer(value)) return 0; + a = checkAttribute(attr[n]); + if (a == -1) return 0; // illegal attribute error + att[n ] = attNames[a]; // no heap memory + att[n+1] = value; // heap memory + } + el->attributes = att; // NULL if n=0 + el->n = n; + return 1; // success +} + +// Returns NULL to indicate error +Element* newElement(Elm type, int size, const char** attr) { + Element* e = (Element*)calloc(1, size); + if (!checkPointer(e)) return NULL; + e->type = type; + e->attributes = NULL; + e->n=0; + if (!addAttributes(e, attr)) return NULL; + return e; +} + +// ------------------------------------------------------------------------- +// callback functions called by the XML parser + +// Create and push a new element node +static void XMLCALL startElement(void *context, const char *elm, const char **attr) { + Elm el; + void* e; + int size; + el = checkElement(elm); + if (el==-1) return; // error + skipData = (el != elm_Name); // skip element content for all elements but Name + switch(getAstNodeType(el)){ + case astElement: size = sizeof(Element); break; + case astListElement: size = sizeof(ListElement); break; + case astType: size = sizeof(Type); break; + case astScalarVariable: size = sizeof(ScalarVariable); break; + case astCoSimulation: size = sizeof(CoSimulation); break; + case astModelDescription: size = sizeof(ModelDescription); break; + default: assert(0); + } + e = newElement(el, size, attr); + checkPointer(e); + stackPush(stack, e); +} + +// Pop all elements of the given type from stack and +// add it to the ListElement that follows. +// The ListElement remains on the stack. +static void popList(Elm e) { + int n = 0; + Element** array; + Element* elm = stackPop(stack); + while (elm->type == e) { + elm = stackPop(stack); + n++; + } + stackPush(stack, elm); // push ListElement back to stack + array = (Element**)stackLastPopedAsArray0(stack, n); // NULL terminated list + if (getAstNodeType(elm->type)!=astListElement) return; // failure + ((ListElement*)elm)->list = array; + return; // success only if list!=NULL +} + +// Pop the children from the stack and +// check for correct type and sequence of children +static void XMLCALL endElement(void *context, const char *elm) { + Elm el; + el = checkElement(elm); + switch(el) { + case elm_fmiModelDescription: + { + ModelDescription* md; + ListElement** ud = NULL; // NULL or list of BaseUnits + Type** td = NULL; // NULL or list of Types + Element* de = NULL; // NULL or DefaultExperiment + ListElement** va = NULL; // NULL or list of Tools + ScalarVariable** mv = NULL; // NULL or list of ScalarVariable + CoSimulation *cs = NULL; // NULL or CoSimulation + ListElement* child; + + child = checkPop(ANY_TYPE); + if (child->type == elm_CoSimulation_StandAlone || child->type == elm_CoSimulation_Tool) { + cs = (CoSimulation*)child; + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_ModelVariables){ + mv = (ScalarVariable**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_VendorAnnotations){ + va = (ListElement**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_DefaultExperiment){ + de = (Element*)child; + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_TypeDefinitions){ + td = (Type**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_UnitDefinitions){ + ud = (ListElement**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + // work around bug of SimulationX 3.4 and 3.5 which places Implementation at wrong location + if (!cs && (child->type == elm_CoSimulation_StandAlone || child->type == elm_CoSimulation_Tool)) { + cs = (CoSimulation*)child; + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (!checkElementType(child, elm_fmiModelDescription)) return; + md = (ModelDescription*)child; + md->modelVariables = mv; + md->vendorAnnotations = va; + md->defaultExperiment = de; + md->typeDefinitions = td; + md->unitDefinitions = ud; + md->cosimulation = cs; + stackPush(stack, md); + break; + } + case elm_Implementation: + { + // replace Implementation element + void* cs = checkPop(ANY_TYPE); + void* im = checkPop(elm_Implementation); + stackPush(stack, cs); + free(im); + el = ((Element*)cs)->type; + break; + } + case elm_CoSimulation_StandAlone: + { + Element* ca = checkPop(elm_Capabilities); + CoSimulation* cs = checkPop(elm_CoSimulation_StandAlone); + if (!ca || !cs) return; + cs->capabilities = ca; + stackPush(stack, cs); + break; + } + case elm_CoSimulation_Tool: + { + ListElement* mo = checkPop(elm_Model); + Element* ca = checkPop(elm_Capabilities); + CoSimulation* cs = checkPop(elm_CoSimulation_Tool); + if (!ca || !mo || !cs) return; + cs->capabilities = ca; + cs->model = mo; + stackPush(stack, cs); + break; + } + case elm_Type: + { + Type* tp; + Element* ts = checkPop(ANY_TYPE); + if (!ts) return; + if (!checkPeek(elm_Type)) return; + tp = (Type*)stackPeek(stack); + switch (ts->type) { + case elm_RealType: + case elm_IntegerType: + case elm_BooleanType: + case elm_StringType: + case elm_EnumerationType: + break; + default: + logFatalTypeError("RealType or similar", ts->type); + return; + } + tp->typeSpec = ts; + break; + } + case elm_ScalarVariable: + { + ScalarVariable* sv; + Element** list = NULL; + Element* child = checkPop(ANY_TYPE); + if (!child) return; + if (child->type==elm_DirectDependency){ + list = ((ListElement*)child)->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (!checkPeek(elm_ScalarVariable)) return; + sv = (ScalarVariable*)stackPeek(stack); + switch (child->type) { + case elm_Real: + case elm_Integer: + case elm_Boolean: + case elm_String: + case elm_Enumeration: + break; + default: + logFatalTypeError("Real or similar", child->type); + return; + } + sv->directDependencies = list; + sv->typeSpec = child; + break; + } + case elm_ModelVariables: popList(elm_ScalarVariable); break; + case elm_VendorAnnotations: popList(elm_Tool);break; + case elm_Tool: popList(elm_Annotation); break; + case elm_TypeDefinitions: popList(elm_Type); break; + case elm_EnumerationType: popList(elm_Item); break; + case elm_UnitDefinitions: popList(elm_BaseUnit); break; + case elm_BaseUnit: popList(elm_DisplayUnitDefinition); break; + case elm_DirectDependency: popList(elm_Name); break; + case elm_Model: popList(elm_File); break; + case elm_Name: + { + // Exception: the name value is represented as element content. + // All other values of the XML file are represented using attributes. + Element* name = checkPop(elm_Name); + if (!name) return; + name->n = 2; + name->attributes = malloc(2*sizeof(char*)); + name->attributes[0] = attNames[att_input]; + name->attributes[1] = data; + data = NULL; + skipData = 1; // stop recording element content + stackPush(stack, name); + break; + } + case -1: return; // illegal element error + default: // must be a leaf Element + assert(getAstNodeType(el)==astElement); + break; + } + // All children of el removed from the stack. + // The top element must be of type el now. + checkPeek(el); +} + +// Called to handle element data, e.g. "xy" in xy +// Can be called many times, e.g. with "x" and then with "y" in the example above. +// Feature in expat: +// For some reason, if the element data is the empty string (Eg. ) +// instead of an empty string with len == 0 we get "\n". The workaround is +// to replace this with the empty string whenever we encounter "\n". +void XMLCALL handleData(void *context, const XML_Char *s, int len) { + int n; + if (skipData) return; + if (!data) { + // start a new data string + if (len == 1 && s[0] == '\n') { + data = strdup(""); + } else { + data = malloc(len + 1); + strncpy(data, s, len); + data[len] = '\0'; + } + } + else { + // continue existing string + n = strlen(data) + len; + data = realloc(data, n+1); + strncat(data, s, len); + data[n] = '\0'; + } + return; +} + +// ------------------------------------------------------------------------- +// printing + +static void printList(int indent, void** list); + +void printElement(int indent, void* element){ + int i; + Element* e = (Element*)element; + if (!e) return; + // print attributes + for (i=0; itype]); + for (i=0; in; i+=2) + printf(" %s=%s", e->attributes[i], e->attributes[i+1]); + printf("\n"); + // print child nodes + indent += 2; + switch (getAstNodeType(e->type)) { + case astListElement: + printList(indent, ((ListElement*)e)->list); + break; + case astScalarVariable: + printElement(indent, ((Type*)e)->typeSpec); + printList(indent, ((ScalarVariable*)e)->directDependencies); + break; + case astType: + printElement(indent, ((Type*)e)->typeSpec); + break; + case astCoSimulation: { + CoSimulation* cs = (CoSimulation*)e; + printElement(indent, cs->capabilities); + printElement(indent, cs->model); + break; + } + case astModelDescription: { + ModelDescription *md = (ModelDescription*)e; + printList(indent, md->unitDefinitions); + printList(indent, md->typeDefinitions); + printElement(indent, md->defaultExperiment); + printList(indent, md->vendorAnnotations); + printList(indent, md->modelVariables); + printElement(indent, md->cosimulation); + break; + } + } +} + +static void printList(int indent, void** list){ + int i; + if (list) for (i=0; list[i]; i++) + printElement(indent, list[i]); +} + +// ------------------------------------------------------------------------- +// free memory of the AST + +static void freeList(void** list); + +void freeElement(void* element){ + int i; + Element* e = (Element*)element; + if (!e) return; + // free attributes + for (i=0; in; i+=2) + free(e->attributes[i+1]); + if (e->attributes) free(e->attributes); + // free child nodes + switch (getAstNodeType(e->type)) { + case astListElement: + freeList(((ListElement*)e)->list); + break; + case astScalarVariable: + freeList(((ScalarVariable*)e)->directDependencies); + case astType: + freeElement(((Type*)e)->typeSpec); + break; + case astCoSimulation: { + CoSimulation* cs = (CoSimulation*)e; + freeElement(cs->capabilities); + freeElement(cs->model); + break; + } + case astModelDescription: { + ModelDescription* md = (ModelDescription*)e; + freeList(md->unitDefinitions); + freeList(md->typeDefinitions); + freeElement(md->defaultExperiment); + freeList(md->vendorAnnotations); + freeList(md->modelVariables); + freeElement(md->cosimulation); + break; + } + } + // free the struct + free(e); +} + +static void freeList(void** list){ + int i; + if (!list) return; + for (i=0; list[i]; i++) + freeElement(list[i]); + free(list); +} + +// ------------------------------------------------------------------------- +// Validation - done after parsing to report all errors + +ModelDescription* validate(ModelDescription* md) { + int error = 0; + int i; + if (md->modelVariables) + for (i=0; md->modelVariables[i]; i++){ + ScalarVariable* sv = (ScalarVariable*)md->modelVariables[i]; + char* declaredType = getString(sv->typeSpec, att_declaredType); + Type* decltype = getDeclaredType(md, declaredType); + if (declaredType && decltype==NULL) { + printf("Warning: Declared type %s of variable %s not found in modelDescription.xml\n", declaredType, getName(sv)); + error++; + } + } + if (error) { + printf("Error: Found %d error in modelDescription.xml\n", error); + return NULL; + } + return md; +} + +// ------------------------------------------------------------------------- +// Entry function parse() of the XML parser + +static void cleanup(FILE *file) { + stackFree(stack); + stack = NULL; + XML_ParserFree(parser); + parser = NULL; + fclose(file); +} + +// Returns NULL to indicate failure +// Otherwise, return the root node md of the AST. +// The receiver must call freeElement(md) to release AST memory. +ModelDescription* parse(const char* xmlPath) { + ModelDescription* md = NULL; + FILE *file; + int done = 0; + stack = stackNew(100, 10); + if (!checkPointer(stack)) return NULL; // failure + parser = XML_ParserCreate(NULL); + if (!checkPointer(parser)) return NULL; // failure + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, handleData); + file = fopen(xmlPath, "rb"); + if (file == NULL) { + printf("Cannot open file '%s'\n", xmlPath); + XML_ParserFree(parser); + return NULL; // failure + } + while (!done) { + int n = fread(text, sizeof(char), XMLBUFSIZE, file); + if (n != XMLBUFSIZE) done = 1; + if (!XML_Parse(parser, text, n, done)){ + printf("Parse error in file %s at line %d:\n%s\n", + xmlPath, + XML_GetCurrentLineNumber(parser), + XML_ErrorString(XML_GetErrorCode(parser))); + while (! stackIsEmpty(stack)) md = stackPop(stack); + if (md) freeElement(md); + cleanup(file); + return NULL; // failure + } + } + md = stackPop(stack); + assert(stackIsEmpty(stack)); + cleanup(file); + //printElement(1, md); // debug + return validate(md); // success if all refs are valid +} + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/xml_parser.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/xml_parser.h new file mode 100644 index 00000000..0730d56b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src _original/shared/xml_parser.h @@ -0,0 +1,159 @@ +/* ------------------------------------------------------------------------- + * xml_parser.h + * A parser for file modelVariables.xml of an FMU. + * Supports "FMI for Model Exchange 1.0" and "FMI for Co-Simulation 1.0". + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#ifndef xml_parser_h +#define xml_parser_h + +// define XML_STATIC before including expat.h +// to prevent error when linking with libexpatMT.lib +#define XML_STATIC +#include "expat.h" +#include "stack.h" + +typedef unsigned int fmiValueReference; +#define fmiUndefinedValueReference (fmiValueReference)(-1) + +#define SIZEOF_ELM 31 +extern const char *elmNames[SIZEOF_ELM]; + +#define SIZEOF_ATT 47 +extern const char *attNames[SIZEOF_ATT]; + +#define SIZEOF_ENU 13 +extern const char *enuNames[SIZEOF_ENU]; + +// Elements +typedef enum { + elm_fmiModelDescription,elm_UnitDefinitions,elm_BaseUnit,elm_DisplayUnitDefinition,elm_TypeDefinitions, + elm_Type,elm_RealType,elm_IntegerType,elm_BooleanType,elm_StringType,elm_EnumerationType,elm_Item, + elm_DefaultExperiment,elm_VendorAnnotations,elm_Tool,elm_Annotation,elm_ModelVariables,elm_ScalarVariable, + elm_DirectDependency,elm_Name,elm_Real,elm_Integer,elm_Boolean,elm_String,elm_Enumeration, + elm_Implementation,elm_CoSimulation_StandAlone,elm_CoSimulation_Tool,elm_Model,elm_File,elm_Capabilities +} Elm; + +// Attributes +typedef enum { + att_fmiVersion,att_displayUnit,att_gain,att_offset,att_unit,att_name,att_description,att_quantity,att_relativeQuantity, + att_min,att_max,att_nominal,att_declaredType,att_start,att_fixed,att_startTime,att_stopTime,att_tolerance,att_value, + att_valueReference,att_variability,att_causality,att_alias,att_modelName,att_modelIdentifier,att_guid,att_author, + att_version,att_generationTool,att_generationDateAndTime,att_variableNamingConvention,att_numberOfContinuousStates, + att_numberOfEventIndicators,att_input, + att_canHandleVariableCommunicationStepSize,att_canHandleEvents,att_canRejectSteps,att_canInterpolateInputs, + att_maxOutputDerivativeOrder,att_canRunAsynchronuously,att_canSignalEvents,att_canBeInstantiatedOnlyOncePerProcess, + att_canNotUseMemoryManagementFunctions,att_entryPoint,att_manualStart,att_type +} Att; + +// Enumeration values +typedef enum { + enu_flat,enu_structured,enu_constant,enu_parameter,enu_discrete,enu_continuous, + enu_input,enu_output,enu_internal,enu_none,enu_noAlias,enu_alias,enu_negatedAlias +} Enu; + +// AST node for element +// DisplayUnitDefinition, RealType, IntegerType, BooleanType, StringType, DefaultExperiment, +// Item, Annotation, Name, Real, Integer, Boolean, String, Enumeration, Capabilities, File +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number +} Element; + +// AST node for element that has a list of elements +// BaseUnit, EnumerationType, Tool, DirectDependency, Model +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + Element** list; // null-terminated array of pointers to elements, not null +} ListElement; + +// AST node for element Type +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, an even number + Element* typeSpec; // one of RealType, IntegerType etc. +} Type; + +// AST node for element ScalarVariable +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + Element* typeSpec; // one of Real, Integer, etc + Element** directDependencies; // null or null-terminated list of Name +} ScalarVariable; + +// AST node for element CoSimulation_StandAlone and CoSimulation_Tool +typedef struct { + Elm type; // one of elm_CoSimulation_StandAlone and elm_CoSimulation_Tool + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + Element* capabilities; // a set of capability attributes + ListElement* model; // non-NULL to support tool coupling, NULL for standalone +} CoSimulation; + +// AST node for element ModelDescription +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + ListElement** unitDefinitions; // NULL or null-terminated list of BaseUnits + Type** typeDefinitions; // NULL or null-terminated list of Types + Element* defaultExperiment; // NULL or DefaultExperiment + ListElement** vendorAnnotations; // NULL or null-terminated list of Tools + ScalarVariable** modelVariables; // NULL or null-terminated list of ScalarVariable + CoSimulation* cosimulation; // NULL if this ModelDescription is for model exchange only +} ModelDescription; + +// types of AST nodes used to represent an element +typedef enum { + astElement, + astListElement, + astType, + astScalarVariable, + astCoSimulation, + astModelDescription +} AstNodeType; + +// Possible results when retrieving an attribute value from an element +typedef enum { + valueMissing, + valueDefined, + valueIllegal +} ValueStatus; + +// Public methods: Parsing and low-level AST access +ModelDescription* parse(const char* xmlPath); +const char* getString(void* element, Att a); +double getDouble (void* element, Att a, ValueStatus* vs); +int getInt (void* element, Att a, ValueStatus* vs); +unsigned int getUInt (void* element, Att a, ValueStatus* vs); +char getBoolean (void* element, Att a, ValueStatus* vs); +Enu getEnumValue (void* element, Att a, ValueStatus* vs); +void freeElement (void* element); + +// Convenience methods for AST access. To be used afer successful validation only. +const char* getModelIdentifier(ModelDescription* md); +int getNumberOfStates(ModelDescription* md); +int getNumberOfEventIndicators(ModelDescription* md); +const char* getName(void* element); +Enu getCausality(void* scalarVariable); +Enu getVariability(void* scalarVariable); +Enu getAlias(void* scalarVariable); +fmiValueReference getValueReference(void* scalarVariable); +ScalarVariable* getVariableByName(ModelDescription* md, const char* name); +ScalarVariable* getVariable(ModelDescription* md, fmiValueReference vr, Elm type); +Type* getDeclaredType(ModelDescription* md, const char* declaredType); +const char* getString2(ModelDescription* md, void* sv, Att a); +const char * getDescription(ModelDescription* md, ScalarVariable* sv); +const char * getVariableAttributeString(ModelDescription* md, fmiValueReference vr, Elm type, Att a); +double getVariableAttributeDouble(ModelDescription* md, fmiValueReference vr, Elm type, Att a, ValueStatus* vs); +double getNominal(ModelDescription* md, fmiValueReference vr); + +#endif // xml_parser_h + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/build_all.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/build_all.bat new file mode 100644 index 00000000..cdd75152 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/build_all.bat @@ -0,0 +1,28 @@ +@echo off + +rem ------------------------------------------------------------ +rem This batch builds both simulators and all FMUs of the FmuSDK +rem (c) 2011 QTronic GmbH +rem ------------------------------------------------------------ + +call build_fmusim_me +call build_fmusim_cs +echo ----------------------------------------------------------- +echo Making the FMUs of the FmuSDK ... +pushd models + +call build_fmu me dq +call build_fmu me inc +call build_fmu me values +call build_fmu me vanDerPol +call build_fmu me bouncingBall + +call build_fmu cs dq +call build_fmu cs inc +call build_fmu cs values +call build_fmu cs vanDerPol +call build_fmu cs bouncingBall + +popd + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/build_fmusim_cs.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/build_fmusim_cs.bat new file mode 100644 index 00000000..6e90292c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/build_fmusim_cs.bat @@ -0,0 +1,48 @@ +@echo off +rem ------------------------------------------------------------ +rem This batch builds the FMU simulator fmusim_cs.exe +rem (c) 2011 QTronic GmbH +rem ------------------------------------------------------------ + +echo ----------------------------------------------------------- +echo building fmusim_cs.exe - FMI for Co-Simulation 1.0 +echo ----------------------------------------------------------- + +rem save env variable settings +set PREV_PATH=%PATH% +if defined INCLUDE set PREV_INCLUDE=%INLUDE% +if defined LIB set PREV_LIB=%LIB% +if defined LIBPATH set PREV_LIBPATH=%LIBPATH% + +rem setup the compiler +if defined VS90COMNTOOLS (call "%VS90COMNTOOLS%\vsvars32.bat") else ^ +if defined VS80COMNTOOLS (call "%VS80COMNTOOLS%\vsvars32.bat") else ^ +goto noCompiler + +set SRC=fmusim_cs\main.c ..\shared\xml_parser.c ..\shared\stack.c ..\shared\sim_support.c +set INC=/Iinclude /I../shared /Ifmusim_cs +set OPTIONS=/DFMI_COSIMULATION /wd4090 /nologo + +rem create fmusim_cs.exe in the fmusim_cs dir +rem /wd4090 to disable warnings about different 'const' qualifiers +pushd co_simulation +cl %SRC% %INC% %OPTIONS% /Fefmusim_cs.exe /link ..\shared\libexpatMT.lib +del *.obj +popd +if not exist co_simulation\fmusim_cs.exe goto compileError +move /Y co_simulation\fmusim_cs.exe ..\bin +goto done + +:noCompiler +echo No Microsoft Visual C compiler found + +:compileError +echo build of fmusim_cs.exe failed + +:done +rem undo variable settings performed by vsvars32.bat +set PATH=%PREV_PATH% +if defined PREV_INCLUDE set INCLUDE=%PREV_INLUDE% +if defined PREV_LIB set LIB=%PREV_LIB% +if defined PREV_LIBPATH set LIBPATH=%PREV_LIBPATH% +echo done. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/build_fmusim_me.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/build_fmusim_me.bat new file mode 100644 index 00000000..0828428b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/build_fmusim_me.bat @@ -0,0 +1,51 @@ +@echo off +rem ------------------------------------------------------------ +rem This batch builds the FMU simulator fmusim_me.exe +rem (c) 2011 QTronic GmbH +rem ------------------------------------------------------------ + +echo ----------------------------------------------------------- +echo building fmusim_me.exe - FMI for Model Exchange 1.0 +echo ----------------------------------------------------------- + +rem save env variable settings +set PREV_PATH=%PATH% +if defined INCLUDE set PREV_INCLUDE=%INLUDE% +if defined LIB set PREV_LIB=%LIB% +if defined LIBPATH set PREV_LIBPATH=%LIBPATH% + +rem setup the compiler +if defined VS90COMNTOOLS (call "%VS90COMNTOOLS%\vsvars32.bat") else ^ +if defined VS80COMNTOOLS (call "%VS80COMNTOOLS%\vsvars32.bat") else ^ +goto noCompiler + +set SRC=fmusim_me\main.c ..\shared\xml_parser.c ..\shared\stack.c ..\shared\sim_support.c +set INC=/Iinclude /I../shared /Ifmusim_me +set OPTIONS=/wd4090 /nologo + +rem create fmusim_me.exe in the fmusim_me dir +rem /wd4090 to disable warnings about different 'const' qualifiers +pushd model_exchange +cl %SRC% %INC% %OPTIONS% /Fefmusim_me.exe /link ..\shared\libexpatMT.lib +del *.obj +popd +if not exist model_exchange\fmusim_me.exe goto compileError +move /Y model_exchange\fmusim_me.exe ..\bin +goto done + +:noCompiler +echo No Microsoft Visual C compiler found + +:compileError +echo build of fmusim_me.exe failed + +:done +rem undo variable settings performed by vsvars32.bat +set PATH=%PREV_PATH% +if defined PREV_INCLUDE set INCLUDE=%PREV_INLUDE% +if defined PREV_LIB set LIB=%PREV_LIB% +if defined PREV_LIBPATH set LIBPATH=%PREV_LIBPATH% +echo done. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/fmusim_cs/fmi_cs.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/fmusim_cs/fmi_cs.h new file mode 100644 index 00000000..f446eac1 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/fmusim_cs/fmi_cs.h @@ -0,0 +1,78 @@ +/* ------------------------------------------------------------------------- + * fmi_cs.h + * Function types for all function of the "FMI for Co-Simulation 1.0" + * and a struct with the corresponding function pointers. + * Copyright 2011 QTronic GmbH. All rights reserved. + * ------------------------------------------------------------------------- + */ + +#ifndef FMI_CS_H +#define FMI_CS_H + +#include +#include "fmiFunctions.h" +#include "xml_parser.h" + +typedef const char* (*fGetTypesPlatform)(); +typedef const char* (*fGetVersion)(); +typedef fmiStatus (*fSetDebugLogging) (fmiComponent c, fmiBoolean loggingOn); +typedef fmiStatus (*fSetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); +typedef fmiStatus (*fSetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); +typedef fmiStatus (*fSetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); +typedef fmiStatus (*fSetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); +typedef fmiStatus (*fGetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); +typedef fmiStatus (*fGetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); +typedef fmiStatus (*fGetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); +typedef fmiStatus (*fGetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); +typedef fmiComponent (*fInstantiateSlave) (fmiString instanceName, fmiString fmuGUID, fmiString fmuLocation, + fmiString mimeType, fmiReal timeout, fmiBoolean visible, fmiBoolean interactive, + fmiCallbackFunctions functions, fmiBoolean loggingOn); +typedef fmiStatus (*fInitializeSlave)(fmiComponent c, fmiReal tStart, fmiBoolean StopTimeDefined, fmiReal tStop); +typedef fmiStatus (*fTerminateSlave) (fmiComponent c); +typedef fmiStatus (*fResetSlave) (fmiComponent c); +typedef void (*fFreeSlaveInstance)(fmiComponent c); +typedef fmiStatus (*fSetRealInputDerivatives)(fmiComponent c, const fmiValueReference vr[], size_t nvr, + const fmiInteger order[], const fmiReal value[]); +typedef fmiStatus (*fGetRealOutputDerivatives)(fmiComponent c, const fmiValueReference vr[], size_t nvr, + const fmiInteger order[], fmiReal value[]); +typedef fmiStatus (*fCancelStep)(fmiComponent c); +typedef fmiStatus (*fDoStep)(fmiComponent c, fmiReal currentCommunicationPoint, + fmiReal communicationStepSize, fmiBoolean newStep); +typedef fmiStatus (*fGetStatus) (fmiComponent c, const fmiStatusKind s, fmiStatus* value); +typedef fmiStatus (*fGetRealStatus) (fmiComponent c, const fmiStatusKind s, fmiReal* value); +typedef fmiStatus (*fGetIntegerStatus)(fmiComponent c, const fmiStatusKind s, fmiInteger* value); +typedef fmiStatus (*fGetBooleanStatus)(fmiComponent c, const fmiStatusKind s, fmiBoolean* value); +typedef fmiStatus (*fGetStringStatus) (fmiComponent c, const fmiStatusKind s, fmiString* value); + +typedef struct { + ModelDescription* modelDescription; + HANDLE dllHandle; + fGetTypesPlatform getTypesPlatform; + fGetVersion getVersion; + fSetDebugLogging setDebugLogging; + fSetReal setReal; + fSetInteger setInteger; + fSetBoolean setBoolean; + fSetString setString; + fGetReal getReal; + fGetInteger getInteger; + fGetBoolean getBoolean; + fGetString getString; + fInstantiateSlave instantiateSlave; + fInitializeSlave initializeSlave; + fTerminateSlave terminateSlave; + fResetSlave resetSlave; + fFreeSlaveInstance freeSlaveInstance; + fGetRealOutputDerivatives getRealOutputDerivatives; + fSetRealInputDerivatives setRealInputDerivatives; + fDoStep doStep; + fCancelStep cancelStep; + fGetStatus getStatus; + fGetRealStatus getRealStatus; + fGetIntegerStatus getIntegerStatus; + fGetBooleanStatus getBooleanStatus; + fGetStringStatus getStringStatus; +} FMU; + +#endif // FMI_CS_H + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/fmusim_cs/main.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/fmusim_cs/main.c new file mode 100644 index 00000000..f0673d11 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/fmusim_cs/main.c @@ -0,0 +1,127 @@ +/* ------------------------------------------------------------------------- + * main.c + * Implements simulation of a single FMU instance + * that implements the "FMI for Co-Simulation 1.0" interface. + * Command syntax: see printHelp() + * Simulates the given FMU from t = 0 .. tEnd with fixed step size h and + * writes the computed solution to file 'result.csv'. + * The CSV file (comma-separated values) may e.g. be plotted using + * OpenOffice Calc or Microsoft Excel. + * This progamm demonstrates basic use of an FMU. + * Real applications may use advanced master algorithms to cosimulate + * many FMUs, limit the numerical error using error estimation + * and back-stepping, provide graphical plotting utilities, debug support, + * and user control of parameter and start values, or perform a clean + * error handling (e.g. call freeSlaveInstance when a call to the fmu + * returns with error). All this is missing here. + * + * Revision history + * 22.08.2011 initial version released in FMU SDK 1.0.2 + * + * Free libraries and tools used to implement this simulator: + * - header files from the FMU specification + * - eXpat 2.0.1 XML parser, see http://expat.sourceforge.net + * - 7z.exe 4.57 zip and unzip tool, see http://www.7-zip.org + * Author: Jakob Mauss + * Copyright 2011 QTronic GmbH. All rights reserved. + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include "fmi_cs.h" +#include "sim_support.h" + +FMU fmu; // the fmu to simulate + +// simulate the given FMU using the forward euler method. +// time events are processed by reducing step size to exactly hit tNext. +// state events are checked and fired only at the end of an Euler step. +// the simulator may therefore miss state events and fires state events typically too late. +static int simulate(FMU* fmu, double tEnd, double h, fmiBoolean loggingOn, char separator) { + double time; + double tStart = 0; // start time + const char* guid; // global unique id of the fmu + fmiComponent c; // instance of the fmu + fmiStatus fmiFlag; // return code of the fmu functions + const char* fmuLocation = NULL; // path to the fmu as URL, "file://C:\QTronic\sales" + const char* mimeType = "application/x-fmu-sharedlibrary"; // denotes tool in case of tool coupling + fmiReal timeout = 1000; // wait period in milli seconds, 0 for unlimited wait period" + fmiBoolean visible = fmiFalse; // no simulator user interface + fmiBoolean interactive = fmiFalse; // simulation run without user interaction + fmiCallbackFunctions callbacks; // called by the model during simulation + ModelDescription* md; // handle to the parsed XML file + int nSteps = 0; + FILE* file; + + // instantiate the fmu + md = fmu->modelDescription; + guid = getString(md, att_guid); + callbacks.logger = fmuLogger; + callbacks.allocateMemory = calloc; + callbacks.freeMemory = free; + callbacks.stepFinished = NULL; // fmiDoStep has to be carried out synchronously + c = fmu->instantiateSlave(getModelIdentifier(md), guid, fmuLocation, mimeType, + timeout, visible, interactive, callbacks, loggingOn); + if (!c) return error("could not instantiate model"); + + // open result file + if (!(file=fopen(RESULT_FILE, "w"))) { + printf("could not write %s because:\n", RESULT_FILE); + printf(" %s\n", strerror(errno)); + return 0; // failure + } + + // StopTimeDefined=fmiFalse means: ignore value of tEnd + fmiFlag = fmu->initializeSlave(c, tStart, fmiTrue, tEnd); + if (fmiFlag > fmiWarning) return error("could not initialize model"); + + // output solution for time t0 + outputRow(fmu, c, tStart, file, separator, TRUE); // output column names + outputRow(fmu, c, tStart, file, separator, FALSE); // output values + + // enter the simulation loop + time = tStart; + while (time < tEnd) { + fmiFlag = fmu->doStep(c, time, h, fmiTrue); + if (fmiFlag != fmiOK) return error("could not complete simulation of the model"); + time += h; + outputRow(fmu, c, time, file, separator, FALSE); // output values for this step + nSteps++; + } + + // end simulation + fmiFlag = fmu->terminateSlave(c); + fmu->freeSlaveInstance(c); + + // print simulation summary + printf("Simulation from %g to %g terminated successful\n", tStart, tEnd); + printf(" steps ............ %d\n", nSteps); + printf(" fixed step size .. %g\n", h); + return 1; // success +} + +int main(int argc, char *argv[]) { + const char* fmuFileName; + + // parse command line arguments and load the FMU + double tEnd = 1.0; + double h=0.1; + int loggingOn = 0; + char csv_separator = ';'; + parseArguments(argc, argv, &fmuFileName, &tEnd, &h, &loggingOn, &csv_separator); + loadFMU(fmuFileName); + + // run the simulation + printf("FMU Simulator: run '%s' from t=0..%g with step size h=%g, loggingOn=%d, csv separator='%c'\n", + fmuFileName, tEnd, h, loggingOn, csv_separator); + simulate(&fmu, tEnd, h, loggingOn, csv_separator); + printf("CSV file '%s' written\n", RESULT_FILE); + + // release FMU + FreeLibrary(fmu.dllHandle); + freeElement(fmu.modelDescription); + return EXIT_SUCCESS; +} + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/include/fmiFunctions.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/include/fmiFunctions.h new file mode 100644 index 00000000..f4341025 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/include/fmiFunctions.h @@ -0,0 +1,231 @@ +#ifndef fmiFunctions_h +#define fmiFunctions_h + +/* This header file must be utilized when compiling a FMU. + It defines all functions of Co-Simulation Interface. + In order to have unique function names even if several FMUs + are compiled together (e.g. for embedded systems), every "real" function name + is constructed by prepending the function name by + "MODEL_IDENTIFIER" + "_" where "MODEL_IDENTIFIER" is the short name + of the model used as the name of the zip-file where the model is stored. + Therefore, the typical usage is: + + #define MODEL_IDENTIFIER MyModel + #include "fmiFunctions.h" + + As a result, a function that is defined as "fmiGetDerivatives" in this header file, + is actually getting the name "MyModel_fmiGetDerivatives". + + Revisions: + - November 4, 2010: Adapted to specification text: + o fmiGetModelTypesPlatform renamed to fmiGetTypesPlatform + o fmiInstantiateSlave: Argument GUID replaced by fmuGUID + Argument mimetype replaced by mimeType + o tabs replaced by spaces + - October 16, 2010: First public Version + + + Copyright © 2008-2010, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html): + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- +*/ + +#include "fmiPlatformTypes.h" +#include + +/* Export fmi functions on Windows */ +#ifdef _MSC_VER +#define DllExport __declspec( dllexport ) +#else +#define DllExport +#endif + +/* Macros to construct the real function name + (prepend function name by MODEL_IDENTIFIER + "_") */ + +#define fmiPaste(a,b) a ## b +#define fmiPasteB(a,b) fmiPaste(a,b) +#define fmiFullName(name) fmiPasteB(MODEL_IDENTIFIER, name) + +/*************************************************** +Common Functions +****************************************************/ +#define fmiGetTypesPlatform fmiFullName(_fmiGetTypesPlatform) +#define fmiGetVersion fmiFullName(_fmiGetVersion) +#define fmiSetDebugLogging fmiFullName(_fmiSetDebugLogging) + +/*Data Exchange*/ +#define fmiSetReal fmiFullName(_fmiSetReal) +#define fmiSetInteger fmiFullName(_fmiSetInteger) +#define fmiSetBoolean fmiFullName(_fmiSetBoolean) +#define fmiSetString fmiFullName(_fmiSetString) + +#define fmiGetReal fmiFullName(_fmiGetReal) +#define fmiGetInteger fmiFullName(_fmiGetInteger) +#define fmiGetBoolean fmiFullName(_fmiGetBoolean) +#define fmiGetString fmiFullName(_fmiGetString) + +/*************************************************** +Functions for FMI for Co-Simulation +****************************************************/ +#define fmiInstantiateSlave fmiFullName(_fmiInstantiateSlave) +#define fmiInitializeSlave fmiFullName(_fmiInitializeSlave) +#define fmiTerminateSlave fmiFullName(_fmiTerminateSlave) +#define fmiResetSlave fmiFullName(_fmiResetSlave) +#define fmiFreeSlaveInstance fmiFullName(_fmiFreeSlaveInstance) +#define fmiSetRealInputDerivatives fmiFullName(_fmiSetRealInputDerivatives) +#define fmiGetRealOutputDerivatives fmiFullName(_fmiGetRealOutputDerivatives) +#define fmiDoStep fmiFullName(_fmiDoStep) +#define fmiCancelStep fmiFullName(_fmiCancelStep) +#define fmiGetStatus fmiFullName(_fmiGetStatus) +#define fmiGetRealStatus fmiFullName(_fmiGetRealStatus) +#define fmiGetIntegerStatus fmiFullName(_fmiGetIntegerStatus) +#define fmiGetBooleanStatus fmiFullName(_fmiGetBooleanStatus) +#define fmiGetStringStatus fmiFullName(_fmiGetStringStatus) + +/* Version number */ +#define fmiVersion "1.0" + +/* make sure all compiler use the same alignment policies for structures */ +#ifdef WIN32 +#pragma pack(push,8) +#endif + + +/* Type definitions */ + typedef enum {fmiOK, + fmiWarning, + fmiDiscard, + fmiError, + fmiFatal, + fmiPending} fmiStatus; + + typedef void (*fmiCallbackLogger) (fmiComponent c, fmiString instanceName, fmiStatus status, + fmiString category, fmiString message, ...); + typedef void* (*fmiCallbackAllocateMemory)(size_t nobj, size_t size); + typedef void (*fmiCallbackFreeMemory) (void* obj); + typedef void (*fmiStepFinished) (fmiComponent c, fmiStatus status); + + typedef struct { + fmiCallbackLogger logger; + fmiCallbackAllocateMemory allocateMemory; + fmiCallbackFreeMemory freeMemory; + fmiStepFinished stepFinished; + } fmiCallbackFunctions; + + typedef struct { + fmiBoolean iterationConverged; + fmiBoolean stateValueReferencesChanged; + fmiBoolean stateValuesChanged; + fmiBoolean terminateSimulation; + fmiBoolean upcomingTimeEvent; + fmiReal nextEventTime; + } fmiEventInfo; + +/* reset alignment policy to the one set before reading this file */ +#ifdef WIN32 +#pragma pack(pop) +#endif + +/*************************************************** +Common Functions +****************************************************/ + +/* Inquire version numbers of header files */ + DllExport const char* fmiGetTypesPlatform(); + DllExport const char* fmiGetVersion(); + + DllExport fmiStatus fmiSetDebugLogging (fmiComponent c, fmiBoolean loggingOn); + +/* Data Exchange Functions*/ + DllExport fmiStatus fmiGetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); + DllExport fmiStatus fmiGetInteger(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); + DllExport fmiStatus fmiGetBoolean(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); + DllExport fmiStatus fmiGetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); + + DllExport fmiStatus fmiSetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); + DllExport fmiStatus fmiSetInteger (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); + DllExport fmiStatus fmiSetBoolean (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); + DllExport fmiStatus fmiSetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); + +/*************************************************** +Functions for FMI for Co-Simulation +****************************************************/ + +/* Creation and destruction of slave instances and setting debug status */ + DllExport fmiComponent fmiInstantiateSlave(fmiString instanceName, + fmiString fmuGUID, + fmiString fmuLocation, + fmiString mimeType, + fmiReal timeout, + fmiBoolean visible, + fmiBoolean interactive, + fmiCallbackFunctions functions, + fmiBoolean loggingOn); + + DllExport fmiStatus fmiInitializeSlave(fmiComponent c, + fmiReal tStart, + fmiBoolean StopTimeDefined, + fmiReal tStop); + + DllExport fmiStatus fmiTerminateSlave (fmiComponent c); + DllExport fmiStatus fmiResetSlave (fmiComponent c); + DllExport void fmiFreeSlaveInstance(fmiComponent c); + + DllExport fmiStatus fmiSetRealInputDerivatives(fmiComponent c, + const fmiValueReference vr[], + size_t nvr, + const fmiInteger order[], + const fmiReal value[]); + + DllExport fmiStatus fmiGetRealOutputDerivatives(fmiComponent c, + const fmiValueReference vr[], + size_t nvr, + const fmiInteger order[], + fmiReal value[]); + + DllExport fmiStatus fmiCancelStep(fmiComponent c); + DllExport fmiStatus fmiDoStep (fmiComponent c, + fmiReal currentCommunicationPoint, + fmiReal communicationStepSize, + fmiBoolean newStep); + + + typedef enum {fmiDoStepStatus, + fmiPendingStatus, + fmiLastSuccessfulTime} fmiStatusKind; + + DllExport fmiStatus fmiGetStatus (fmiComponent c, const fmiStatusKind s, fmiStatus* value); + DllExport fmiStatus fmiGetRealStatus (fmiComponent c, const fmiStatusKind s, fmiReal* value); + DllExport fmiStatus fmiGetIntegerStatus(fmiComponent c, const fmiStatusKind s, fmiInteger* value); + DllExport fmiStatus fmiGetBooleanStatus(fmiComponent c, const fmiStatusKind s, fmiBoolean* value); + DllExport fmiStatus fmiGetStringStatus (fmiComponent c, const fmiStatusKind s, fmiString* value); + + +#endif // fmiFunctions_h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/include/fmiPlatformTypes.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/include/fmiPlatformTypes.h new file mode 100644 index 00000000..7916f792 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/co_simulation/include/fmiPlatformTypes.h @@ -0,0 +1,73 @@ +#ifndef fmiPlatformTypes_h +#define fmiPlatformTypes_h + +/* Standard header file to define the argument types of the + functions of the Model Execution Interface. + This header file must be utilized both by the model and + by the simulation engine. + + Revisions: + - October 2010: First public Version + + + Copyright © 2008-2010, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html): + + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- +*/ + +/* Platform (combination of machine, compiler, operating system) */ +#define fmiPlatform "standard32" + +/* Type definitions of variables passed as arguments + Version "standard32" means: + + fmiComponent : 32 bit pointer + fmiValueReference: 32 bit + fmiReal : 64 bit + fmiInteger : 32 bit + fmiBoolean : 8 bit + fmiString : 32 bit pointer + +*/ + typedef void* fmiComponent; + typedef unsigned int fmiValueReference; + typedef double fmiReal ; + typedef int fmiInteger; + typedef char fmiBoolean; + typedef const char* fmiString ; + +/* Values for fmiBoolean */ +#define fmiTrue 1 +#define fmiFalse 0 + +/* Undefined value for fmiValueReference (largest unsigned int value) */ +#define fmiUndefinedValueReference (fmiValueReference)(-1) + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/fmusim_me/fmi_me.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/fmusim_me/fmi_me.h new file mode 100644 index 00000000..f1152455 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/fmusim_me/fmi_me.h @@ -0,0 +1,89 @@ +/* ------------------------------------------------------------------------- + * fmi_me.h + * Function types for all function of the "FMI for Model Exchange 1.0" + * and a struct with the corresponding function pointers. + * Copyright 2011 QTronic GmbH. All rights reserved. + * ------------------------------------------------------------------------- + */ + +#ifndef FMI_ME_H +#define FMI_ME_H + +#include +#include "fmiModelFunctions.h" +#include "xml_parser.h" + +typedef const char* (*fGetModelTypesPlatform)(); +typedef const char* (*fGetVersion)(); +typedef fmiComponent (*fInstantiateModel)(fmiString instanceName, fmiString GUID, + fmiCallbackFunctions functions, fmiBoolean loggingOn); +typedef void (*fFreeModelInstance) (fmiComponent c); +typedef fmiStatus (*fSetDebugLogging) (fmiComponent c, fmiBoolean loggingOn); +typedef fmiStatus (*fSetTime) (fmiComponent c, fmiReal time); +typedef fmiStatus (*fSetContinuousStates)(fmiComponent c, const fmiReal x[], size_t nx); +typedef fmiStatus (*fCompletedIntegratorStep)(fmiComponent c, fmiBoolean* callEventUpdate); +typedef fmiStatus (*fSetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); +typedef fmiStatus (*fSetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); +typedef fmiStatus (*fSetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); +typedef fmiStatus (*fSetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); +typedef fmiStatus (*fInitialize)(fmiComponent c, fmiBoolean toleranceControlled, + fmiReal relativeTolerance, fmiEventInfo* eventInfo); +typedef fmiStatus (*fGetDerivatives) (fmiComponent c, fmiReal derivatives[] , size_t nx); +typedef fmiStatus (*fGetEventIndicators)(fmiComponent c, fmiReal eventIndicators[], size_t ni); +typedef fmiStatus (*fGetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); +typedef fmiStatus (*fGetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); +typedef fmiStatus (*fGetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); +typedef fmiStatus (*fGetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); +typedef fmiStatus (*fEventUpdate) (fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo); +typedef fmiStatus (*fGetContinuousStates) (fmiComponent c, fmiReal states[], size_t nx); +typedef fmiStatus (*fGetNominalContinuousStates)(fmiComponent c, fmiReal x_nominal[], size_t nx); +typedef fmiStatus (*fGetStateValueReferences) (fmiComponent c, fmiValueReference vrx[], size_t nx); +typedef fmiStatus (*fTerminate) (fmiComponent c); + +typedef struct { + ModelDescription* modelDescription; + HANDLE dllHandle; + fGetModelTypesPlatform getModelTypesPlatform; + fGetVersion getVersion; + fInstantiateModel instantiateModel; + fFreeModelInstance freeModelInstance; + fSetDebugLogging setDebugLogging; + fSetTime setTime; + fSetContinuousStates setContinuousStates; + fCompletedIntegratorStep completedIntegratorStep; + fSetReal setReal; + fSetInteger setInteger; + fSetBoolean setBoolean; + fSetString setString; + fInitialize initialize; + fGetDerivatives getDerivatives; + fGetEventIndicators getEventIndicators; + fGetReal getReal; + fGetInteger getInteger; + fGetBoolean getBoolean; + fGetString getString; + fEventUpdate eventUpdate; + fGetContinuousStates getContinuousStates; + fGetNominalContinuousStates getNominalContinuousStates; + fGetStateValueReferences getStateValueReferences; + fTerminate terminate; +/* + fInstantiateSlave instantiateSlave; + fInitializeSlave initializeSlave; + fTerminateSlave terminateSlave; + fResetSlave resetSlave; + fFreeSlaveInstance freeSlaveInstance; + fGetRealOutputDerivatives getRealOutputDerivatives; + fSetRealInputDerivatives setRealInputDerivatives; + fDoStep doStep; + fCancelStep cancelStep; + fGetStatus getStatus; + fGetRealStatus getRealStatus; + fGetIntegerStatus getIntegerStatus; + fGetBooleanStatus getBooleanStatus; + fGetStringStatus getStringStatus; +*/ +} FMU; + +#endif // FMI_ME_H + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/fmusim_me/main.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/fmusim_me/main.c new file mode 100644 index 00000000..39b3957b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/fmusim_me/main.c @@ -0,0 +1,286 @@ +/* ------------------------------------------------------------------------- + * main.c + * Implements simulation of a single FMU instance using the forward Euler + * method for numerical integration. + * Command syntax: see printHelp() + * Simulates the given FMU from t = 0 .. tEnd with fixed step size h and + * writes the computed solution to file 'result.csv'. + * The CSV file (comma-separated values) may e.g. be plotted using + * OpenOffice Calc or Microsoft Excel. + * This progamm demonstrates basic use of an FMU. + * Real applications may use advanced numerical solvers instead, means to + * exactly locate state events in time, graphical plotting utilities, support + * for coexecution of many FMUs, stepping and debug support, user control + * of parameter and start values etc. + * All this is missing here. + * + * Revision history + * 07.02.2010 initial version released in FMU SDK 1.0 + * 05.03.2010 bug fix: removed strerror(GetLastError()) from error messages + * 11.06.2010 bug fix: replaced win32 API call to OpenFile in getFmuPath + * which restricted path length to FMU to 128 chars. New limit is MAX_PATH. + * 15.07.2010 fixed wrong label in xml parser: deault instead of default + * 13.12.2010 added check for undefined 'declared type' to xml parser + * 31.07.2011 bug fix: added missing freeModelInstance(c) + * 31.07.2011 bug fix: added missing terminate(c) + * + * Free libraries and tools used to implement this simulator: + * - header files from the FMU specification + * - eXpat 2.0.1 XML parser, see http://expat.sourceforge.net + * - 7z.exe 4.57 zip and unzip tool, see http://www.7-zip.org + * Author: Jakob Mauss + * Copyright 2011 QTronic GmbH. All rights reserved. + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include "fmi_me.h" +#include "sim_support.h" + +FMU fmu; // the fmu to simulate + +// simulate the given FMU using the forward euler method. +// time events are processed by reducing step size to exactly hit tNext. +// state events are checked and fired only at the end of an Euler step. +// the simulator may therefore miss state events and fires state events typically too late. +static int simulate(FMU* fmu, double tEnd, double h, fmiBoolean loggingOn, char separator) { + int i, n; + double dt, tPre; + fmiBoolean timeEvent, stateEvent, stepEvent; + double time; + int nx; // number of state variables + int nz; // number of state event indicators + double *x; // continuous states + double *xdot; // the crresponding derivatives in same order + double *z = NULL; // state event indicators + double *prez = NULL; // previous values of state event indicators + fmiEventInfo eventInfo; // updated by calls to initialize and eventUpdate + ModelDescription* md; // handle to the parsed XML file + const char* guid; // global unique id of the fmu + fmiCallbackFunctions callbacks; // called by the model during simulation + fmiComponent c; // instance of the fmu + fmiStatus fmiFlag; // return code of the fmu functions + fmiReal t0 = 0; // start time + fmiBoolean toleranceControlled = fmiFalse; + int nSteps = 0; + int nTimeEvents = 0; + int nStepEvents = 0; + int nStateEvents = 0; + FILE* file; + + double nextTime, step, value, currval; + char *par = "Auxiliary1"; + char *var = "Stock1"; + char* s; + int k; + ScalarVariable** vars = fmu->modelDescription->modelVariables; + fmiValueReference vr; + + + // instantiate the fmu + md = fmu->modelDescription; + guid = getString(md, att_guid); + callbacks.logger = fmuLogger; + callbacks.allocateMemory = calloc; + callbacks.freeMemory = free; + c = fmu->instantiateModel(getModelIdentifier(md), guid, callbacks, loggingOn); + if (!c) return error("could not instantiate model"); + + // allocate memory + nx = getNumberOfStates(md); + nz = getNumberOfEventIndicators(md); + x = (double *) calloc(nx, sizeof(double)); + xdot = (double *) calloc(nx, sizeof(double)); + if (nz>0) { + z = (double *) calloc(nz, sizeof(double)); + prez = (double *) calloc(nz, sizeof(double)); + } + if (!x || !xdot || nz>0 && (!z || !prez)) return error("out of memory"); + + // open result file + if (!(file=fopen(RESULT_FILE, "w"))) { + printf("could not write %s because:\n", RESULT_FILE); + printf(" %s\n", strerror(errno)); + return 0; // failure + } + + // set the start time and initialize + time = t0; + fmiFlag = fmu->setTime(c, t0); + if (fmiFlag > fmiWarning) return error("could not set time"); + fmiFlag = fmu->initialize(c, toleranceControlled, t0, &eventInfo); + if (fmiFlag > fmiWarning) return error("could not initialize model"); + if (eventInfo.terminateSimulation) { + printf("model requested termination at init"); + tEnd = time; + } + + // output solution for time t0 + outputRow(fmu, c, t0, file, separator, TRUE); // output column names + outputRow(fmu, c, t0, file, separator, FALSE); // output values + + nextTime = time; + // enter the simulation loop + while (time < tEnd) { + + if(time >= nextTime) { + // change variable value + for (k=0; vars[k]; k++) { + ScalarVariable* sv = vars[k]; + if (getAlias(sv)!=enu_noAlias) continue; + + s = getName(sv); + + if(strcmp(s,par) == 0) { + printf("Value for %s: ", s); + scanf("%lf", &value); + + vr = getValueReference(sv); + fmu->setReal(c, &vr, 1, &value); + + } + } + + printf("Give step: "); + scanf("%lf", &step); + nextTime = time + step; + } + + + // get current state and derivatives + fmiFlag = fmu->getContinuousStates(c, x, nx); + if (fmiFlag > fmiWarning) return error("could not retrieve states"); + fmiFlag = fmu->getDerivatives(c, xdot, nx); + if (fmiFlag > fmiWarning) return error("could not retrieve derivatives"); + + // advance time + tPre = time; + + time = min(time+h, tEnd); + timeEvent = eventInfo.upcomingTimeEvent && eventInfo.nextEventTime < time; + if (timeEvent) time = eventInfo.nextEventTime; + dt = time - tPre; + printf("Actual time: %lf\n", time); + fmiFlag = fmu->setTime(c, time); + if (fmiFlag > fmiWarning) error("could not set time"); + + // perform one step + for (i=0; isetContinuousStates(c, x, nx); + if (fmiFlag > fmiWarning) return error("could not set states"); + if (loggingOn) printf("Step %d to t=%.16g\n", nSteps, time); + + // Check for step event, e.g. dynamic state selection + fmiFlag = fmu->completedIntegratorStep(c, &stepEvent); + if (fmiFlag > fmiWarning) return error("could not complete intgrator step"); + + // Check for state event + for (i=0; igetEventIndicators(c, z, nz); + if (fmiFlag > fmiWarning) return error("could not retrieve event indicators"); + stateEvent = FALSE; + for (i=0; i0 && z[i]<0) ? "-\\-" : "-/-", i, time); + } + if (stepEvent) { + nStepEvents++; + if (loggingOn) printf("step event at t=%.16g\n", time); + } + + // event iteration in one step, ignoring intermediate results + fmiFlag = fmu->eventUpdate(c, fmiFalse, &eventInfo); + if (fmiFlag > fmiWarning) return error("could not perform event update"); + + // terminate simulation, if requested by the model + if (eventInfo.terminateSimulation) { + printf("model requested termination at t=%.16g\n", time); + break; // success + } + + // check for change of value of states + if (eventInfo.stateValuesChanged && loggingOn) { + printf("state values changed at t=%.16g\n", time); + } + + // check for selection of new state variables + if (eventInfo.stateValueReferencesChanged && loggingOn) { + printf("new state variables selected at t=%.16g\n", time); + } + + } // if event + outputRow(fmu, c, time, file, separator, FALSE); // output values for this step + + // change variable value + for (k=0; vars[k]; k++) { + ScalarVariable* sv = vars[k]; + if (getAlias(sv)!=enu_noAlias) continue; + + s = getName(sv); + + if(strcmp(s,var) == 0) { + vr = getValueReference(sv); + fmu->getReal(c, &vr, 1, &currval); + printf("Value for %s: %lf\n", s, currval); + } + } + + nSteps++; + } // while + + // cleanup + if(! eventInfo.terminateSimulation) fmu->terminate(c); + fmu->freeModelInstance(c); + fclose(file); + if (x!=NULL) free(x); + if (xdot!= NULL) free(xdot); + if (z!= NULL) free(z); + if (prez!= NULL) free(prez); + + // print simulation summary + printf("Simulation from %g to %g terminated successful\n", t0, tEnd); + printf(" steps ............ %d\n", nSteps); + printf(" fixed step size .. %g\n", h); + printf(" time events ...... %d\n", nTimeEvents); + printf(" state events ..... %d\n", nStateEvents); + printf(" step events ...... %d\n", nStepEvents); + + return 1; // success +} + +int main(int argc, char *argv[]) { + const char* fmuFileName; + + // parse command line arguments and load the FMU + double tEnd = 1.0; + double h=0.1; + int loggingOn = 0; + char csv_separator = ';'; + parseArguments(argc, argv, &fmuFileName, &tEnd, &h, &loggingOn, &csv_separator); + loadFMU(fmuFileName); + + // run the simulation + printf("FMU Simulator: run '%s' from t=0..%g with step size h=%g, loggingOn=%d, csv separator='%c'\n", + fmuFileName, tEnd, h, loggingOn, csv_separator); + simulate(&fmu, tEnd, h, loggingOn, csv_separator); + printf("CSV file '%s' written\n", RESULT_FILE); + + // release FMU + FreeLibrary(fmu.dllHandle); + freeElement(fmu.modelDescription); + return EXIT_SUCCESS; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/include/fmiModelFunctions.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/include/fmiModelFunctions.h new file mode 100644 index 00000000..e2047724 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/include/fmiModelFunctions.h @@ -0,0 +1,210 @@ +#ifndef fmiModelFunctions_h +#define fmiModelFunctions_h + +/* This header file must be utilized when compiling a model. + It defines all functions of the Model Execution Interface. + In order to have unique function names even if several models + are compiled together (e.g. for embedded systems), every "real" function name + is constructed by prepending the function name by + "MODEL_IDENTIFIER" + "_" where "MODEL_IDENTIFIER" is the short name + of the model used as the name of the zip-file where the model is stored. + Therefore, the typical usage is: + + #define MODEL_IDENTIFIER MyModel + #include "fmiModelFunctions.h" + + As a result, a function that is defined as "fmiGetDerivatives" in this header file, + is actually getting the name "MyModel_fmiGetDerivatives". + + Revisions: + - Jan. 20, 2010: stateValueReferencesChanged added to struct fmiEventInfo (ticket #27) + (by M. Otter, DLR) + Added WIN32 pragma to define the struct layout (ticket #34) + (by J. Mauss, QTronic) + - Jan. 4, 2010: Removed argument intermediateResults from fmiInitialize + Renamed macro fmiGetModelFunctionsVersion to fmiGetVersion + Renamed macro fmiModelFunctionsVersion to fmiVersion + Replaced fmiModel by fmiComponent in decl of fmiInstantiateModel + (by J. Mauss, QTronic) + - Dec. 17, 2009: Changed extension "me" to "fmi" (by Martin Otter, DLR). + - Dez. 14, 2009: Added eventInfo to meInitialize and added + meGetNominalContinuousStates (by Martin Otter, DLR) + - Sept. 9, 2009: Added DllExport (according to Peter Nilsson's suggestion) + (by A. Junghanns, QTronic) + - Sept. 9, 2009: Changes according to FMI-meeting on July 21: + meInquireModelTypesVersion -> meGetModelTypesPlatform + meInquireModelFunctionsVersion -> meGetModelFunctionsVersion + meSetStates -> meSetContinuousStates + meGetStates -> meGetContinuousStates + removal of meInitializeModelClass + removal of meGetTime + change of arguments of meInstantiateModel + change of arguments of meCompletedIntegratorStep + (by Martin Otter, DLR): + - July 19, 2009: Added "me" as prefix to file names (by Martin Otter, DLR). + - March 2, 2009: Changed function definitions according to the last design + meeting with additional improvements (by Martin Otter, DLR). + - Dec. 3 , 2008: First version by Martin Otter (DLR) and Hans Olsson (Dynasim). + + + Copyright © 2008-2009, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html): + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- + + with the extension: + + You may distribute or publicly perform any modification only under the + terms of this license. +*/ + +#include "fmiModelTypes.h" +#include + +/* Export fmi functions on Windows */ +#ifdef _MSC_VER +#define DllExport __declspec( dllexport ) +#else +#define DllExport +#endif + +/* Macros to construct the real function name + (prepend function name by MODEL_IDENTIFIER + "_") */ + +#define fmiPaste(a,b) a ## b +#define fmiPasteB(a,b) fmiPaste(a,b) +#define fmiFullName(name) fmiPasteB(MODEL_IDENTIFIER, name) + +#define fmiGetModelTypesPlatform fmiFullName(_fmiGetModelTypesPlatform) +#define fmiGetVersion fmiFullName(_fmiGetVersion) +#define fmiInstantiateModel fmiFullName(_fmiInstantiateModel) +#define fmiFreeModelInstance fmiFullName(_fmiFreeModelInstance) +#define fmiSetDebugLogging fmiFullName(_fmiSetDebugLogging) +#define fmiSetTime fmiFullName(_fmiSetTime) +#define fmiSetContinuousStates fmiFullName(_fmiSetContinuousStates) +#define fmiCompletedIntegratorStep fmiFullName(_fmiCompletedIntegratorStep) +#define fmiSetReal fmiFullName(_fmiSetReal) +#define fmiSetInteger fmiFullName(_fmiSetInteger) +#define fmiSetBoolean fmiFullName(_fmiSetBoolean) +#define fmiSetString fmiFullName(_fmiSetString) +#define fmiInitialize fmiFullName(_fmiInitialize) +#define fmiGetDerivatives fmiFullName(_fmiGetDerivatives) +#define fmiGetEventIndicators fmiFullName(_fmiGetEventIndicators) +#define fmiGetReal fmiFullName(_fmiGetReal) +#define fmiGetInteger fmiFullName(_fmiGetInteger) +#define fmiGetBoolean fmiFullName(_fmiGetBoolean) +#define fmiGetString fmiFullName(_fmiGetString) +#define fmiEventUpdate fmiFullName(_fmiEventUpdate) +#define fmiGetContinuousStates fmiFullName(_fmiGetContinuousStates) +#define fmiGetNominalContinuousStates fmiFullName(_fmiGetNominalContinuousStates) +#define fmiGetStateValueReferences fmiFullName(_fmiGetStateValueReferences) +#define fmiTerminate fmiFullName(_fmiTerminate) + + +/* Version number */ +#define fmiVersion "1.0" + +/* Inquire version numbers of header files */ + DllExport const char* fmiGetModelTypesPlatform(); + DllExport const char* fmiGetVersion(); + +/* make sure all compiler use the same alignment policies for structures */ +#ifdef WIN32 +#pragma pack(push,8) +#endif + +/* Type definitions */ + typedef enum {fmiOK, + fmiWarning, + fmiDiscard, + fmiError, + fmiFatal} fmiStatus; + + typedef void (*fmiCallbackLogger) (fmiComponent c, fmiString instanceName, fmiStatus status, + fmiString category, fmiString message, ...); + typedef void* (*fmiCallbackAllocateMemory)(size_t nobj, size_t size); + typedef void (*fmiCallbackFreeMemory) (void* obj); + + typedef struct { + fmiCallbackLogger logger; + fmiCallbackAllocateMemory allocateMemory; + fmiCallbackFreeMemory freeMemory; + } fmiCallbackFunctions; + + typedef struct { + fmiBoolean iterationConverged; + fmiBoolean stateValueReferencesChanged; + fmiBoolean stateValuesChanged; + fmiBoolean terminateSimulation; + fmiBoolean upcomingTimeEvent; + fmiReal nextEventTime; + } fmiEventInfo; + +/* reset alignment policy to the one set before reading this file */ +#ifdef WIN32 +#pragma pack(pop) +#endif + +/* Creation and destruction of model instances and setting debug status */ + DllExport fmiComponent fmiInstantiateModel (fmiString instanceName, + fmiString GUID, + fmiCallbackFunctions functions, + fmiBoolean loggingOn); + DllExport void fmiFreeModelInstance(fmiComponent c); + DllExport fmiStatus fmiSetDebugLogging (fmiComponent c, fmiBoolean loggingOn); + + +/* Providing independent variables and re-initialization of caching */ + DllExport fmiStatus fmiSetTime (fmiComponent c, fmiReal time); + DllExport fmiStatus fmiSetContinuousStates (fmiComponent c, const fmiReal x[], size_t nx); + DllExport fmiStatus fmiCompletedIntegratorStep(fmiComponent c, fmiBoolean* callEventUpdate); + DllExport fmiStatus fmiSetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); + DllExport fmiStatus fmiSetInteger (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); + DllExport fmiStatus fmiSetBoolean (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); + DllExport fmiStatus fmiSetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); + + +/* Evaluation of the model equations */ + DllExport fmiStatus fmiInitialize(fmiComponent c, fmiBoolean toleranceControlled, + fmiReal relativeTolerance, fmiEventInfo* eventInfo); + + DllExport fmiStatus fmiGetDerivatives (fmiComponent c, fmiReal derivatives[] , size_t nx); + DllExport fmiStatus fmiGetEventIndicators(fmiComponent c, fmiReal eventIndicators[], size_t ni); + + DllExport fmiStatus fmiGetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); + DllExport fmiStatus fmiGetInteger(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); + DllExport fmiStatus fmiGetBoolean(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); + DllExport fmiStatus fmiGetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); + + DllExport fmiStatus fmiEventUpdate (fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo); + DllExport fmiStatus fmiGetContinuousStates (fmiComponent c, fmiReal states[], size_t nx); + DllExport fmiStatus fmiGetNominalContinuousStates(fmiComponent c, fmiReal x_nominal[], size_t nx); + DllExport fmiStatus fmiGetStateValueReferences (fmiComponent c, fmiValueReference vrx[], size_t nx); + DllExport fmiStatus fmiTerminate (fmiComponent c); + +#endif // fmiModelFunctions_h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/include/fmiModelTypes.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/include/fmiModelTypes.h new file mode 100644 index 00000000..17e9e300 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/model_exchange/include/fmiModelTypes.h @@ -0,0 +1,91 @@ +#ifndef fmiModelTypes_h +#define fmiModelTypes_h + +/* Standard header file to define the argument types of the + functions of the Model Execution Interface. + This header file must be utilized both by the model and + by the simulation engine. + + Revisions: + - Jan. 4, 2010: Renamed meModelTypes_h to fmiModelTypes_h (by Mauss, QTronic) + - Dec. 21, 2009: Changed "me" to "fmi" and "meModel" to "fmiComponent" + according to meeting on Dec. 18 (by Martin Otter, DLR) + - Dec. 6, 2009: Added meUndefinedValueReference (by Martin Otter, DLR) + - Sept. 9, 2009: Changes according to FMI-meeting on July 21: + Changed "version" to "platform", "standard" to "standard32", + Added a precise definition of "standard32" as comment + (by Martin Otter, DLR) + - July 19, 2009: Added "me" as prefix to file names, added meTrue/meFalse, + and changed meValueReferenced from int to unsigned int + (by Martin Otter, DLR). + - March 2, 2009: Moved enums and function pointer definitions to + ModelFunctions.h (by Martin Otter, DLR). + - Dec. 3, 2008 : First version by Martin Otter (DLR) and + Hans Olsson (Dynasim). + + + Copyright © 2008-2010, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html) + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- + + with the extension: + + You may distribute or publicly perform any modification only under the + terms of this license. +*/ + +/* Platform (combination of machine, compiler, operating system) */ +#define fmiModelTypesPlatform "standard32" + +/* Type definitions of variables passed as arguments + Version "standard32" means: + + fmiComponent : 32 bit pointer + fmiValueReference: 32 bit + fmiReal : 64 bit + fmiInteger : 32 bit + fmiBoolean : 8 bit + fmiString : 32 bit pointer + +*/ + typedef void* fmiComponent; + typedef unsigned int fmiValueReference; + typedef double fmiReal ; + typedef int fmiInteger; + typedef char fmiBoolean; + typedef const char* fmiString ; + +/* Values for fmiBoolean */ +#define fmiTrue 1 +#define fmiFalse 0 + +/* Undefined value for fmiValueReference (largest unsigned int value) */ +#define fmiUndefinedValueReference (fmiValueReference)(-1) + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/_main.html new file mode 100644 index 00000000..fff15c6a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/_main.html @@ -0,0 +1,52 @@ + + + Documentation for bouncingBall.fmu + + + +

bouncingBall.fmu

+The bouncingBall implements the following equation: +
    +
  • der(h) = v; +
  • der(v) = -g; +
  • when h<0 then v := -e* v +
+with start values h=1, e=0.7, g = 9.81 and +
    +
  • h: height [m], used as state +
  • v: velocity of ball [m/s], used as state +
  • der(h): velocity of ball [m/s] +
  • der(v): acceleration of ball [m/s2] +
  • g: acceleration of gravity [m/s2], a parameter +
  • e: a dimensionless parameter +
+ +
+ +
+The figure shows the solution computed with Silver +for height h of the ball for the start values given above. + +

+The chain of events during simulation is as follows +

    +
  1. intitially h>0 and pos(0)=true
  2. +
  3. continuous integration until a state event is detected, i.e. + until h + EPS_INDICATORS = 0. + At this time h < 0, the EPS_INDICATORS adds hysteresis.
  4. +
  5. the simulator calls eventUpdate once which reverses the speed direction + v of the ball: v = -e * v, and sets pos(0)=false
  6. +
  7. continuous integration until state event is detected, i.e. + until h - EPS_INDICATORS = 0. + At this time h > 0, the EPS_INDICATORS adds hysteresis.
  8. +
  9. the simulator calls eventUpdate once more which sets pos(0)=true.
  10. +
  11. goto 2
  12. +
+The above description refers to the variables used +in file bouncingBall.c. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/bouncingBall.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/bouncingBall.c new file mode 100644 index 00000000..7f6c3037 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/bouncingBall.c @@ -0,0 +1,103 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU - a bouncing ball. + * This demonstrates the use of state events and reinit of states. + * Equations: + * der(h) = v; + * der(v) = -g; + * when h<0 then v := -e * v; + * where + * h height [m], used as state, start = 1 + * v velocity of ball [m/s], used as state + * der(h) velocity of ball [m/s] + * der(v) acceleration of ball [m/s2] + * g acceleration of gravity [m/s2], a parameter, start = 9.81 + * e a dimensionless parameter, start = 0.7 + * + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER bouncingBall +#define MODEL_GUID "{8c4e810f-3df3-4a00-8276-176fa3c9f003}" + +// define model size +#define NUMBER_OF_REALS 5 +#define NUMBER_OF_INTEGERS 0 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_STATES 2 +#define NUMBER_OF_EVENT_INDICATORS 1 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define h_ 0 +#define der_h_ 1 +#define v_ 2 +#define der_v_ 3 +#define g_ 3 // negated alias +#define e_ 4 + +// define initial state vector as vector of value references +#define STATES { h_, v_ } + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + r(h_) = 1; + r(v_) = 0; + r(der_v_) = -9.81; + r(e_) = 0.7; + pos(0) = r(h_) > 0; +} + +// called by fmiGetReal, fmiGetContinuousStates and fmiGetDerivatives +fmiReal getReal(ModelInstance* comp, fmiValueReference vr){ + switch (vr) { + case h_ : return r(h_); + case der_h_ : return r(v_); + case v_ : return r(v_); + case der_v_ : return r(der_v_); + case e_ : return r(e_); + default: return 0; + } +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +// offset for event indicator, adds hysteresis and prevents z=0 at restart +#define EPS_INDICATORS 1e-14 + +fmiReal getEventIndicator(ModelInstance* comp, int z) { + switch (z) { + case 0 : return r(h_) + (pos(0) ? EPS_INDICATORS : -EPS_INDICATORS); + default: return 0; + } +} + +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { + if (pos(0)) { + r(v_) = - r(e_) * r(v_); + } + pos(0) = r(h_) > 0; + eventInfo->iterationConverged = fmiTrue; + eventInfo->stateValueReferencesChanged = fmiFalse; + eventInfo->stateValuesChanged = fmiTrue; + eventInfo->terminateSimulation = fmiFalse; + eventInfo->upcomingTimeEvent = fmiFalse; + } + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/modelDescription.xml new file mode 100644 index 00000000..4cb345e7 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/modelDescription.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/plot_h.PNG b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/plot_h.PNG new file mode 100644 index 00000000..ced85c46 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/bouncingBall/plot_h.PNG differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/build_fmu.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/build_fmu.bat new file mode 100644 index 00000000..9d014581 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/build_fmu.bat @@ -0,0 +1,80 @@ +@echo off +rem ------------------------------------------------------------ +rem This batch builds an FMU of the FMU SDK +rem Usage: build_fmu (me|cs) +rem (c) 2011 QTronic GmbH +rem ------------------------------------------------------------ + +echo ----------------------------------------------------------- +if %1==cs (^ +echo building FMU %2 - FMI for Co-Simulation 1.0) else ^ +echo building FMU %2 - FMI for Model Exchange 1.0 + +rem save env variable settings +set PREV_PATH=%PATH% +if defined INCLUDE set PREV_INCLUDE=%INLUDE% +if defined LIB set PREV_LIB=%LIB% +if defined LIBPATH set PREV_LIBPATH=%LIBPATH% + +rem setup the compiler +if defined VS90COMNTOOLS (call "%VS90COMNTOOLS%\vsvars32.bat") else ^ +if defined VS80COMNTOOLS (call "%VS80COMNTOOLS%\vsvars32.bat") else ^ +goto noCompiler + +rem create the %2.dll in the temp dir +if not exist temp mkdir temp +pushd temp +if exist *.dll del /Q *.dll + +rem /wd4090 disables warnings about different 'const' qualifiers +if %1==cs (set FMI_DIR=co_simulation) else set FMI_DIR=model_exchange +if %1==cs (set DEF=/DFMI_COSIMULATION) else set DEF= +cl /LD /wd4090 /nologo %DEF% ..\%2\%2.c /I ..\. /I ..\..\%FMI_DIR%\include +if not exist %2.dll goto compileError + +rem create FMU dir structure with root 'fmu' +set BIN_DIR=fmu\binaries\win32 +set SRC_DIR=fmu\sources +set DOC_DIR=fmu\documentation +if not exist %BIN_DIR% mkdir %BIN_DIR% +if not exist %SRC_DIR% mkdir %SRC_DIR% +if not exist %DOC_DIR% mkdir %DOC_DIR% +move /Y %2.dll %BIN_DIR% +if exist ..\%2\*~ del /Q ..\%2\*~ +copy ..\%2\%2.c %SRC_DIR% +type ..\%2\modelDescription.xml ..\%1.xml > fmu\modelDescription.xml +copy ..\%2\model.png fmu +copy ..\fmuTemplate.c %SRC_DIR% +copy ..\fmuTemplate.h %SRC_DIR% +copy ..\%2\*.html %DOC_DIR% +copy ..\%2\*.png %DOC_DIR% +del %DOC_DIR%\model.png + +rem zip the directory tree and move to fmu directory +cd fmu +set FMU_FILE=..\..\..\..\fmu\%1\%2.fmu +if exist %ZIP_FILE% del %FMU_FILE% +..\..\..\..\bin\7z.exe a -tzip -xr!.svn %FMU_FILE% ^ + modelDescription.xml model.png binaries sources documentation +goto cleanup + +:noCompiler +echo No Microsoft Visual C compiler found +exit + +:compileError +echo build of %2 failed + +:cleanup +popd +if exist temp rmdir /S /Q temp + +rem undo variable settings performed by vsvars32.bat +set PATH=%PREV_PATH% +if defined PREV_INCLUDE set INCLUDE=%PREV_INLUDE% +if defined PREV_LIB set LIB=%PREV_LIB% +if defined PREV_LIBPATH set LIBPATH=%PREV_LIBPATH% +echo done. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/cs.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/cs.xml new file mode 100644 index 00000000..9e38bc40 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/cs.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/_main.html new file mode 100644 index 00000000..f981d0fe --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/_main.html @@ -0,0 +1,29 @@ + + +Documentation for dq.fmu + + + +

dq.fmu

+This FMU implements the equation +
    +
  • der(x) = -k * x
  • +
+The analytical solution of this system is +
    +
  • x(t) = exp(-k*t)
  • +
+The above equation is also known as +Dahlquist +test equation. +
+ +
+The figure shows the solution for x computed with Silver +for start values k = 1 and x = 1. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/dq.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/dq.c new file mode 100644 index 00000000..bb8df472 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/dq.c @@ -0,0 +1,67 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU - the Dahlquist test equation. + * + * der(x) = - k * x and x(0) = 1. + * Analytical solution: x(t) = exp(-k*t). + * + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER dq +#define MODEL_GUID "{8c4e810f-3df3-4a00-8276-176fa3c9f000}" + +// define model size +#define NUMBER_OF_REALS 3 +#define NUMBER_OF_INTEGERS 0 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_STATES 1 +#define NUMBER_OF_EVENT_INDICATORS 0 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define x_ 0 +#define der_x_ 1 +#define k_ 2 + +// define state vector as vector of value references +#define STATES { x_ } + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + r(x_) = 1; + r(k_) = 1; +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +// called by fmiGetReal, fmiGetContinuousStates and fmiGetDerivatives +fmiReal getReal(ModelInstance* comp, fmiValueReference vr){ + switch (vr) { + case x_ : return r(x_); + case der_x_ : return - r(k_) * r(x_); + case k_ : return r(k_); + default: return 0; + } +} + +// Used to set the next time event, if any. +void eventUpdate(fmiComponent comp, fmiEventInfo* eventInfo) { +} + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/modelDescription.xml new file mode 100644 index 00000000..daf9fbf0 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/modelDescription.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/plot_x.PNG b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/plot_x.PNG new file mode 100644 index 00000000..b28fa66c Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/dq/plot_x.PNG differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/fmuTemplate.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/fmuTemplate.c new file mode 100644 index 00000000..e64b47e3 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/fmuTemplate.c @@ -0,0 +1,765 @@ +/* ---------------------------------------------------------------------------* + * Implementation of the FMI interface based on functions and macros to + * be defined by the includer of this file. + * If FMI_COSIMULATION is defined, this implements "FMI for Co-Simulation 1.0", + * otherwise "FMI for Model Exchange 1.0". + * The "FMI for Co-Simulation 1.0", implementation assumes that exactly the + * following capability flags are set to fmiTrue: + * canHandleVariableCommunicationStepSize, i.e. fmiDoStep step size can vary + * canHandleEvents, i.e. fmiDoStep step size can be zero + * and all other capability flags are set to default, i.e. to fmiFalse or 0. + * + * Revision history + * 07.02.2010 initial version for "Model Exchange 1.0" released in FMU SDK 1.0 + * 05.03.2010 bug fix: fmiSetString now copies the passed string argument + * and fmiFreeModelInstance frees all string copies + * 11.12.2010 replaced calloc by functions.allocateMemory in fmiInstantiateModel + * 04.08.2011 added support for "FMI for Co-Simulation 1.0" + * + * (c) 2011 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// array of value references of states +#if NUMBER_OF_REALS>0 +fmiValueReference vrStates[NUMBER_OF_STATES] = STATES; +#endif + +// --------------------------------------------------------------------------- +// Private helpers used below to validate function arguments +// --------------------------------------------------------------------------- + +static fmiBoolean invalidNumber(ModelInstance* comp, const char* f, const char* arg, int n, int nExpected){ + if (n != nExpected) { + comp->state = modelError; + comp->functions.logger(comp, comp->instanceName, fmiError, "error", + "%s: Invalid argument %s = %d. Expected %d.", f, arg, n, nExpected); + return fmiTrue; + } + return fmiFalse; +} + +static fmiBoolean invalidState(ModelInstance* comp, const char* f, int statesExpected){ + if (!comp) + return fmiTrue; + if (!(comp->state & statesExpected)) { + comp->state = modelError; + comp->functions.logger(comp, comp->instanceName, fmiError, "error", + "%s: Illegal call sequence.", f); + return fmiTrue; + } + return fmiFalse; +} + +static fmiBoolean nullPointer(ModelInstance* comp, const char* f, const char* arg, const void* p){ + if (!p) { + comp->state = modelError; + comp->functions.logger(comp, comp->instanceName, fmiError, "error", + "%s: Invalid argument %s = NULL.", f, arg); + return fmiTrue; + } + return fmiFalse; +} + +static fmiBoolean vrOutOfRange(ModelInstance* comp, const char* f, fmiValueReference vr, int end) { + if (vr >= end) { + comp->functions.logger(comp, comp->instanceName, fmiError, "error", + "%s: Illegal value reference %u.", f, vr); + comp->state = fmiError; + return fmiTrue; + } + return fmiFalse; +} + +// --------------------------------------------------------------------------- +// Private helpers used below to implement functions +// --------------------------------------------------------------------------- + +fmiStatus setString(fmiComponent comp, fmiValueReference vr, fmiString value){ + return fmiSetString(comp, &vr, 1, &value); +} + +// fname is fmiInstantiateModel or fmiInstantiateSlave +static fmiComponent instantiateModel(char* fname, fmiString instanceName, fmiString GUID, + fmiCallbackFunctions functions, fmiBoolean loggingOn) { + ModelInstance* comp; + if (!functions.logger) + return NULL; + if (!functions.allocateMemory || !functions.freeMemory){ + functions.logger(NULL, instanceName, fmiError, "error", + "%s: Missing callback function.", fname); + return NULL; + } + if (!instanceName || strlen(instanceName)==0) { + functions.logger(NULL, instanceName, fmiError, "error", + "%s: Missing instance name.", fname); + return NULL; + } + if (strcmp(GUID, MODEL_GUID)) { + functions.logger(NULL, instanceName, fmiError, "error", + "%s: Wrong GUID %s. Expected %s.", fname, GUID, MODEL_GUID); + return NULL; + } + comp = (ModelInstance *)functions.allocateMemory(1, sizeof(ModelInstance)); + if (comp) { + comp->r = functions.allocateMemory(NUMBER_OF_REALS, sizeof(fmiReal)); + comp->i = functions.allocateMemory(NUMBER_OF_INTEGERS, sizeof(fmiInteger)); + comp->b = functions.allocateMemory(NUMBER_OF_BOOLEANS, sizeof(fmiBoolean)); + comp->s = functions.allocateMemory(NUMBER_OF_STRINGS, sizeof(fmiString)); + comp->isPositive = functions.allocateMemory(NUMBER_OF_EVENT_INDICATORS, sizeof(fmiBoolean)); + } + if (!comp || !comp->r || !comp->i || !comp->b || !comp->s || !comp->isPositive) { + functions.logger(NULL, instanceName, fmiError, "error", + "%s: Out of memory.", fname); + return NULL; + } + if (comp->loggingOn) comp->functions.logger(NULL, instanceName, fmiOK, "log", + "%s: GUID=%s", fname, GUID); + comp->instanceName = instanceName; + comp->GUID = GUID; + comp->functions = functions; + comp->loggingOn = loggingOn; + comp->state = modelInstantiated; + setStartValues(comp); // to be implemented by the includer of this file + return comp; +} + +// fname is fmiInitialize or fmiInitializeSlave +static fmiStatus init(char* fname, fmiComponent c, fmiBoolean toleranceControlled, fmiReal relativeTolerance, + fmiEventInfo* eventInfo) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, fname, modelInstantiated)) + return fmiError; + if (nullPointer(comp, fname, "eventInfo", eventInfo)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "%s: toleranceControlled=%d relativeTolerance=%g", + fname, toleranceControlled, relativeTolerance); + eventInfo->iterationConverged = fmiTrue; + eventInfo->stateValueReferencesChanged = fmiFalse; + eventInfo->stateValuesChanged = fmiFalse; + eventInfo->terminateSimulation = fmiFalse; + eventInfo->upcomingTimeEvent = fmiFalse; + initialize(comp, eventInfo); // to be implemented by the includer of this file + comp->state = modelInitialized; + return fmiOK; +} + +// fname is fmiTerminate or fmiTerminateSlave +static fmiStatus terminate(char* fname, fmiComponent c){ + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, fname, modelInitialized)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", fname); + comp->state = modelTerminated; + return fmiOK; +} + +// fname is freeModelInstance of freeSlaveInstance +void freeInstance(char* fname, fmiComponent c) { + ModelInstance* comp = (ModelInstance *)c; + if (!comp) return; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", fname); + if (comp->r) comp->functions.freeMemory(comp->r); + if (comp->i) comp->functions.freeMemory(comp->i); + if (comp->b) comp->functions.freeMemory(comp->b); + if (comp->s) { + int i; + for (i=0; is[i]) comp->functions.freeMemory(comp->s[i]); + } + comp->functions.freeMemory(comp->s); + } + comp->functions.freeMemory(comp); +} + +// --------------------------------------------------------------------------- +// FMI functions: class methods not depending of a specific model instance +// --------------------------------------------------------------------------- + +const char* fmiGetVersion() { + return fmiVersion; +} + +// --------------------------------------------------------------------------- +// FMI functions: for FMI Model Exchange 1.0 and for FMI Co-Simulation 1.0 +// logging control, setters and getters for Real, Integer, Boolean, String +// --------------------------------------------------------------------------- + +fmiStatus fmiSetDebugLogging(fmiComponent c, fmiBoolean loggingOn) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetDebugLogging", not_modelError)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetDebugLogging: loggingOn=%d", loggingOn); + comp->loggingOn = loggingOn; + return fmiOK; +} + +fmiStatus fmiSetReal(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetReal", modelInstantiated|modelInitialized)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetReal", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetReal", "value[]", value)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetReal: nvr = %d", nvr); + // no check wether setting the value is allowed in the current state + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetReal: #r%d# = %.16g", vr[i], value[i]); + comp->r[vr[i]] = value[i]; + } + return fmiOK; +} + +fmiStatus fmiSetInteger(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetInteger", modelInstantiated|modelInitialized)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetInteger", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetInteger", "value[]", value)) + return fmiError; + if (comp->loggingOn) + comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiSetInteger: nvr = %d", nvr); + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetInteger: #i%d# = %d", vr[i], value[i]); + comp->i[vr[i]] = value[i]; + } + return fmiOK; +} + +fmiStatus fmiSetBoolean(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetBoolean", modelInstantiated|modelInitialized)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetBoolean", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetBoolean", "value[]", value)) + return fmiError; + if (comp->loggingOn) + comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiSetBoolean: nvr = %d", nvr); + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetBoolean: #b%d# = %s", vr[i], value[i] ? "true" : "false"); + comp->b[vr[i]] = value[i]; + } + return fmiOK; +} + +fmiStatus fmiSetString(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]){ + int i, n; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetString", modelInstantiated|modelInitialized)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetString", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiSetString", "value[]", value)) + return fmiError; + if (comp->loggingOn) + comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiSetString: nvr = %d", nvr); + for (i=0; is[vr[i]]; + if (vrOutOfRange(comp, "fmiSetString", vr[i], NUMBER_OF_STRINGS)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetString: #s%d# = '%s'", vr[i], value[i]); + if (nullPointer(comp, "fmiSetString", "value[i]", value[i])) + return fmiError; + if (string==NULL || strlen(string) < strlen(value[i])) { + if (string) comp->functions.freeMemory(string); + comp->s[vr[i]] = comp->functions.allocateMemory(1+strlen(value[i]), sizeof(char)); + if (!comp->s[vr[i]]) { + comp->state = modelError; + comp->functions.logger(NULL, comp->instanceName, fmiError, "error", "fmiSetString: Out of memory."); + return fmiError; + } + } + strcpy(comp->s[vr[i]], value[i]); + } + return fmiOK; +} + +fmiStatus fmiGetReal(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetReal", not_modelError)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetReal", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetReal", "value[]", value)) + return fmiError; +#if NUMBER_OF_REALS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetReal: #r%u# = %.16g", vr[i], value[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiGetInteger(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetInteger", not_modelError)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetInteger", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetInteger", "value[]", value)) + return fmiError; + for (i=0; ii[vr[i]]; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetInteger: #i%u# = %d", vr[i], value[i]); + } + return fmiOK; +} + +fmiStatus fmiGetBoolean(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetBoolean", not_modelError)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetBoolean", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetBoolean", "value[]", value)) + return fmiError; + for (i=0; ib[vr[i]]; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetBoolean: #b%u# = %s", vr[i], value[i]? "true" : "false"); + } + return fmiOK; +} + +fmiStatus fmiGetString(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetString", not_modelError)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetString", "vr[]", vr)) + return fmiError; + if (nvr>0 && nullPointer(comp, "fmiGetString", "value[]", value)) + return fmiError; + for (i=0; is[vr[i]]; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetString: #s%u# = '%s'", vr[i], value[i]); + } + return fmiOK; +} + +#ifdef FMI_COSIMULATION +// --------------------------------------------------------------------------- +// FMI functions: only for FMI Co-Simulation 1.0 +// --------------------------------------------------------------------------- + +const char* fmiGetTypesPlatform() { + return fmiPlatform; +} + +fmiComponent fmiInstantiateSlave(fmiString instanceName, fmiString GUID, + fmiString fmuLocation, fmiString mimeType, fmiReal timeout, fmiBoolean visible, + fmiBoolean interactive, fmiCallbackFunctions functions, fmiBoolean loggingOn) { + // ignoring arguments: fmuLocation, mimeType, timeout, visible, interactive + return instantiateModel("fmiInstantiateSlave", instanceName, GUID, functions, loggingOn); +} + +fmiStatus fmiInitializeSlave(fmiComponent c, fmiReal tStart, fmiBoolean StopTimeDefined, fmiReal tStop) { + ModelInstance* comp = (ModelInstance *)c; + fmiBoolean toleranceControlled = fmiFalse; + fmiReal relativeTolerance = 0; + fmiStatus flag = fmiOK; + comp->eventInfo.iterationConverged = 0; + while (flag==fmiOK && !comp->eventInfo.iterationConverged) { + // ignoring arguments: tStart, StopTimeDefined, tStop + flag = init("fmiInitializeSlave", c, toleranceControlled, relativeTolerance, &comp->eventInfo); + } + return flag; +} + +fmiStatus fmiTerminateSlave(fmiComponent c) { + return terminate("fmiTerminateSlave", c); +} + +fmiStatus fmiResetSlave(fmiComponent c) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiResetSlave", modelInitialized)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", "fmiResetSlave"); + comp->state = modelInstantiated; + setStartValues(comp); // to be implemented by the includer of this file + return fmiOK; +} + +void fmiFreeSlaveInstance(fmiComponent c) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiFreeSlaveInstance", modelTerminated)) + return; + freeInstance("fmiFreeSlaveInstance", c); +} + +fmiStatus fmiSetRealInputDerivatives(fmiComponent c, const fmiValueReference vr[], size_t nvr, + const fmiInteger order[], const fmiReal value[]) { + ModelInstance* comp = (ModelInstance *)c; + fmiCallbackLogger log = comp->functions.logger; + if (invalidState(comp, "fmiSetRealInputDerivatives", modelInitialized)) + return fmiError; + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "fmiSetRealInputDerivatives: nvr= %d", nvr); + log(NULL, comp->instanceName, fmiError, "warning", "fmiSetRealInputDerivatives: ignoring function call." + " This model cannot interpolate inputs: canInterpolateInputs=\"fmiFalse\""); + return fmiWarning; +} + +fmiStatus fmiGetRealOutputDerivatives(fmiComponent c, const fmiValueReference vr[], size_t nvr, + const fmiInteger order[], fmiReal value[]) { + int i; + ModelInstance* comp = (ModelInstance *)c; + fmiCallbackLogger log = comp->functions.logger; + if (invalidState(comp, "fmiGetRealOutputDerivatives", modelInitialized)) + return fmiError; + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "fmiGetRealOutputDerivatives: nvr= %d", nvr); + log(NULL, comp->instanceName, fmiError, "warning", "fmiGetRealOutputDerivatives: ignoring function call." + " This model cannot compute derivatives of outputs: MaxOutputDerivativeOrder=\"0\""); + for (i=0; ifunctions.logger; + if (invalidState(comp, "fmiCancelStep", modelInitialized)) + return fmiError; + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "fmiCancelStep"); + log(NULL, comp->instanceName, fmiError, "error", + "fmiCancelStep: Can be called when fmiDoStep returned fmiPending." + " This is not the case."); + return fmiError; +} + +fmiStatus fmiDoStep(fmiComponent c, fmiReal currentCommunicationPoint, + fmiReal communicationStepSize, fmiBoolean newStep) { + ModelInstance* comp = (ModelInstance *)c; + fmiCallbackLogger log = comp->functions.logger; + double h = communicationStepSize / 10; + int k,i; + const int n = 10; // how many Euler steps to perform for one do step + double prevState[max(NUMBER_OF_STATES, 1)]; + double prevEventIndicators[max(NUMBER_OF_EVENT_INDICATORS, 1)]; + int stateEvent = 0; + + if (invalidState(comp, "fmiDoStep", modelInitialized)) + return fmiError; + + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "fmiDoStep: " + "currentCommunicationPoint = %g, ", + "communicationStepSize = %g, ", + "newStep = fmi%s", + currentCommunicationPoint, communicationStepSize, newStep ? "True" : "False"); + + // Treat also case of zero step, i.e. during an event iteration + if (communicationStepSize == 0) { + return fmiOK; + } + +#if NUMBER_OF_EVENT_INDICATORS>0 + // initialize previous event indcators with current values + for (i=0; itime = currentCommunicationPoint; + for (k=0; ktime += h; + +#if NUMBER_OF_REALS>0 + for (i=0; i0 + // check for state event + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiDoStep: state event at %g, z%d crosses zero -%c-", comp->time, i, ei<0 ? '\\' : '/'); + stateEvent++; + } + prevEventIndicators[i] = ei; + } + if (stateEvent) { + eventUpdate(comp, &comp->eventInfo); + stateEvent = 0; + } +#endif + // check for time event + if (comp->eventInfo.upcomingTimeEvent && comp->time > comp->eventInfo.nextEventTime) { + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiDoStep: time event detected at %g", comp->time); + eventUpdate(comp, &comp->eventInfo); + } + + // terminate simulation, if requested by the model + if (comp->eventInfo.terminateSimulation) { + comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiDoStep: model requested termination at t=%g", comp->time); + return fmiError; // enforce termination of the simulation loop + } + } + return fmiOK; +} + +static fmiStatus getStatus(char* fname, fmiComponent c, const fmiStatusKind s) { + const char* statusKind[3] = {"fmiDoStepStatus","fmiPendingStatus","fmiLastSuccessfulTime"}; + ModelInstance* comp = (ModelInstance *)c; + fmiCallbackLogger log = comp->functions.logger; + if (invalidState(comp, fname, modelInstantiated|modelInitialized)) + return fmiError; + if (comp->loggingOn) log(c, comp->instanceName, fmiOK, "log", "$s: fmiStatusKind = %s", fname, statusKind[s]); + switch(s) { + case fmiDoStepStatus: log(NULL, comp->instanceName, fmiError, "error", + "%s: Can be called with fmiDoStepStatus when fmiDoStep returned fmiPending." + " This is not the case.", fname); + break; + case fmiPendingStatus: log(NULL, comp->instanceName, fmiError, "error", + "%s: Can be called with fmiPendingStatus when fmiDoStep returned fmiPending." + " This is not the case.", fname); + break; + case fmiLastSuccessfulTime: log(NULL, comp->instanceName, fmiError, "error", + "%s: Can be called with fmiLastSuccessfulTime when fmiDoStep returned fmiDiscard." + " This is not the case.", fname); + break; + } + return fmiError; +} + +fmiStatus fmiGetStatus(fmiComponent c, const fmiStatusKind s, fmiStatus* value) { + return getStatus("fmiGetStatus", c, s); +} + +fmiStatus fmiGetRealStatus(fmiComponent c, const fmiStatusKind s, fmiReal* value){ + return getStatus("fmiGetRealStatus", c, s); +} + +fmiStatus fmiGetIntegerStatus(fmiComponent c, const fmiStatusKind s, fmiInteger* value){ + return getStatus("fmiGetIntegerStatus", c, s); +} + +fmiStatus fmiGetBooleanStatus(fmiComponent c, const fmiStatusKind s, fmiBoolean* value){ + return getStatus("fmiGetBooleanStatus", c, s); +} + +fmiStatus fmiGetStringStatus(fmiComponent c, const fmiStatusKind s, fmiString* value){ + return getStatus("fmiGetStringStatus", c, s); +} + +#else +// --------------------------------------------------------------------------- +// FMI functions: only for Model Exchange 1.0 +// --------------------------------------------------------------------------- + +const char* fmiGetModelTypesPlatform() { + return fmiModelTypesPlatform; +} + +fmiComponent fmiInstantiateModel(fmiString instanceName, fmiString GUID, + fmiCallbackFunctions functions, fmiBoolean loggingOn) { + return instantiateModel("fmiInstantiateModel", instanceName, GUID, functions, loggingOn); +} + +fmiStatus fmiInitialize(fmiComponent c, fmiBoolean toleranceControlled, fmiReal relativeTolerance, + fmiEventInfo* eventInfo) { + return init("fmiInitialize", c, toleranceControlled, relativeTolerance, eventInfo); +} + +fmiStatus fmiSetTime(fmiComponent c, fmiReal time) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiSetTime", modelInstantiated|modelInitialized)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetTime: time=%.16g", time); + comp->time = time; + return fmiOK; +} + +fmiStatus fmiSetContinuousStates(fmiComponent c, const fmiReal x[], size_t nx){ + ModelInstance* comp = (ModelInstance *)c; + int i; + if (invalidState(comp, "fmiSetContinuousStates", modelInitialized)) + return fmiError; + if (invalidNumber(comp, "fmiSetContinuousStates", "nx", nx, NUMBER_OF_STATES)) + return fmiError; + if (nullPointer(comp, "fmiSetContinuousStates", "x[]", x)) + return fmiError; +#if NUMBER_OF_REALS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiSetContinuousStates: #r%d#=%.16g", vr, x[i]); + assert(vr>=0 && vrr[vr] = x[i]; + } +#endif + return fmiOK; +} + +fmiStatus fmiEventUpdate(fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo) { + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiEventUpdate", modelInitialized)) + return fmiError; + if (nullPointer(comp, "fmiEventUpdate", "eventInfo", eventInfo)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiEventUpdate: intermediateResults = %d", intermediateResults); + eventInfo->iterationConverged = fmiTrue; + eventInfo->stateValueReferencesChanged = fmiFalse; + eventInfo->stateValuesChanged = fmiFalse; + eventInfo->terminateSimulation = fmiFalse; + eventInfo->upcomingTimeEvent = fmiFalse; + eventUpdate(comp, eventInfo); // to be implemented by the includer of this file + return fmiOK; +} + +fmiStatus fmiCompletedIntegratorStep(fmiComponent c, fmiBoolean* callEventUpdate){ + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiCompletedIntegratorStep", modelInitialized)) + return fmiError; + if (nullPointer(comp, "fmiCompletedIntegratorStep", "callEventUpdate", callEventUpdate)) + return fmiError; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiCompletedIntegratorStep"); + *callEventUpdate = fmiFalse; + return fmiOK; +} + +fmiStatus fmiGetStateValueReferences(fmiComponent c, fmiValueReference vrx[], size_t nx){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetStateValueReferences", not_modelError)) + return fmiError; + if (invalidNumber(comp, "fmiGetStateValueReferences", "nx", nx, NUMBER_OF_STATES)) + return fmiError; + if (nullPointer(comp, "fmiGetStateValueReferences", "vrx[]", vrx)) + return fmiError; +#if NUMBER_OF_REALS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetStateValueReferences: vrx[%d] = %d", i, vrx[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiGetContinuousStates(fmiComponent c, fmiReal states[], size_t nx){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetContinuousStates", not_modelError)) + return fmiError; + if (invalidNumber(comp, "fmiGetContinuousStates", "nx", nx, NUMBER_OF_STATES)) + return fmiError; + if (nullPointer(comp, "fmiGetContinuousStates", "states[]", states)) + return fmiError; +#if NUMBER_OF_REALS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetContinuousStates: #r%u# = %.16g", vr, states[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiGetNominalContinuousStates(fmiComponent c, fmiReal x_nominal[], size_t nx){ + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetNominalContinuousStates", not_modelError)) + return fmiError; + if (invalidNumber(comp, "fmiGetNominalContinuousStates", "nx", nx, NUMBER_OF_STATES)) + return fmiError; + if (nullPointer(comp, "fmiGetNominalContinuousStates", "x_nominal[]", x_nominal)) + return fmiError; + x_nominal[0] = 1; + if (comp->loggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetNominalContinuousStates: x_nominal[0..%d] = 1.0", nx-1); + for (i=0; i0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetDerivatives: #r%d# = %.16g", vr, derivatives[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiGetEventIndicators(fmiComponent c, fmiReal eventIndicators[], size_t ni) { + int i; + ModelInstance* comp = (ModelInstance *)c; + if (invalidState(comp, "fmiGetEventIndicators", not_modelError)) + return fmiError; + if (invalidNumber(comp, "fmiGetEventIndicators", "ni", ni, NUMBER_OF_EVENT_INDICATORS)) + return fmiError; +#if NUMBER_OF_EVENT_INDICATORS>0 + for (i=0; iloggingOn) comp->functions.logger(c, comp->instanceName, fmiOK, "log", + "fmiGetEventIndicators: z%d = %.16g", i, eventIndicators[i]); + } +#endif + return fmiOK; +} + +fmiStatus fmiTerminate(fmiComponent c){ + return terminate("fmiTerminate", c); +} + +void fmiFreeModelInstance(fmiComponent c) { + freeInstance("fmiFreeModelInstance", c); +} + +#endif // Model Exchange 1.0 diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/fmuTemplate.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/fmuTemplate.h new file mode 100644 index 00000000..486bd406 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/fmuTemplate.h @@ -0,0 +1,49 @@ +/* ---------------------------------------------------------------------------* + * fmuTemplate.h + * Definitions used in fmiModelFunctions.c and by the includer of this file + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +#include +#include +#include + +#ifdef FMI_COSIMULATION +#include "fmiFunctions.h" +#else +#include "fmiModelFunctions.h" +#endif + +// macros used to define variables +#define r(vr) comp->r[vr] +#define i(vr) comp->i[vr] +#define b(vr) comp->b[vr] +#define s(vr) comp->s[vr] +#define pos(z) comp->isPositive[z] +#define copy(vr, value) setString(comp, vr, value) + +#define not_modelError (modelInstantiated|modelInitialized|modelTerminated) + +typedef enum { + modelInstantiated = 1<<0, + modelInitialized = 1<<1, + modelTerminated = 1<<2, + modelError = 1<<3 +} ModelState; + +typedef struct { + fmiReal *r; + fmiInteger *i; + fmiBoolean *b; + fmiString *s; + fmiBoolean *isPositive; + fmiReal time; + fmiString instanceName; + fmiString GUID; + fmiCallbackFunctions functions; + fmiBoolean loggingOn; + ModelState state; +#ifdef FMI_COSIMULATION + fmiEventInfo eventInfo; +#endif +} ModelInstance; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/_main.html new file mode 100644 index 00000000..8850b0d8 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/_main.html @@ -0,0 +1,18 @@ + + + Documentation for inc.fmu + + + +

inc.fmu

+This FMU generates time events to increment an integer counter every second and terminates simulation at t=12 sec. +
+ +
+The figure shows the solution computed with Silver. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/inc.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/inc.c new file mode 100644 index 00000000..8440dcd5 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/inc.c @@ -0,0 +1,56 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU - increments an int counter every second. + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER inc +#define MODEL_GUID "{8c4e810f-3df3-4a00-8276-176fa3c9f008}" + +// define model size +#define NUMBER_OF_REALS 0 +#define NUMBER_OF_INTEGERS 1 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_STATES 0 +#define NUMBER_OF_EVENT_INDICATORS 0 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define counter_ 0 + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + i(counter_) = 1; +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { + eventInfo->upcomingTimeEvent = fmiTrue; + eventInfo->nextEventTime = 1 + comp->time; +} + +// called by fmiEventUpdate() after setting eventInfo to defaults +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { + i(counter_) += 1; + if (i(counter_) == 13) + eventInfo->terminateSimulation = fmiTrue; + else { + eventInfo->upcomingTimeEvent = fmiTrue; + eventInfo->nextEventTime = 1 + comp->time; + } +} + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/modelDescription.xml new file mode 100644 index 00000000..58ce6f81 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/modelDescription.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/plot_counter.PNG b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/plot_counter.PNG new file mode 100644 index 00000000..d3ec25da Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/inc/plot_counter.PNG differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/me.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/me.xml new file mode 100644 index 00000000..5ecace66 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/me.xml @@ -0,0 +1 @@ + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/_main.html new file mode 100644 index 00000000..082d5145 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/_main.html @@ -0,0 +1,19 @@ + + + Documentation for values.fmu + + + +

values.fmu

+ This FMU demonstrates the use of all four scalar FMU data types + and terminates simulation at t=12 sec. + +
+The figure shows the solution computed with fmusim using the command +fmusim me fmu\me\values.fmu 12 12. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/modelDescription.xml new file mode 100644 index 00000000..3673a616 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/modelDescription.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/values.PNG b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/values.PNG new file mode 100644 index 00000000..45eaf966 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/values.PNG differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/values.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/values.c new file mode 100644 index 00000000..536a2904 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/values/values.c @@ -0,0 +1,85 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU + * This demonstrates the use of all FMU variable types. + * (c) 2010 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER values +#define MODEL_GUID "{8c4e810f-3df3-4a00-8276-176fa3c9f004}" + +// define model size +#define NUMBER_OF_REALS 2 +#define NUMBER_OF_INTEGERS 2 +#define NUMBER_OF_BOOLEANS 2 +#define NUMBER_OF_STRINGS 2 +#define NUMBER_OF_STATES 1 +#define NUMBER_OF_EVENT_INDICATORS 0 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define x_ 0 +#define der_x_ 1 +#define int_in_ 0 +#define int_out_ 1 +#define bool_in_ 0 +#define bool_out_ 1 +#define string_in_ 0 +#define string_out_ 1 + +// define state vector as vector of value references +#define STATES { x_ } + +const char* month[] = { + "jan","feb","march","april","may","june","july", + "august","sept","october","november","december" +}; + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + r(x_) = 1; + i(int_in_) = 2; + i(int_out_) = 0; + b(bool_in_) = fmiTrue; + b(bool_out_) = fmiFalse; + copy(string_in_, "a string"); + copy(string_out_, month[0]); +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { + eventInfo->upcomingTimeEvent = fmiTrue; + eventInfo->nextEventTime = 1 + comp->time; +} + +// called by fmiGetReal, fmiGetContinuousStates and fmiGetDerivatives +fmiReal getReal(ModelInstance* comp, fmiValueReference vr){ + switch (vr) { + case x_ : return r(x_); + case der_x_ : return - r(x_); + default: return 0; + } +} + +// called by fmiEventUpdate() after setting eventInfo to defaults +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { + eventInfo->upcomingTimeEvent = fmiTrue; + eventInfo->nextEventTime = 1 + comp->time; + i(int_out_) += 1; + b(bool_out_) = !b(bool_out_); + if (i(int_out_)<12) copy(string_out_, month[i(int_out_)]); + else eventInfo->terminateSimulation = fmiTrue; +} + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/_main.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/_main.html new file mode 100644 index 00000000..07875f40 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/_main.html @@ -0,0 +1,23 @@ + + +Documentation for vanDerPol.fmu + + + +

vanDerPol.fmu

+This FMU implements the famous +Van der Pol oscillator. +
    +
  • der(x0) = x1
  • +
  • der(x1) = mu * ((1 - x0 * x0) * x1) - x0
  • +
+ +
+The figure shows the solution computed with Silver +for start values x0 = 2, x1 = 0, mu = 1. + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/model.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/model.png new file mode 100644 index 00000000..8d23e9a9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/model.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/modelDescription.xml new file mode 100644 index 00000000..ca44c3f3 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/modelDescription.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/plot_states.png b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/plot_states.png new file mode 100644 index 00000000..05761cd2 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/plot_states.png differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/vanDerPol.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/vanDerPol.c new file mode 100644 index 00000000..c4945207 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/models/vanDerPol/vanDerPol.c @@ -0,0 +1,75 @@ +/* ---------------------------------------------------------------------------* + * Sample implementation of an FMU - the Van der Pol oscillator. + * See http://en.wikipedia.org/wiki/Van_der_Pol_oscillator + * + * der(x0) = x1 + * der(x1) = mu * ((1 - x0 ^ 2) * x1) - x0; + * + * start values: x0=2, x1=0, mue=1 + * + * (c) 2011 QTronic GmbH + * ---------------------------------------------------------------------------*/ + +// define class name and unique id +#define MODEL_IDENTIFIER vanDerPol +#define MODEL_GUID "{8c4e810f-3da3-4a00-8276-176fa3c9f000}" + +// define model size +#define NUMBER_OF_REALS 5 +#define NUMBER_OF_INTEGERS 0 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_STATES 2 +#define NUMBER_OF_EVENT_INDICATORS 0 + +// include fmu header files, typedefs and macros +#include "fmuTemplate.h" + +// define all model variables and their value references +// conventions used here: +// - if x is a variable, then macro x_ is its variable reference +// - the vr of a variable is its index in array r, i, b or s +// - if k is the vr of a real state, then k+1 is the vr of its derivative +#define x0_ 0 +#define der_x0_ 1 +#define x1_ 2 +#define der_x1_ 3 +#define mu_ 4 + +// define state vector as vector of value references +#define STATES { x0_, x1_ } + +// called by fmiInstantiateModel +// Set values for all variables that define a start value +// Settings used unless changed by fmiSetX before fmiInitialize +void setStartValues(ModelInstance *comp) { + r(x0_) = 2; + r(x1_) = 0; + r(mu_) = 1; +} + +// called by fmiInitialize() after setting eventInfo to defaults +// Used to set the first time event, if any. +void initialize(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +// called by fmiGetReal, fmiGetContinuousStates and fmiGetDerivatives +fmiReal getReal(ModelInstance* comp, fmiValueReference vr){ + switch (vr) { + case x0_ : return r(x0_); + case x1_ : return r(x1_); + case der_x0_ : return r(x1_); + case der_x1_ : return r(mu_) * ((1.0-r(x0_)*r(x0_))*r(x1_)) - r(x0_); + case mu_ : return r(mu_); + default: return 0; + } +} + +// Used to set the next time event, if any. +void eventUpdate(fmiComponent comp, fmiEventInfo* eventInfo) { +} + +// include code that implements the FMI based on the above definitions +#include "fmuTemplate.c" + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/COPYING.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/COPYING.txt new file mode 100644 index 00000000..90422175 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/COPYING.txt @@ -0,0 +1,24 @@ +Files expat.h, expat_external.h and libexpatMT.lib + +Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + and Clark Cooper +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/expat.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/expat.h new file mode 100644 index 00000000..6c2b6ff5 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/expat.h @@ -0,0 +1,1014 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_INCLUDED +#define Expat_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include +#include "expat_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, + /* Added in 2.0. */ + XML_ERROR_RESERVED_PREFIX_XML, + XML_ERROR_RESERVED_PREFIX_XMLNS, + XML_ERROR_RESERVED_NAMESPACE_URI +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, + void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { + XML_INITIALIZED, + XML_PARSING, + XML_FINISHED, + XML_SUSPENDED +}; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR, + XML_FEATURE_NS, + XML_FEATURE_LARGE_SIZE + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 0 +#define XML_MICRO_VERSION 1 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/expat_external.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/expat_external.h new file mode 100644 index 00000000..bb83a995 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/expat_external.h @@ -0,0 +1,115 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(_MSC_VER) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +typedef __int64 XML_Index; +typedef unsigned __int64 XML_Size; +#else +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#endif +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/libexpatMT.lib b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/libexpatMT.lib new file mode 100644 index 00000000..2436f617 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/libexpatMT.lib differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/sim_support.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/sim_support.c new file mode 100644 index 00000000..32b5439b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/sim_support.c @@ -0,0 +1,476 @@ +/* ------------------------------------------------------------------------- + * sim_support.c + * Functions used by both FMU simulators fmusim_me and fmusim_cs + * to parse command-line arguments, to unzip and load an fmu, + * to write CSV file, and more. + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +#ifdef FMI_COSIMULATION +#include "fmi_cs.h" +#else +#include "fmi_me.h" +#endif + +#include "sim_support.h" + +extern FMU fmu; + +int unzip(const char *zipPath, const char *outPath) { + int code; + char cwd[BUFSIZE]; + char binPath[BUFSIZE]; + int n = strlen(UNZIP_CMD) + strlen(outPath) + 1 + strlen(zipPath) + 9; + char* cmd = (char*)calloc(sizeof(char), n); + + // remember current directory + if (!GetCurrentDirectory(BUFSIZE, cwd)) { + printf ("error: Could not get current directory\n"); + return 0; // error + } + + // change to %FMUSDK_HOME%\bin to find 7z.dll and 7z.exe + if (!GetEnvironmentVariable("FMUSDK_HOME", binPath, BUFSIZE)) { + if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + printf ("error: Environment variable FMUSDK_HOME not defined\n"); + } + else { + printf ("error: Could not get value of FMUSDK_HOME\n"); + } + return 0; // error + } + strcat(binPath, "\\bin"); + if (!SetCurrentDirectory(binPath)) { + printf ("error: could not change to directory '%s'\n", binPath); + return 0; // error + } + + // run the unzip command + // remove "> NUL" to see the unzip protocol + sprintf(cmd, "%s%s \"%s\" > NUL", UNZIP_CMD, outPath, zipPath); + // printf("cmd='%s'\n", cmd); + code = system(cmd); + free(cmd); + if (code!=SEVEN_ZIP_NO_ERROR) { + switch (code) { + printf("7z: "); + case SEVEN_ZIP_WARNING: printf("warning\n"); break; + case SEVEN_ZIP_ERROR: printf("error\n"); break; + case SEVEN_ZIP_COMMAND_LINE_ERROR: printf("command line error\n"); break; + case SEVEN_ZIP_OUT_OF_MEMORY: printf("out of memory\n"); break; + case SEVEN_ZIP_STOPPED_BY_USER: printf("stopped by user\n"); break; + default: printf("unknown problem\n"); + } + } + + // restore current directory + SetCurrentDirectory(cwd); + + return (code==SEVEN_ZIP_NO_ERROR || code==SEVEN_ZIP_WARNING) ? 1 : 0; +} + +// fileName is an absolute path, e.g. C:\test\a.fmu +// or relative to the current dir, e.g. ..\test\a.fmu +// Does not check for existence of the file +static char* getFmuPath(const char* fileName){ + char pathName[MAX_PATH]; + int n = GetFullPathName(fileName, MAX_PATH, pathName, NULL); + return n ? strdup(pathName) : NULL; +} + +static char* getTmpPath() { + char tmpPath[BUFSIZE]; + if(! GetTempPath(BUFSIZE, tmpPath)) { + printf ("error: Could not find temporary disk space\n"); + return NULL; + } + strcat(tmpPath, "fmu\\"); + return strdup(tmpPath); +} + +static void* getAdr(int* s, FMU *fmu, const char* functionName){ + char name[BUFSIZE]; + void* fp; + sprintf(name, "%s_%s", getModelIdentifier(fmu->modelDescription), functionName); + fp = GetProcAddress(fmu->dllHandle, name); + if (!fp) { + printf ("warning: Function %s not found in dll\n", name); + *s = 0; // mark dll load as 'failed' + } + return fp; +} + +// Load the given dll and set function pointers in fmu +// Return 0 to indicate failure +static int loadDll(const char* dllPath, FMU *fmu) { + int x = 1, s = 1; + HANDLE h = LoadLibrary(dllPath); + if (!h) { + printf("error: Could not load %s\n", dllPath); + return 0; // failure + } + fmu->dllHandle = h; + +#ifdef FMI_COSIMULATION + fmu->getTypesPlatform = (fGetTypesPlatform) getAdr(&s, fmu, "fmiGetTypesPlatform"); + if (s==0) { + s = 1; // work around bug for FMUs exported using Dymola 2012 and SimulationX 3.x + fmu->getTypesPlatform = (fGetTypesPlatform) getAdr(&s, fmu, "fmiGetModelTypesPlatform"); + if (s==1) printf(" using fmiGetModelTypesPlatform instead\n", dllPath); + } + fmu->instantiateSlave = (fInstantiateSlave) getAdr(&s, fmu, "fmiInstantiateSlave"); + fmu->initializeSlave = (fInitializeSlave) getAdr(&s, fmu, "fmiInitializeSlave"); + fmu->terminateSlave = (fTerminateSlave) getAdr(&s, fmu, "fmiTerminateSlave"); + fmu->resetSlave = (fResetSlave) getAdr(&s, fmu, "fmiResetSlave"); + fmu->freeSlaveInstance = (fFreeSlaveInstance) getAdr(&s, fmu, "fmiFreeSlaveInstance"); + fmu->setRealInputDerivatives = (fSetRealInputDerivatives) getAdr(&s, fmu, "fmiSetRealInputDerivatives"); + fmu->getRealOutputDerivatives = (fGetRealOutputDerivatives) getAdr(&s, fmu, "fmiGetRealOutputDerivatives"); + fmu->cancelStep = (fCancelStep) getAdr(&s, fmu, "fmiCancelStep"); + fmu->doStep = (fDoStep) getAdr(&s, fmu, "fmiDoStep"); + // SimulationX 3.4 and 3.5 do not yet export getStatus and getXStatus: do not count this as failure here + fmu->getStatus = (fGetStatus) getAdr(&x, fmu, "fmiGetStatus"); + fmu->getRealStatus = (fGetRealStatus) getAdr(&x, fmu, "fmiGetRealStatus"); + fmu->getIntegerStatus = (fGetIntegerStatus) getAdr(&x, fmu, "fmiGetIntegerStatus"); + fmu->getBooleanStatus = (fGetBooleanStatus) getAdr(&x, fmu, "fmiGetBooleanStatus"); + fmu->getStringStatus = (fGetStringStatus) getAdr(&x, fmu, "fmiGetStringStatus"); + +#else // FMI for Model Exchange 1.0 + fmu->getModelTypesPlatform = (fGetModelTypesPlatform) getAdr(&s, fmu, "fmiGetModelTypesPlatform"); + fmu->instantiateModel = (fInstantiateModel) getAdr(&s, fmu, "fmiInstantiateModel"); + fmu->freeModelInstance = (fFreeModelInstance) getAdr(&s, fmu, "fmiFreeModelInstance"); + fmu->setTime = (fSetTime) getAdr(&s, fmu, "fmiSetTime"); + fmu->setContinuousStates = (fSetContinuousStates)getAdr(&s, fmu, "fmiSetContinuousStates"); + fmu->completedIntegratorStep = (fCompletedIntegratorStep)getAdr(&s, fmu, "fmiCompletedIntegratorStep"); + fmu->initialize = (fInitialize) getAdr(&s, fmu, "fmiInitialize"); + fmu->getDerivatives = (fGetDerivatives) getAdr(&s, fmu, "fmiGetDerivatives"); + fmu->getEventIndicators = (fGetEventIndicators) getAdr(&s, fmu, "fmiGetEventIndicators"); + fmu->eventUpdate = (fEventUpdate) getAdr(&s, fmu, "fmiEventUpdate"); + fmu->getContinuousStates = (fGetContinuousStates)getAdr(&s, fmu, "fmiGetContinuousStates"); + fmu->getNominalContinuousStates = (fGetNominalContinuousStates)getAdr(&s, fmu, "fmiGetNominalContinuousStates"); + fmu->getStateValueReferences = (fGetStateValueReferences)getAdr(&s, fmu, "fmiGetStateValueReferences"); + fmu->terminate = (fTerminate) getAdr(&s, fmu, "fmiTerminate"); +#endif + fmu->getVersion = (fGetVersion) getAdr(&s, fmu, "fmiGetVersion"); + fmu->setDebugLogging = (fSetDebugLogging) getAdr(&s, fmu, "fmiSetDebugLogging"); + fmu->setReal = (fSetReal) getAdr(&s, fmu, "fmiSetReal"); + fmu->setInteger = (fSetInteger) getAdr(&s, fmu, "fmiSetInteger"); + fmu->setBoolean = (fSetBoolean) getAdr(&s, fmu, "fmiSetBoolean"); + fmu->setString = (fSetString) getAdr(&s, fmu, "fmiSetString"); + fmu->getReal = (fGetReal) getAdr(&s, fmu, "fmiGetReal"); + fmu->getInteger = (fGetInteger) getAdr(&s, fmu, "fmiGetInteger"); + fmu->getBoolean = (fGetBoolean) getAdr(&s, fmu, "fmiGetBoolean"); + fmu->getString = (fGetString) getAdr(&s, fmu, "fmiGetString"); + return s; +} + +static void printModelDescription(ModelDescription* md){ + Element* e = (Element*)md; + int i; + printf("%s\n", elmNames[e->type]); + for (i=0; in; i+=2) + printf(" %s=%s\n", e->attributes[i], e->attributes[i+1]); +#ifdef FMI_COSIMULATION + if (!md->cosimulation) { + printf("error: No Implementation element found in model description. This FMU is not for Co-Simulation.\n"); + exit(EXIT_FAILURE); + } + e = md->cosimulation->capabilities; + printf("%s\n", elmNames[e->type]); + for (i=0; in; i+=2) + printf(" %s=%s\n", e->attributes[i], e->attributes[i+1]); +#endif // FMI_COSIMULATION +} + +void loadFMU(const char* fmuFileName) { + char* fmuPath; + char* tmpPath; + char* xmlPath; + char* dllPath; + + // get absolute path to FMU, NULL if not found + fmuPath = getFmuPath(fmuFileName); + if (!fmuPath) exit(EXIT_FAILURE); + + // unzip the FMU to the tmpPath directory + tmpPath = getTmpPath(); + if (!unzip(fmuPath, tmpPath)) exit(EXIT_FAILURE); + + // parse tmpPath\modelDescription.xml + xmlPath = calloc(sizeof(char), strlen(tmpPath) + strlen(XML_FILE) + 1); + sprintf(xmlPath, "%s%s", tmpPath, XML_FILE); + fmu.modelDescription = parse(xmlPath); + free(xmlPath); + if (!fmu.modelDescription) exit(EXIT_FAILURE); + printModelDescription(fmu.modelDescription); + + // load the FMU dll + dllPath = calloc(sizeof(char), strlen(tmpPath) + strlen(DLL_DIR) + + strlen( getModelIdentifier(fmu.modelDescription)) + strlen(".dll") + 1); + sprintf(dllPath,"%s%s%s.dll", tmpPath, DLL_DIR, getModelIdentifier(fmu.modelDescription)); + if (!loadDll(dllPath, &fmu)) exit(EXIT_FAILURE); + free(dllPath); + free(fmuPath); + free(tmpPath); +} + +static void doubleToCommaString(char* buffer, double r){ + char* comma; + sprintf(buffer, "%.16g", r); + comma = strchr(buffer, '.'); + if (comma) *comma = ','; +} + +// output time and all non-alias variables in CSV format +// if separator is ',', columns are separated by ',' and '.' is used for floating-point numbers. +// otherwise, the given separator (e.g. ';' or '\t') is to separate columns, and ',' is used +// as decimal dot in floating-point numbers. +void outputRow(FMU *fmu, fmiComponent c, double time, FILE* file, char separator, boolean header) { + int k; + fmiReal r; + fmiInteger i; + fmiBoolean b; + fmiString s; + fmiValueReference vr; + ScalarVariable** vars = fmu->modelDescription->modelVariables; + char buffer[32]; + + // print first column + if (header) + fprintf(file, "time"); + else { + if (separator==',') + fprintf(file, "%.16g", time); + else { + // separator is e.g. ';' or '\t' + doubleToCommaString(buffer, time); + fprintf(file, "%s", buffer); + } + } + + // print all other columns + for (k=0; vars[k]; k++) { + ScalarVariable* sv = vars[k]; + if (getAlias(sv)!=enu_noAlias) continue; + if (header) { + // output names only + if (separator==',') { + // treat array element, e.g. print a[1, 2] as a[1.2] + char* s = getName(sv); + fprintf(file, "%c", separator); + while (*s) { + if (*s!=' ') fprintf(file, "%c", *s==',' ? '.' : *s); + s++; + } + } + else + fprintf(file, "%c%s", separator, getName(sv)); + } + else { + // output values + vr = getValueReference(sv); + switch (sv->typeSpec->type){ + case elm_Real: + fmu->getReal(c, &vr, 1, &r); + if (separator==',') + fprintf(file, ",%.16g", r); + else { + // separator is e.g. ';' or '\t' + doubleToCommaString(buffer, r); + fprintf(file, "%c%s", separator, buffer); + } + break; + case elm_Integer: + case elm_Enumeration: + fmu->getInteger(c, &vr, 1, &i); + fprintf(file, "%c%d", separator, i); + break; + case elm_Boolean: + fmu->getBoolean(c, &vr, 1, &b); + fprintf(file, "%c%d", separator, b); + break; + case elm_String: + fmu->getString(c, &vr, 1, &s); + fprintf(file, "%c%s", separator, s); + break; + default: + fprintf(file, "%cNoValueForType=%d", separator,sv->typeSpec->type); + } + } + } // for + + // terminate this row + fprintf(file, "\n"); +} + +static const char* fmiStatusToString(fmiStatus status){ + switch (status){ + case fmiOK: return "ok"; + case fmiWarning: return "warning"; + case fmiDiscard: return "discard"; + case fmiError: return "error"; + case fmiFatal: return "fatal"; +#ifdef FMI_COSIMULATION + case fmiPending: return "fmiPending"; +#endif + default: return "?"; + } +} + +// search a fmu for the given variable +// return NULL if not found or vr = fmiUndefinedValueReference +static ScalarVariable* getSV(FMU* fmu, char type, fmiValueReference vr) { + int i; + Elm tp; + ScalarVariable** vars = fmu->modelDescription->modelVariables; + if (vr==fmiUndefinedValueReference) return NULL; + switch (type) { + case 'r': tp = elm_Real; break; + case 'i': tp = elm_Integer; break; + case 'b': tp = elm_Boolean; break; + case 's': tp = elm_String; break; + } + for (i=0; vars[i]; i++) { + ScalarVariable* sv = vars[i]; + if (vr==getValueReference(sv) && tp==sv->typeSpec->type) + return sv; + } + return NULL; +} + +// replace e.g. #r1365# by variable name and ## by # in message +// copies the result to buffer +static void replaceRefsInMessage(const char* msg, char* buffer, int nBuffer, FMU* fmu){ + int i=0; // position in msg + int k=0; // position in buffer + int n; + char c = msg[i]; + while (c!='\0' && k < nBuffer) { + if (c!='#') { + buffer[k++]=c; + i++; + c = msg[i]; + } + else { + char* end = strchr(msg+i+1, '#'); + if (!end) { + printf("unmatched '#' in '%s'\n", msg); + buffer[k++]='#'; + break; + } + n = end - (msg+i); + if (n==1) { + // ## detected, output # + buffer[k++]='#'; + i += 2; + c = msg[i]; + } + else { + char type = msg[i+1]; // one of ribs + fmiValueReference vr; + int nvr = sscanf(msg+i+2, "%u", &vr); + if (nvr==1) { + // vr of type detected, e.g. #r12# + ScalarVariable* sv = getSV(fmu, type, vr); + const char* name = sv ? getName(sv) : "?"; + sprintf(buffer+k, "%s", name); + k += strlen(name); + i += (n+1); + c = msg[i]; + } + else { + // could not parse the number + printf("illegal value reference at position %d in '%s'\n", i+2, msg); + buffer[k++]='#'; + break; + } + } + } + } // while + buffer[k] = '\0'; +} + +#define MAX_MSG_SIZE 1000 +void fmuLogger(fmiComponent c, fmiString instanceName, fmiStatus status, + fmiString category, fmiString message, ...) { + char msg[MAX_MSG_SIZE]; + char* copy; + va_list argp; + + // replace C format strings + va_start(argp, message); + vsprintf(msg, message, argp); + + // replace e.g. ## and #r12# + copy = strdup(msg); + replaceRefsInMessage(copy, msg, MAX_MSG_SIZE, &fmu); + free(copy); + + // print the final message + if (!instanceName) instanceName = "?"; + if (!category) category = "?"; + printf("%s %s (%s): %s\n", fmiStatusToString(status), instanceName, category, msg); +} + +int error(const char* message){ + printf("%s\n", message); + return 0; +} + +void parseArguments(int argc, char *argv[], char** fmuFileName, double* tEnd, double* h, int* loggingOn, char* csv_separator) { + // parse command line arguments + if (argc>1) { + *fmuFileName = argv[1]; + } + else { + printf("error: no fmu file\n"); + printHelp(argv[0]); + exit(EXIT_FAILURE); + } + if (argc>2) { + if (sscanf(argv[2],"%lf", tEnd) != 1) { + printf("error: The given end time (%s) is not a number\n", argv[2]); + exit(EXIT_FAILURE); + } + } + if (argc>3) { + if (sscanf(argv[3],"%lf", h) != 1) { + printf("error: The given stepsize (%s) is not a number\n", argv[3]); + exit(EXIT_FAILURE); + } + } + if (argc>4) { + if (sscanf(argv[4],"%d", loggingOn) != 1 || *loggingOn<0 || *loggingOn>1) { + printf("error: The given logging flag (%s) is not boolean\n", argv[4]); + exit(EXIT_FAILURE); + } + } + if (argc>5) { + if (strlen(argv[5]) != 1) { + printf("error: The given CSV separator char (%s) is not valid\n", argv[5]); + exit(EXIT_FAILURE); + } + switch (argv[5][0]) { + case 'c': *csv_separator = ','; break; // comma + case 's': *csv_separator = ';'; break; // semicolon + default: *csv_separator = argv[5][0]; break; // any other char + } + } + if (argc>6) { + printf("warning: Ignoring %d additional arguments: %s ...\n", argc-6, argv[6]); + printHelp(argv[0]); + } +} + +void printHelp(const char* fmusim) { + printf("command syntax: %s \n", fmusim); + printf(" .... path to FMU, relative to current dir or absolute, required\n"); + printf(" ......... end time of simulation, optional, defaults to 1.0 sec\n"); + printf(" ............ step size of simulation, optional, defaults to 0.1 sec\n"); + printf(" .... 1 to activate logging, optional, defaults to 0\n"); + printf(" . separator in csv file, optional, c for ';', s for';', defaults to c\n"); +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/sim_support.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/sim_support.h new file mode 100644 index 00000000..648c8b59 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/sim_support.h @@ -0,0 +1,31 @@ +/* ------------------------------------------------------------------------- + * sim_support.h + * Functions used by the FMU simulatios fmusim_me and fmusim_cs. + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +// Used 7z options, version 4.57: +// -x Extracts files from an archive with their full paths in the current dir, or in an output dir if specified +// -aoa Overwrite All existing files without prompt +// -o Specifies a destination directory where files are to be extracted +#define UNZIP_CMD "7z x -aoa -o" +#define XML_FILE "modelDescription.xml" +#define DLL_DIR "binaries\\win32\\" +#define RESULT_FILE "result.csv" +#define BUFSIZE 4096 + +// return codes of the 7z command line tool +#define SEVEN_ZIP_NO_ERROR 0 // success +#define SEVEN_ZIP_WARNING 1 // e.g., one or more files were locked during zip +#define SEVEN_ZIP_ERROR 2 +#define SEVEN_ZIP_COMMAND_LINE_ERROR 7 +#define SEVEN_ZIP_OUT_OF_MEMORY 8 +#define SEVEN_ZIP_STOPPED_BY_USER 255 + +void fmuLogger(fmiComponent c, fmiString instanceName, fmiStatus status, fmiString category, fmiString message, ...); +int unzip(const char *zipPath, const char *outPath); +void parseArguments(int argc, char *argv[], char** fmuFileName, double* tEnd, double* h, int* loggingOn, char* csv_separator); +void loadFMU(const char* fmuFileName); +void outputRow(FMU *fmu, fmiComponent c, double time, FILE* file, char separator, boolean header); +int error(const char* message); +void printHelp(const char* fmusim); diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/stack.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/stack.c new file mode 100644 index 00000000..042b796b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/stack.c @@ -0,0 +1,85 @@ +/* ------------------------------------------------------------------------- + * stack.c + * A stack of pointers. + * Copyright 2010 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#include +#include +#include +#include "stack.h" + +Stack* stackNew(int initialSize, int inc){ + Stack* s = (Stack*)malloc(sizeof(Stack)); + s->stack = NULL; + s->stackSize = 0; + s->stackPos = -1; + s->initialSize = initialSize; + s->inc = inc; + return s; +} + +int stackIsEmpty(Stack* s) { + return s->stackPos == -1; +} + +// add an element to stack and grow stack if required +// returns 1 to indicate success and 0 for error +int stackPush(Stack* s, void* e) { + s->stackPos++; + if (s->stackPos==s->stackSize){ + s->stackSize += (s->stack ? s->inc: s->initialSize); + s->stack = (void**) realloc(s->stack, s->stackSize * sizeof(void*)); + if (!s->stack) return 0; // error; + } + s->stack[s->stackPos] = e; + return 1; // success +} + +// return top element (possibly NULL), if stack not empty +// runtime error if stack is empty +void* stackPeek(Stack* s){ + assert(!stackIsEmpty(s)); + return s->stack[s->stackPos]; +} + +// remove top element (possibly NULL) from stack and return it +// runtime error if stack is empty +void* stackPop(Stack* s){ + assert(!stackIsEmpty(s)); + return s->stack[s->stackPos--]; +} + +// return the last n elements as null terminated array, +// or NULL if memory allocation fails +void** stackLastPopedAsArray0(Stack* s, int n){ + int i; + void** array = (void**)malloc((n + 1)*sizeof(void*)); + if (! array) return NULL; // failure + for (i=0; istack[i+ s->stackPos + 1]; + } + array[n]=NULL; // terminating NULL + return array; +} + +// return stack as possibly empty array, or NULL if memory allocation fails +// On sucessful return, the stack is empty. +void** stackPopAllAsArray(Stack* s, int *size) { + int i; + void** array = (void**)malloc((s->stackPos + 1)*sizeof(void*)); + if (! array) return NULL; // failure + *size = s->stackPos + 1; + for (i=0; i<*size; i++) + array[i] = s->stack[i]; + s->stackPos = -1; + return array; +} + +// release the given stack +void stackFree(Stack* s){ + if (s->stack) free(s->stack); + free(s); +} + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/stack.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/stack.h new file mode 100644 index 00000000..a52977fa --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/stack.h @@ -0,0 +1,28 @@ +/* ------------------------------------------------------------------------- + * stack.c + * A stack of pointers. + * Copyright 2010 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#ifndef STACK_H +#define STACK_H + +typedef struct { + void** stack; + int stackSize; // allocated size of stack + int stackPos; // array index of top element, -1 if stack is empty. + int initialSize; // how many element to allocate initially + int inc; // how many elements to allocate when stack gets full +} Stack; + +Stack* stackNew(int initialSize, int inc); +int stackIsEmpty(Stack* s); +int stackPush(Stack* s, void* e); +void* stackPeek(Stack* s); +void* stackPop(Stack* s); +void** stackPopAllAsArray(Stack* s, int *size); +void** stackLastPopedAsArray0(Stack* s, int n); +void stackFree(Stack* s); + +#endif // STACK_H + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/xml_parser.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/xml_parser.c new file mode 100644 index 00000000..93e62162 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/xml_parser.c @@ -0,0 +1,860 @@ +/* ------------------------------------------------------------------------- + * xml_Parser.c + * A parser for file modelVariables.xml of an FMU. + * The parser creates an AST (abstract syntax tree) for a given XML file. + * The root node of the AST is of type ModelDescription. + * Validation already performed by this parser + * - check for match of open/close elements (performed by Expat) + * - ceck element, attribute and enum value names, all case sensitive + * - check for each element that is has the expected parent element + * - check for correct sequence of elements + * - check that all decalaredType values reference an existing Type + * Validation to be performed by this parser + * - check for each attribute value that it is of the expected type + * - check that required attributes are present + * - check that dependencies are only declared for outputs and + * refer only to inputs + * Author: Jakob Mauss + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#include +#include +#include +#include "xml_parser.h" + +const char *elmNames[SIZEOF_ELM] = { + "fmiModelDescription","UnitDefinitions","BaseUnit","DisplayUnitDefinition","TypeDefinitions", + "Type","RealType","IntegerType","BooleanType","StringType","EnumerationType","Item", + "DefaultExperiment","VendorAnnotations","Tool","Annotation", "ModelVariables","ScalarVariable", + "DirectDependency","Name","Real","Integer","Boolean","String","Enumeration", + "Implementation","CoSimulation_StandAlone","CoSimulation_Tool","Model","File","Capabilities" +}; + +const char *attNames[SIZEOF_ATT] = { + "fmiVersion","displayUnit","gain","offset","unit","name","description","quantity", "relativeQuantity", + "min","max","nominal","declaredType","start","fixed","startTime","stopTime","tolerance","value", + "valueReference","variability","causality","alias", "modelName","modelIdentifier","guid","author", + "version","generationTool","generationDateAndTime","variableNamingConvention","numberOfContinuousStates", + "numberOfEventIndicators","input", + "canHandleVariableCommunicationStepSize","canHandleEvents","canRejectSteps","canInterpolateInputs", + "maxOutputDerivativeOrder","canRunAsynchronuously","canSignalEvents","canBeInstantiatedOnlyOncePerProcess", + "canNotUseMemoryManagementFunctions","file","entryPoint","manualStart","type" +}; + +const char *enuNames[SIZEOF_ENU] = { + "flat","structured","constant","parameter","discrete","continuous", + "input","output", "internal","none","noAlias","alias","negatedAlias" +}; + +#define ANY_TYPE -1 +#define XMLBUFSIZE 1024 +char text[XMLBUFSIZE]; // XML file is parsed in chunks of length XMLBUFZIZE +XML_Parser parser = NULL; // non-NULL during parsing +Stack* stack = NULL; // the parser stack +char* data = NULL; // buffer that holds element content, see handleData +int skipData=0; // 1 to ignore element content, 0 when recordig content + +// ------------------------------------------------------------------------- +// Low-level functions for inspecting the model description + +const char* getString(void* element, Att a){ + Element* e = (Element*)element; + const char** attr = e->attributes; + int i; + for (i=0; in; i+=2) + if (attr[i]==attNames[a]) return attr[i+1]; + return NULL; +} + +double getDouble(void* element, Att a, ValueStatus* vs){ + double d = 0; + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return d; } + *vs = (1==sscanf(value, "%lf", &d)) ? valueDefined : valueIllegal; + return d; +} + +// getInt() is also used to retrieve Enumeration values from XML, +// e.g. the start value for a variable of user-defined enumeration type. +int getInt(void* element, Att a, ValueStatus* vs){ + int n = 0; + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return n; } + *vs = (1==sscanf(value, "%d", &n)) ? valueDefined : valueIllegal; + return n; +} + +unsigned int getUInt(void* element, Att a, ValueStatus* vs){ + unsigned int u = -1; + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return u; } + *vs = (1==sscanf(value, "%u", &u)) ? valueDefined : valueIllegal; + return u; +} + +char getBoolean(void* element, Att a, ValueStatus* vs){ + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return 0; }; + *vs = valueDefined; + if (!strcmp(value, "true")) return 1; + if (!strcmp(value, "false")) return 0; + *vs = valueIllegal; + return 0; +} + +static int checkEnumValue(const char* enu); + +// Retrieve the value of the given built-in enum attribute. +// If the value is missing, this is marked in the ValueStatus +// and the corresponding default is returned. +// Returns -1 or a globally unique id for the value such that +// enuNames[id] is the string representation of the enum value. +Enu getEnumValue(void* element, Att a, ValueStatus* vs) { + const char* value = getString(element, a); + Enu id = valueDefined; + if (!value) { + *vs = valueMissing; + switch (a) { + case att_variableNamingConvention: return enu_flat; + case att_variability: return enu_continuous; + case att_causality: return enu_internal; + case att_alias: return enu_noAlias; + default: return -1; + } + } + id = checkEnumValue(value); + if (id==-1) *vs = valueIllegal; + return id; +} + +// ------------------------------------------------------------------------- +// Convenience methods for accessing the model description. +// Use is only safe after the ast has been successfuly validated. + +const char* getModelIdentifier(ModelDescription* md) { + const char* modelId = getString(md, att_modelIdentifier); + assert(modelId); // this is a required attribute + return modelId; +} + +int getNumberOfStates(ModelDescription* md) { + ValueStatus vs; + int n = getUInt(md, att_numberOfContinuousStates, &vs); + assert(vs==valueDefined); // this is a required attribute + return n; +} + +int getNumberOfEventIndicators(ModelDescription* md) { + ValueStatus vs; + int n = getInt(md, att_numberOfEventIndicators, &vs); + assert(vs==valueDefined); // this is a required attribute + return n; +} + +// name is a required attribute of ScalarVariable, Type, Item, Annotation, and Tool +const char* getName(void* element) { + const char* name = getString(element, att_name); + assert(name); // this is a required attribute + return name; +} + +// returns one of: input, output, internal, none +// if value is missing, the default internal is returned +Enu getCausality(void* scalarVariable) { + ValueStatus vs; + return getEnumValue(scalarVariable, att_causality, &vs); +} + +// returns one of constant, parameter, discrete, continuous +// if value is missing, the default continuous is returned +Enu getVariability(void* scalarVariable) { + ValueStatus vs; + return getEnumValue(scalarVariable, att_variability, &vs); +} + +// returns one of noAlias, alias, negatedAlias +// if value is missing, the default noAlias is returned +Enu getAlias(void* scalarVariable) { + ValueStatus vs; + return getEnumValue(scalarVariable, att_alias, &vs); +} + +// the vr is unique only for one of the 4 base data types r,i,b,s and +// may also be fmiUndefinedValueReference = 4294967295 = 0xFFFFFFFF +// here, i means integer or enumeration +fmiValueReference getValueReference(void* scalarVariable) { + ValueStatus vs; + fmiValueReference vr = getUInt(scalarVariable, att_valueReference, &vs); + assert(((Element*)scalarVariable)->type == elm_ScalarVariable); + assert(vs==valueDefined); // this is a reqired attribute + return vr; +} + +// the name is unique within a fmu +ScalarVariable* getVariableByName(ModelDescription* md, const char* name) { + int i; + if (md->modelVariables) + for (i=0; md->modelVariables[i]; i++){ + ScalarVariable* sv = (ScalarVariable*)md->modelVariables[i]; + if (!strcmp(getName(sv), name)) return sv; + } + return NULL; +} + +// Enumeration and Integer have the same base type while +// Real, String, Boolean define own base types. +int sameBaseType(Elm t1, Elm t2){ + return t1==t2 || + t1==elm_Enumeration && t2==elm_Integer || + t2==elm_Enumeration && t1==elm_Integer; +} + +// returns NULL if variable not found or vr==fmiUndefinedValueReference +ScalarVariable* getVariable(ModelDescription* md, fmiValueReference vr, Elm type){ + int i; + if (md->modelVariables && vr!=fmiUndefinedValueReference) + for (i=0; md->modelVariables[i]; i++){ + ScalarVariable* sv = (ScalarVariable*)md->modelVariables[i]; + if (sameBaseType(type, sv->typeSpec->type) && getValueReference(sv) == vr) + return sv; + } + return NULL; +} + +Type* getDeclaredType(ModelDescription* md, const char* declaredType){ + int i; + if (declaredType && md->typeDefinitions) + for (i=0; md->typeDefinitions[i]; i++){ + Type* tp = (Type*)md->typeDefinitions[i]; + if (!strcmp(declaredType, getName(tp))) return tp; + } + return NULL; +} + +const char* getString2(ModelDescription* md, void* tp, Att a) { + Type* type; + const char* value = getString(tp, a); + if (value) return value; // found + // search declared type, if any + type = getDeclaredType(md, getString(tp, att_declaredType)); + return type ? getString(type->typeSpec, a) : NULL; +} + +// Get description from variable or from declared type, or NULL. +const char * getDescription(ModelDescription* md, ScalarVariable* sv) { + const char* value = getString(sv, att_description); + Type* type; + if (value) return value; // found + // search declared type, if any + type = getDeclaredType(md, getString(sv->typeSpec, att_declaredType)); + return type ? getString(type, att_description) : NULL; +} + +// Get attribute value from scalar variable given by vr and type, +// incl. default value provided by declared type, if any. +const char * getVariableAttributeString(ModelDescription* md, + fmiValueReference vr, Elm type, Att a){ + const char* value; + const char* declaredType; + Type* tp; + ScalarVariable* sv = getVariable(md, vr, type); + if (!sv) return NULL; + value = getString(sv->typeSpec, a); + if (value) return value; // found + // search declared type, if any + tp = getDeclaredType(md, getString(sv->typeSpec, att_declaredType)); + return tp ? getString(tp->typeSpec, a) : NULL; +} + +// Get attribute value from scalar variable given by vr and type, +// incl. default value provided by declared type, if any. +double getVariableAttributeDouble(ModelDescription* md, + fmiValueReference vr, Elm type, Att a, ValueStatus* vs){ + double d = 0; + const char* value = getVariableAttributeString(md, vr, type, a); + if (!value) { *vs = valueMissing; return d; } + *vs = (1==sscanf(value, "%lf", &d)) ? valueDefined : valueIllegal; + return d; +} + +// Get nominal value from real variable or its declared type. +// Return 1, if no nominal value is defined. +double getNominal(ModelDescription* md, fmiValueReference vr){ + ValueStatus vs; + double nominal = getVariableAttributeDouble(md, vr, elm_Real, att_nominal, &vs); + return vs==valueDefined ? nominal : 1.0; +} + +// ------------------------------------------------------------------------- +// Various checks that log an error and stop the parser + +// Returns 0 to indicate error +static int checkPointer(const void* ptr){ + if (! ptr) { + printf("Out of memory\n"); + if (parser) XML_StopParser(parser, XML_FALSE); + return 0; // error + } + return 1; // success +} + +static int checkName(const char* name, const char* kind, const char* array[], int n){ + int i; + for (i=0; itype == e) return 1; // success + logFatalTypeError(elmNames[e], elm->type); + return 0; // error +} + +// Returns 0 to indicate error +// Verify that the next stack element exists and is of the given type +// If e==ANY_TYPE, the type check is ommited +static int checkPeek(Elm e) { + if (stackIsEmpty(stack)){ + printf("Illegal document structure, expected %s\n", elmNames[e]); + XML_StopParser(parser, XML_FALSE); + return 0; // error + } + return e==ANY_TYPE ? 1 : checkElementType(stackPeek(stack), e); +} + +// Returns NULL to indicate error +// Get the next stack element, it is of the given type. +// If e==ANY_TYPE, the type check is ommited +static void* checkPop(Elm e){ + return checkPeek(e) ? stackPop(stack) : NULL; +} + +// ------------------------------------------------------------------------- +// Helper + +AstNodeType getAstNodeType(Elm e){ + switch (e) { + case elm_fmiModelDescription: + return astModelDescription; + case elm_Type: + return astType; + case elm_ScalarVariable: + return astScalarVariable; + case elm_CoSimulation_StandAlone: + case elm_CoSimulation_Tool: + return astCoSimulation; + case elm_BaseUnit: + case elm_EnumerationType: + case elm_Tool: + case elm_UnitDefinitions: + case elm_TypeDefinitions: + case elm_VendorAnnotations: + case elm_ModelVariables: + case elm_DirectDependency: + case elm_Model: + return astListElement; + default: + return astElement; + } +} + +// Returns 0 to indicate error +// Copies the attr array and all values. +// Replaces all attribute names by constant literal strings. +// Converts the null-terminated array into an array of known size n. +int addAttributes(Element* el, const char** attr) { + int n, a; + const char** att = NULL; + for (n=0; attr[n]; n+=2); + if (n>0) { + att = calloc(n, sizeof(char*)); + if (!checkPointer(att)) return 0; + } + for (n=0; attr[n]; n+=2) { + char* value = strdup(attr[n+1]); + if (!checkPointer(value)) return 0; + a = checkAttribute(attr[n]); + if (a == -1) return 0; // illegal attribute error + att[n ] = attNames[a]; // no heap memory + att[n+1] = value; // heap memory + } + el->attributes = att; // NULL if n=0 + el->n = n; + return 1; // success +} + +// Returns NULL to indicate error +Element* newElement(Elm type, int size, const char** attr) { + Element* e = (Element*)calloc(1, size); + if (!checkPointer(e)) return NULL; + e->type = type; + e->attributes = NULL; + e->n=0; + if (!addAttributes(e, attr)) return NULL; + return e; +} + +// ------------------------------------------------------------------------- +// callback functions called by the XML parser + +// Create and push a new element node +static void XMLCALL startElement(void *context, const char *elm, const char **attr) { + Elm el; + void* e; + int size; + el = checkElement(elm); + if (el==-1) return; // error + skipData = (el != elm_Name); // skip element content for all elements but Name + switch(getAstNodeType(el)){ + case astElement: size = sizeof(Element); break; + case astListElement: size = sizeof(ListElement); break; + case astType: size = sizeof(Type); break; + case astScalarVariable: size = sizeof(ScalarVariable); break; + case astCoSimulation: size = sizeof(CoSimulation); break; + case astModelDescription: size = sizeof(ModelDescription); break; + default: assert(0); + } + e = newElement(el, size, attr); + checkPointer(e); + stackPush(stack, e); +} + +// Pop all elements of the given type from stack and +// add it to the ListElement that follows. +// The ListElement remains on the stack. +static void popList(Elm e) { + int n = 0; + Element** array; + Element* elm = stackPop(stack); + while (elm->type == e) { + elm = stackPop(stack); + n++; + } + stackPush(stack, elm); // push ListElement back to stack + array = (Element**)stackLastPopedAsArray0(stack, n); // NULL terminated list + if (getAstNodeType(elm->type)!=astListElement) return; // failure + ((ListElement*)elm)->list = array; + return; // success only if list!=NULL +} + +// Pop the children from the stack and +// check for correct type and sequence of children +static void XMLCALL endElement(void *context, const char *elm) { + Elm el; + el = checkElement(elm); + switch(el) { + case elm_fmiModelDescription: + { + ModelDescription* md; + ListElement** ud = NULL; // NULL or list of BaseUnits + Type** td = NULL; // NULL or list of Types + Element* de = NULL; // NULL or DefaultExperiment + ListElement** va = NULL; // NULL or list of Tools + ScalarVariable** mv = NULL; // NULL or list of ScalarVariable + CoSimulation *cs = NULL; // NULL or CoSimulation + ListElement* child; + + child = checkPop(ANY_TYPE); + if (child->type == elm_CoSimulation_StandAlone || child->type == elm_CoSimulation_Tool) { + cs = (CoSimulation*)child; + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_ModelVariables){ + mv = (ScalarVariable**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_VendorAnnotations){ + va = (ListElement**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_DefaultExperiment){ + de = (Element*)child; + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_TypeDefinitions){ + td = (Type**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_UnitDefinitions){ + ud = (ListElement**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + // work around bug of SimulationX 3.4 and 3.5 which places Implementation at wrong location + if (!cs && (child->type == elm_CoSimulation_StandAlone || child->type == elm_CoSimulation_Tool)) { + cs = (CoSimulation*)child; + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (!checkElementType(child, elm_fmiModelDescription)) return; + md = (ModelDescription*)child; + md->modelVariables = mv; + md->vendorAnnotations = va; + md->defaultExperiment = de; + md->typeDefinitions = td; + md->unitDefinitions = ud; + md->cosimulation = cs; + stackPush(stack, md); + break; + } + case elm_Implementation: + { + // replace Implementation element + void* cs = checkPop(ANY_TYPE); + void* im = checkPop(elm_Implementation); + stackPush(stack, cs); + free(im); + el = ((Element*)cs)->type; + break; + } + case elm_CoSimulation_StandAlone: + { + Element* ca = checkPop(elm_Capabilities); + CoSimulation* cs = checkPop(elm_CoSimulation_StandAlone); + if (!ca || !cs) return; + cs->capabilities = ca; + stackPush(stack, cs); + break; + } + case elm_CoSimulation_Tool: + { + ListElement* mo = checkPop(elm_Model); + Element* ca = checkPop(elm_Capabilities); + CoSimulation* cs = checkPop(elm_CoSimulation_Tool); + if (!ca || !mo || !cs) return; + cs->capabilities = ca; + cs->model = mo; + stackPush(stack, cs); + break; + } + case elm_Type: + { + Type* tp; + Element* ts = checkPop(ANY_TYPE); + if (!ts) return; + if (!checkPeek(elm_Type)) return; + tp = (Type*)stackPeek(stack); + switch (ts->type) { + case elm_RealType: + case elm_IntegerType: + case elm_BooleanType: + case elm_StringType: + case elm_EnumerationType: + break; + default: + logFatalTypeError("RealType or similar", ts->type); + return; + } + tp->typeSpec = ts; + break; + } + case elm_ScalarVariable: + { + ScalarVariable* sv; + Element** list = NULL; + Element* child = checkPop(ANY_TYPE); + if (!child) return; + if (child->type==elm_DirectDependency){ + list = ((ListElement*)child)->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (!checkPeek(elm_ScalarVariable)) return; + sv = (ScalarVariable*)stackPeek(stack); + switch (child->type) { + case elm_Real: + case elm_Integer: + case elm_Boolean: + case elm_String: + case elm_Enumeration: + break; + default: + logFatalTypeError("Real or similar", child->type); + return; + } + sv->directDependencies = list; + sv->typeSpec = child; + break; + } + case elm_ModelVariables: popList(elm_ScalarVariable); break; + case elm_VendorAnnotations: popList(elm_Tool);break; + case elm_Tool: popList(elm_Annotation); break; + case elm_TypeDefinitions: popList(elm_Type); break; + case elm_EnumerationType: popList(elm_Item); break; + case elm_UnitDefinitions: popList(elm_BaseUnit); break; + case elm_BaseUnit: popList(elm_DisplayUnitDefinition); break; + case elm_DirectDependency: popList(elm_Name); break; + case elm_Model: popList(elm_File); break; + case elm_Name: + { + // Exception: the name value is represented as element content. + // All other values of the XML file are represented using attributes. + Element* name = checkPop(elm_Name); + if (!name) return; + name->n = 2; + name->attributes = malloc(2*sizeof(char*)); + name->attributes[0] = attNames[att_input]; + name->attributes[1] = data; + data = NULL; + skipData = 1; // stop recording element content + stackPush(stack, name); + break; + } + case -1: return; // illegal element error + default: // must be a leaf Element + assert(getAstNodeType(el)==astElement); + break; + } + // All children of el removed from the stack. + // The top element must be of type el now. + checkPeek(el); +} + +// Called to handle element data, e.g. "xy" in xy +// Can be called many times, e.g. with "x" and then with "y" in the example above. +// Feature in expat: +// For some reason, if the element data is the empty string (Eg. ) +// instead of an empty string with len == 0 we get "\n". The workaround is +// to replace this with the empty string whenever we encounter "\n". +void XMLCALL handleData(void *context, const XML_Char *s, int len) { + int n; + if (skipData) return; + if (!data) { + // start a new data string + if (len == 1 && s[0] == '\n') { + data = strdup(""); + } else { + data = malloc(len + 1); + strncpy(data, s, len); + data[len] = '\0'; + } + } + else { + // continue existing string + n = strlen(data) + len; + data = realloc(data, n+1); + strncat(data, s, len); + data[n] = '\0'; + } + return; +} + +// ------------------------------------------------------------------------- +// printing + +static void printList(int indent, void** list); + +void printElement(int indent, void* element){ + int i; + Element* e = (Element*)element; + if (!e) return; + // print attributes + for (i=0; itype]); + for (i=0; in; i+=2) + printf(" %s=%s", e->attributes[i], e->attributes[i+1]); + printf("\n"); + // print child nodes + indent += 2; + switch (getAstNodeType(e->type)) { + case astListElement: + printList(indent, ((ListElement*)e)->list); + break; + case astScalarVariable: + printElement(indent, ((Type*)e)->typeSpec); + printList(indent, ((ScalarVariable*)e)->directDependencies); + break; + case astType: + printElement(indent, ((Type*)e)->typeSpec); + break; + case astCoSimulation: { + CoSimulation* cs = (CoSimulation*)e; + printElement(indent, cs->capabilities); + printElement(indent, cs->model); + break; + } + case astModelDescription: { + ModelDescription *md = (ModelDescription*)e; + printList(indent, md->unitDefinitions); + printList(indent, md->typeDefinitions); + printElement(indent, md->defaultExperiment); + printList(indent, md->vendorAnnotations); + printList(indent, md->modelVariables); + printElement(indent, md->cosimulation); + break; + } + } +} + +static void printList(int indent, void** list){ + int i; + if (list) for (i=0; list[i]; i++) + printElement(indent, list[i]); +} + +// ------------------------------------------------------------------------- +// free memory of the AST + +static void freeList(void** list); + +void freeElement(void* element){ + int i; + Element* e = (Element*)element; + if (!e) return; + // free attributes + for (i=0; in; i+=2) + free(e->attributes[i+1]); + if (e->attributes) free(e->attributes); + // free child nodes + switch (getAstNodeType(e->type)) { + case astListElement: + freeList(((ListElement*)e)->list); + break; + case astScalarVariable: + freeList(((ScalarVariable*)e)->directDependencies); + case astType: + freeElement(((Type*)e)->typeSpec); + break; + case astCoSimulation: { + CoSimulation* cs = (CoSimulation*)e; + freeElement(cs->capabilities); + freeElement(cs->model); + break; + } + case astModelDescription: { + ModelDescription* md = (ModelDescription*)e; + freeList(md->unitDefinitions); + freeList(md->typeDefinitions); + freeElement(md->defaultExperiment); + freeList(md->vendorAnnotations); + freeList(md->modelVariables); + freeElement(md->cosimulation); + break; + } + } + // free the struct + free(e); +} + +static void freeList(void** list){ + int i; + if (!list) return; + for (i=0; list[i]; i++) + freeElement(list[i]); + free(list); +} + +// ------------------------------------------------------------------------- +// Validation - done after parsing to report all errors + +ModelDescription* validate(ModelDescription* md) { + int error = 0; + int i; + if (md->modelVariables) + for (i=0; md->modelVariables[i]; i++){ + ScalarVariable* sv = (ScalarVariable*)md->modelVariables[i]; + char* declaredType = getString(sv->typeSpec, att_declaredType); + Type* decltype = getDeclaredType(md, declaredType); + if (declaredType && decltype==NULL) { + printf("Warning: Declared type %s of variable %s not found in modelDescription.xml\n", declaredType, getName(sv)); + error++; + } + } + if (error) { + printf("Error: Found %d error in modelDescription.xml\n", error); + return NULL; + } + return md; +} + +// ------------------------------------------------------------------------- +// Entry function parse() of the XML parser + +static void cleanup(FILE *file) { + stackFree(stack); + stack = NULL; + XML_ParserFree(parser); + parser = NULL; + fclose(file); +} + +// Returns NULL to indicate failure +// Otherwise, return the root node md of the AST. +// The receiver must call freeElement(md) to release AST memory. +ModelDescription* parse(const char* xmlPath) { + ModelDescription* md = NULL; + FILE *file; + int done = 0; + stack = stackNew(100, 10); + if (!checkPointer(stack)) return NULL; // failure + parser = XML_ParserCreate(NULL); + if (!checkPointer(parser)) return NULL; // failure + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, handleData); + file = fopen(xmlPath, "rb"); + if (file == NULL) { + printf("Cannot open file '%s'\n", xmlPath); + XML_ParserFree(parser); + return NULL; // failure + } + while (!done) { + int n = fread(text, sizeof(char), XMLBUFSIZE, file); + if (n != XMLBUFSIZE) done = 1; + if (!XML_Parse(parser, text, n, done)){ + printf("Parse error in file %s at line %d:\n%s\n", + xmlPath, + XML_GetCurrentLineNumber(parser), + XML_ErrorString(XML_GetErrorCode(parser))); + while (! stackIsEmpty(stack)) md = stackPop(stack); + if (md) freeElement(md); + cleanup(file); + return NULL; // failure + } + } + md = stackPop(stack); + assert(stackIsEmpty(stack)); + cleanup(file); + //printElement(1, md); // debug + return validate(md); // success if all refs are valid +} + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/xml_parser.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/xml_parser.h new file mode 100644 index 00000000..0730d56b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMISDK/src/shared/xml_parser.h @@ -0,0 +1,159 @@ +/* ------------------------------------------------------------------------- + * xml_parser.h + * A parser for file modelVariables.xml of an FMU. + * Supports "FMI for Model Exchange 1.0" and "FMI for Co-Simulation 1.0". + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#ifndef xml_parser_h +#define xml_parser_h + +// define XML_STATIC before including expat.h +// to prevent error when linking with libexpatMT.lib +#define XML_STATIC +#include "expat.h" +#include "stack.h" + +typedef unsigned int fmiValueReference; +#define fmiUndefinedValueReference (fmiValueReference)(-1) + +#define SIZEOF_ELM 31 +extern const char *elmNames[SIZEOF_ELM]; + +#define SIZEOF_ATT 47 +extern const char *attNames[SIZEOF_ATT]; + +#define SIZEOF_ENU 13 +extern const char *enuNames[SIZEOF_ENU]; + +// Elements +typedef enum { + elm_fmiModelDescription,elm_UnitDefinitions,elm_BaseUnit,elm_DisplayUnitDefinition,elm_TypeDefinitions, + elm_Type,elm_RealType,elm_IntegerType,elm_BooleanType,elm_StringType,elm_EnumerationType,elm_Item, + elm_DefaultExperiment,elm_VendorAnnotations,elm_Tool,elm_Annotation,elm_ModelVariables,elm_ScalarVariable, + elm_DirectDependency,elm_Name,elm_Real,elm_Integer,elm_Boolean,elm_String,elm_Enumeration, + elm_Implementation,elm_CoSimulation_StandAlone,elm_CoSimulation_Tool,elm_Model,elm_File,elm_Capabilities +} Elm; + +// Attributes +typedef enum { + att_fmiVersion,att_displayUnit,att_gain,att_offset,att_unit,att_name,att_description,att_quantity,att_relativeQuantity, + att_min,att_max,att_nominal,att_declaredType,att_start,att_fixed,att_startTime,att_stopTime,att_tolerance,att_value, + att_valueReference,att_variability,att_causality,att_alias,att_modelName,att_modelIdentifier,att_guid,att_author, + att_version,att_generationTool,att_generationDateAndTime,att_variableNamingConvention,att_numberOfContinuousStates, + att_numberOfEventIndicators,att_input, + att_canHandleVariableCommunicationStepSize,att_canHandleEvents,att_canRejectSteps,att_canInterpolateInputs, + att_maxOutputDerivativeOrder,att_canRunAsynchronuously,att_canSignalEvents,att_canBeInstantiatedOnlyOncePerProcess, + att_canNotUseMemoryManagementFunctions,att_entryPoint,att_manualStart,att_type +} Att; + +// Enumeration values +typedef enum { + enu_flat,enu_structured,enu_constant,enu_parameter,enu_discrete,enu_continuous, + enu_input,enu_output,enu_internal,enu_none,enu_noAlias,enu_alias,enu_negatedAlias +} Enu; + +// AST node for element +// DisplayUnitDefinition, RealType, IntegerType, BooleanType, StringType, DefaultExperiment, +// Item, Annotation, Name, Real, Integer, Boolean, String, Enumeration, Capabilities, File +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number +} Element; + +// AST node for element that has a list of elements +// BaseUnit, EnumerationType, Tool, DirectDependency, Model +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + Element** list; // null-terminated array of pointers to elements, not null +} ListElement; + +// AST node for element Type +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, an even number + Element* typeSpec; // one of RealType, IntegerType etc. +} Type; + +// AST node for element ScalarVariable +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + Element* typeSpec; // one of Real, Integer, etc + Element** directDependencies; // null or null-terminated list of Name +} ScalarVariable; + +// AST node for element CoSimulation_StandAlone and CoSimulation_Tool +typedef struct { + Elm type; // one of elm_CoSimulation_StandAlone and elm_CoSimulation_Tool + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + Element* capabilities; // a set of capability attributes + ListElement* model; // non-NULL to support tool coupling, NULL for standalone +} CoSimulation; + +// AST node for element ModelDescription +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + ListElement** unitDefinitions; // NULL or null-terminated list of BaseUnits + Type** typeDefinitions; // NULL or null-terminated list of Types + Element* defaultExperiment; // NULL or DefaultExperiment + ListElement** vendorAnnotations; // NULL or null-terminated list of Tools + ScalarVariable** modelVariables; // NULL or null-terminated list of ScalarVariable + CoSimulation* cosimulation; // NULL if this ModelDescription is for model exchange only +} ModelDescription; + +// types of AST nodes used to represent an element +typedef enum { + astElement, + astListElement, + astType, + astScalarVariable, + astCoSimulation, + astModelDescription +} AstNodeType; + +// Possible results when retrieving an attribute value from an element +typedef enum { + valueMissing, + valueDefined, + valueIllegal +} ValueStatus; + +// Public methods: Parsing and low-level AST access +ModelDescription* parse(const char* xmlPath); +const char* getString(void* element, Att a); +double getDouble (void* element, Att a, ValueStatus* vs); +int getInt (void* element, Att a, ValueStatus* vs); +unsigned int getUInt (void* element, Att a, ValueStatus* vs); +char getBoolean (void* element, Att a, ValueStatus* vs); +Enu getEnumValue (void* element, Att a, ValueStatus* vs); +void freeElement (void* element); + +// Convenience methods for AST access. To be used afer successful validation only. +const char* getModelIdentifier(ModelDescription* md); +int getNumberOfStates(ModelDescription* md); +int getNumberOfEventIndicators(ModelDescription* md); +const char* getName(void* element); +Enu getCausality(void* scalarVariable); +Enu getVariability(void* scalarVariable); +Enu getAlias(void* scalarVariable); +fmiValueReference getValueReference(void* scalarVariable); +ScalarVariable* getVariableByName(ModelDescription* md, const char* name); +ScalarVariable* getVariable(ModelDescription* md, fmiValueReference vr, Elm type); +Type* getDeclaredType(ModelDescription* md, const char* declaredType); +const char* getString2(ModelDescription* md, void* sv, Att a); +const char * getDescription(ModelDescription* md, ScalarVariable* sv); +const char * getVariableAttributeString(ModelDescription* md, fmiValueReference vr, Elm type, Att a); +double getVariableAttributeDouble(ModelDescription* md, fmiValueReference vr, Elm type, Att a, ValueStatus* vs); +double getNominal(ModelDescription* md, fmiValueReference vr); + +#endif // xml_parser_h + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/FMUSimulator.vcxproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/FMUSimulator.vcxproj new file mode 100644 index 00000000..a1c71e6f --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/FMUSimulator.vcxproj @@ -0,0 +1,107 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {9838038D-09A3-43A5-AB97-B5B5C763DF43} + Win32Proj + FMUSimulator + + + + DynamicLibrary + true + NotSet + + + DynamicLibrary + false + false + NotSet + + + + + + + + + + + + + false + $(SolutionDir)zlib-1.2.6\contrib\minizip;$(OutDir);$(ProjectDir)include;$(IncludePath) + $(OutDir);$(ProjectDir)include;$(LibraryPath) + $(SourcePath) + + + false + $(SolutionDir)zlib-1.2.6\contrib\minizip;$(OutDir);$(ProjectDir)include;$(IncludePath) + $(OutDir);$(ProjectDir)include;$(LibraryPath) + $(SourcePath) + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;FMUSIMULATOR_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebug + + + Windows + true + $(OutDir)zlibwapi.lib;$(OutDir)miniunz.lib;%(AdditionalDependencies) + + + + + Level3 + NotUsing + MaxSpeed + + + false + WIN32;NDEBUG;_WINDOWS;_USRDLL;FMUSIMULATOR_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + + + Windows + true + true + true + $(OutDir)zlibwapi.lib;$(OutDir)miniunz.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/FMUSimulator.vcxproj.filters b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/FMUSimulator.vcxproj.filters new file mode 100644 index 00000000..a819ab7d --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/FMUSimulator.vcxproj.filters @@ -0,0 +1,56 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/COPYING.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/COPYING.txt new file mode 100644 index 00000000..90422175 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/COPYING.txt @@ -0,0 +1,24 @@ +Files expat.h, expat_external.h and libexpatMT.lib + +Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + and Clark Cooper +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/expat.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/expat.h new file mode 100644 index 00000000..6c2b6ff5 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/expat.h @@ -0,0 +1,1014 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_INCLUDED +#define Expat_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include +#include "expat_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, + /* Added in 2.0. */ + XML_ERROR_RESERVED_PREFIX_XML, + XML_ERROR_RESERVED_PREFIX_XMLNS, + XML_ERROR_RESERVED_NAMESPACE_URI +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, + void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { + XML_INITIALIZED, + XML_PARSING, + XML_FINISHED, + XML_SUSPENDED +}; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR, + XML_FEATURE_NS, + XML_FEATURE_LARGE_SIZE + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 0 +#define XML_MICRO_VERSION 1 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/expat_external.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/expat_external.h new file mode 100644 index 00000000..bb83a995 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/expat_external.h @@ -0,0 +1,115 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(_MSC_VER) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +typedef __int64 XML_Index; +typedef unsigned __int64 XML_Size; +#else +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#endif +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/fmiModelFunctions.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/fmiModelFunctions.h new file mode 100644 index 00000000..e2047724 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/fmiModelFunctions.h @@ -0,0 +1,210 @@ +#ifndef fmiModelFunctions_h +#define fmiModelFunctions_h + +/* This header file must be utilized when compiling a model. + It defines all functions of the Model Execution Interface. + In order to have unique function names even if several models + are compiled together (e.g. for embedded systems), every "real" function name + is constructed by prepending the function name by + "MODEL_IDENTIFIER" + "_" where "MODEL_IDENTIFIER" is the short name + of the model used as the name of the zip-file where the model is stored. + Therefore, the typical usage is: + + #define MODEL_IDENTIFIER MyModel + #include "fmiModelFunctions.h" + + As a result, a function that is defined as "fmiGetDerivatives" in this header file, + is actually getting the name "MyModel_fmiGetDerivatives". + + Revisions: + - Jan. 20, 2010: stateValueReferencesChanged added to struct fmiEventInfo (ticket #27) + (by M. Otter, DLR) + Added WIN32 pragma to define the struct layout (ticket #34) + (by J. Mauss, QTronic) + - Jan. 4, 2010: Removed argument intermediateResults from fmiInitialize + Renamed macro fmiGetModelFunctionsVersion to fmiGetVersion + Renamed macro fmiModelFunctionsVersion to fmiVersion + Replaced fmiModel by fmiComponent in decl of fmiInstantiateModel + (by J. Mauss, QTronic) + - Dec. 17, 2009: Changed extension "me" to "fmi" (by Martin Otter, DLR). + - Dez. 14, 2009: Added eventInfo to meInitialize and added + meGetNominalContinuousStates (by Martin Otter, DLR) + - Sept. 9, 2009: Added DllExport (according to Peter Nilsson's suggestion) + (by A. Junghanns, QTronic) + - Sept. 9, 2009: Changes according to FMI-meeting on July 21: + meInquireModelTypesVersion -> meGetModelTypesPlatform + meInquireModelFunctionsVersion -> meGetModelFunctionsVersion + meSetStates -> meSetContinuousStates + meGetStates -> meGetContinuousStates + removal of meInitializeModelClass + removal of meGetTime + change of arguments of meInstantiateModel + change of arguments of meCompletedIntegratorStep + (by Martin Otter, DLR): + - July 19, 2009: Added "me" as prefix to file names (by Martin Otter, DLR). + - March 2, 2009: Changed function definitions according to the last design + meeting with additional improvements (by Martin Otter, DLR). + - Dec. 3 , 2008: First version by Martin Otter (DLR) and Hans Olsson (Dynasim). + + + Copyright © 2008-2009, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html): + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- + + with the extension: + + You may distribute or publicly perform any modification only under the + terms of this license. +*/ + +#include "fmiModelTypes.h" +#include + +/* Export fmi functions on Windows */ +#ifdef _MSC_VER +#define DllExport __declspec( dllexport ) +#else +#define DllExport +#endif + +/* Macros to construct the real function name + (prepend function name by MODEL_IDENTIFIER + "_") */ + +#define fmiPaste(a,b) a ## b +#define fmiPasteB(a,b) fmiPaste(a,b) +#define fmiFullName(name) fmiPasteB(MODEL_IDENTIFIER, name) + +#define fmiGetModelTypesPlatform fmiFullName(_fmiGetModelTypesPlatform) +#define fmiGetVersion fmiFullName(_fmiGetVersion) +#define fmiInstantiateModel fmiFullName(_fmiInstantiateModel) +#define fmiFreeModelInstance fmiFullName(_fmiFreeModelInstance) +#define fmiSetDebugLogging fmiFullName(_fmiSetDebugLogging) +#define fmiSetTime fmiFullName(_fmiSetTime) +#define fmiSetContinuousStates fmiFullName(_fmiSetContinuousStates) +#define fmiCompletedIntegratorStep fmiFullName(_fmiCompletedIntegratorStep) +#define fmiSetReal fmiFullName(_fmiSetReal) +#define fmiSetInteger fmiFullName(_fmiSetInteger) +#define fmiSetBoolean fmiFullName(_fmiSetBoolean) +#define fmiSetString fmiFullName(_fmiSetString) +#define fmiInitialize fmiFullName(_fmiInitialize) +#define fmiGetDerivatives fmiFullName(_fmiGetDerivatives) +#define fmiGetEventIndicators fmiFullName(_fmiGetEventIndicators) +#define fmiGetReal fmiFullName(_fmiGetReal) +#define fmiGetInteger fmiFullName(_fmiGetInteger) +#define fmiGetBoolean fmiFullName(_fmiGetBoolean) +#define fmiGetString fmiFullName(_fmiGetString) +#define fmiEventUpdate fmiFullName(_fmiEventUpdate) +#define fmiGetContinuousStates fmiFullName(_fmiGetContinuousStates) +#define fmiGetNominalContinuousStates fmiFullName(_fmiGetNominalContinuousStates) +#define fmiGetStateValueReferences fmiFullName(_fmiGetStateValueReferences) +#define fmiTerminate fmiFullName(_fmiTerminate) + + +/* Version number */ +#define fmiVersion "1.0" + +/* Inquire version numbers of header files */ + DllExport const char* fmiGetModelTypesPlatform(); + DllExport const char* fmiGetVersion(); + +/* make sure all compiler use the same alignment policies for structures */ +#ifdef WIN32 +#pragma pack(push,8) +#endif + +/* Type definitions */ + typedef enum {fmiOK, + fmiWarning, + fmiDiscard, + fmiError, + fmiFatal} fmiStatus; + + typedef void (*fmiCallbackLogger) (fmiComponent c, fmiString instanceName, fmiStatus status, + fmiString category, fmiString message, ...); + typedef void* (*fmiCallbackAllocateMemory)(size_t nobj, size_t size); + typedef void (*fmiCallbackFreeMemory) (void* obj); + + typedef struct { + fmiCallbackLogger logger; + fmiCallbackAllocateMemory allocateMemory; + fmiCallbackFreeMemory freeMemory; + } fmiCallbackFunctions; + + typedef struct { + fmiBoolean iterationConverged; + fmiBoolean stateValueReferencesChanged; + fmiBoolean stateValuesChanged; + fmiBoolean terminateSimulation; + fmiBoolean upcomingTimeEvent; + fmiReal nextEventTime; + } fmiEventInfo; + +/* reset alignment policy to the one set before reading this file */ +#ifdef WIN32 +#pragma pack(pop) +#endif + +/* Creation and destruction of model instances and setting debug status */ + DllExport fmiComponent fmiInstantiateModel (fmiString instanceName, + fmiString GUID, + fmiCallbackFunctions functions, + fmiBoolean loggingOn); + DllExport void fmiFreeModelInstance(fmiComponent c); + DllExport fmiStatus fmiSetDebugLogging (fmiComponent c, fmiBoolean loggingOn); + + +/* Providing independent variables and re-initialization of caching */ + DllExport fmiStatus fmiSetTime (fmiComponent c, fmiReal time); + DllExport fmiStatus fmiSetContinuousStates (fmiComponent c, const fmiReal x[], size_t nx); + DllExport fmiStatus fmiCompletedIntegratorStep(fmiComponent c, fmiBoolean* callEventUpdate); + DllExport fmiStatus fmiSetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); + DllExport fmiStatus fmiSetInteger (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); + DllExport fmiStatus fmiSetBoolean (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); + DllExport fmiStatus fmiSetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); + + +/* Evaluation of the model equations */ + DllExport fmiStatus fmiInitialize(fmiComponent c, fmiBoolean toleranceControlled, + fmiReal relativeTolerance, fmiEventInfo* eventInfo); + + DllExport fmiStatus fmiGetDerivatives (fmiComponent c, fmiReal derivatives[] , size_t nx); + DllExport fmiStatus fmiGetEventIndicators(fmiComponent c, fmiReal eventIndicators[], size_t ni); + + DllExport fmiStatus fmiGetReal (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); + DllExport fmiStatus fmiGetInteger(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); + DllExport fmiStatus fmiGetBoolean(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); + DllExport fmiStatus fmiGetString (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); + + DllExport fmiStatus fmiEventUpdate (fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo); + DllExport fmiStatus fmiGetContinuousStates (fmiComponent c, fmiReal states[], size_t nx); + DllExport fmiStatus fmiGetNominalContinuousStates(fmiComponent c, fmiReal x_nominal[], size_t nx); + DllExport fmiStatus fmiGetStateValueReferences (fmiComponent c, fmiValueReference vrx[], size_t nx); + DllExport fmiStatus fmiTerminate (fmiComponent c); + +#endif // fmiModelFunctions_h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/fmiModelTypes.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/fmiModelTypes.h new file mode 100644 index 00000000..17e9e300 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/fmiModelTypes.h @@ -0,0 +1,91 @@ +#ifndef fmiModelTypes_h +#define fmiModelTypes_h + +/* Standard header file to define the argument types of the + functions of the Model Execution Interface. + This header file must be utilized both by the model and + by the simulation engine. + + Revisions: + - Jan. 4, 2010: Renamed meModelTypes_h to fmiModelTypes_h (by Mauss, QTronic) + - Dec. 21, 2009: Changed "me" to "fmi" and "meModel" to "fmiComponent" + according to meeting on Dec. 18 (by Martin Otter, DLR) + - Dec. 6, 2009: Added meUndefinedValueReference (by Martin Otter, DLR) + - Sept. 9, 2009: Changes according to FMI-meeting on July 21: + Changed "version" to "platform", "standard" to "standard32", + Added a precise definition of "standard32" as comment + (by Martin Otter, DLR) + - July 19, 2009: Added "me" as prefix to file names, added meTrue/meFalse, + and changed meValueReferenced from int to unsigned int + (by Martin Otter, DLR). + - March 2, 2009: Moved enums and function pointer definitions to + ModelFunctions.h (by Martin Otter, DLR). + - Dec. 3, 2008 : First version by Martin Otter (DLR) and + Hans Olsson (Dynasim). + + + Copyright © 2008-2010, MODELISAR consortium. All rights reserved. + This file is licensed by the copyright holders under the BSD License + (http://www.opensource.org/licenses/bsd-license.html) + + ---------------------------------------------------------------------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------- + + with the extension: + + You may distribute or publicly perform any modification only under the + terms of this license. +*/ + +/* Platform (combination of machine, compiler, operating system) */ +#define fmiModelTypesPlatform "standard32" + +/* Type definitions of variables passed as arguments + Version "standard32" means: + + fmiComponent : 32 bit pointer + fmiValueReference: 32 bit + fmiReal : 64 bit + fmiInteger : 32 bit + fmiBoolean : 8 bit + fmiString : 32 bit pointer + +*/ + typedef void* fmiComponent; + typedef unsigned int fmiValueReference; + typedef double fmiReal ; + typedef int fmiInteger; + typedef char fmiBoolean; + typedef const char* fmiString ; + +/* Values for fmiBoolean */ +#define fmiTrue 1 +#define fmiFalse 0 + +/* Undefined value for fmiValueReference (largest unsigned int value) */ +#define fmiUndefinedValueReference (fmiValueReference)(-1) + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/fmi_me.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/fmi_me.h new file mode 100644 index 00000000..f1152455 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/fmi_me.h @@ -0,0 +1,89 @@ +/* ------------------------------------------------------------------------- + * fmi_me.h + * Function types for all function of the "FMI for Model Exchange 1.0" + * and a struct with the corresponding function pointers. + * Copyright 2011 QTronic GmbH. All rights reserved. + * ------------------------------------------------------------------------- + */ + +#ifndef FMI_ME_H +#define FMI_ME_H + +#include +#include "fmiModelFunctions.h" +#include "xml_parser.h" + +typedef const char* (*fGetModelTypesPlatform)(); +typedef const char* (*fGetVersion)(); +typedef fmiComponent (*fInstantiateModel)(fmiString instanceName, fmiString GUID, + fmiCallbackFunctions functions, fmiBoolean loggingOn); +typedef void (*fFreeModelInstance) (fmiComponent c); +typedef fmiStatus (*fSetDebugLogging) (fmiComponent c, fmiBoolean loggingOn); +typedef fmiStatus (*fSetTime) (fmiComponent c, fmiReal time); +typedef fmiStatus (*fSetContinuousStates)(fmiComponent c, const fmiReal x[], size_t nx); +typedef fmiStatus (*fCompletedIntegratorStep)(fmiComponent c, fmiBoolean* callEventUpdate); +typedef fmiStatus (*fSetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiReal value[]); +typedef fmiStatus (*fSetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiInteger value[]); +typedef fmiStatus (*fSetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiBoolean value[]); +typedef fmiStatus (*fSetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, const fmiString value[]); +typedef fmiStatus (*fInitialize)(fmiComponent c, fmiBoolean toleranceControlled, + fmiReal relativeTolerance, fmiEventInfo* eventInfo); +typedef fmiStatus (*fGetDerivatives) (fmiComponent c, fmiReal derivatives[] , size_t nx); +typedef fmiStatus (*fGetEventIndicators)(fmiComponent c, fmiReal eventIndicators[], size_t ni); +typedef fmiStatus (*fGetReal) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiReal value[]); +typedef fmiStatus (*fGetInteger)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiInteger value[]); +typedef fmiStatus (*fGetBoolean)(fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiBoolean value[]); +typedef fmiStatus (*fGetString) (fmiComponent c, const fmiValueReference vr[], size_t nvr, fmiString value[]); +typedef fmiStatus (*fEventUpdate) (fmiComponent c, fmiBoolean intermediateResults, fmiEventInfo* eventInfo); +typedef fmiStatus (*fGetContinuousStates) (fmiComponent c, fmiReal states[], size_t nx); +typedef fmiStatus (*fGetNominalContinuousStates)(fmiComponent c, fmiReal x_nominal[], size_t nx); +typedef fmiStatus (*fGetStateValueReferences) (fmiComponent c, fmiValueReference vrx[], size_t nx); +typedef fmiStatus (*fTerminate) (fmiComponent c); + +typedef struct { + ModelDescription* modelDescription; + HANDLE dllHandle; + fGetModelTypesPlatform getModelTypesPlatform; + fGetVersion getVersion; + fInstantiateModel instantiateModel; + fFreeModelInstance freeModelInstance; + fSetDebugLogging setDebugLogging; + fSetTime setTime; + fSetContinuousStates setContinuousStates; + fCompletedIntegratorStep completedIntegratorStep; + fSetReal setReal; + fSetInteger setInteger; + fSetBoolean setBoolean; + fSetString setString; + fInitialize initialize; + fGetDerivatives getDerivatives; + fGetEventIndicators getEventIndicators; + fGetReal getReal; + fGetInteger getInteger; + fGetBoolean getBoolean; + fGetString getString; + fEventUpdate eventUpdate; + fGetContinuousStates getContinuousStates; + fGetNominalContinuousStates getNominalContinuousStates; + fGetStateValueReferences getStateValueReferences; + fTerminate terminate; +/* + fInstantiateSlave instantiateSlave; + fInitializeSlave initializeSlave; + fTerminateSlave terminateSlave; + fResetSlave resetSlave; + fFreeSlaveInstance freeSlaveInstance; + fGetRealOutputDerivatives getRealOutputDerivatives; + fSetRealInputDerivatives setRealInputDerivatives; + fDoStep doStep; + fCancelStep cancelStep; + fGetStatus getStatus; + fGetRealStatus getRealStatus; + fGetIntegerStatus getIntegerStatus; + fGetBooleanStatus getBooleanStatus; + fGetStringStatus getStringStatus; +*/ +} FMU; + +#endif // FMI_ME_H + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/inffixed.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/inffixed.h new file mode 100644 index 00000000..d6283277 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/inflate.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/inflate.h new file mode 100644 index 00000000..95f4986d --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/inftrees.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/inftrees.h new file mode 100644 index 00000000..baa53a0b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/jni.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/jni.h new file mode 100644 index 00000000..8ed7366a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/jni.h @@ -0,0 +1,1944 @@ +/* + * %W% %E% + * + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +/* + * We used part of Netscape's Java Runtime Interface (JRI) as the starting + * point of our design and implementation. + */ + +/****************************************************************************** + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + *****************************************************************************/ + +#ifndef _JAVASOFT_JNI_H_ +#define _JAVASOFT_JNI_H_ + +#include +#include + +/* jni_md.h contains the machine-dependent typedefs for jbyte, jint + and jlong */ + +#include "jni_md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * JNI Types + */ + +#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H + +typedef unsigned char jboolean; +typedef unsigned short jchar; +typedef short jshort; +typedef float jfloat; +typedef double jdouble; + +typedef jint jsize; + +#ifdef __cplusplus + +class _jobject {}; +class _jclass : public _jobject {}; +class _jthrowable : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jobjectArray : public _jarray {}; + +typedef _jobject *jobject; +typedef _jclass *jclass; +typedef _jthrowable *jthrowable; +typedef _jstring *jstring; +typedef _jarray *jarray; +typedef _jbooleanArray *jbooleanArray; +typedef _jbyteArray *jbyteArray; +typedef _jcharArray *jcharArray; +typedef _jshortArray *jshortArray; +typedef _jintArray *jintArray; +typedef _jlongArray *jlongArray; +typedef _jfloatArray *jfloatArray; +typedef _jdoubleArray *jdoubleArray; +typedef _jobjectArray *jobjectArray; + +#else + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +#endif + +typedef jobject jweak; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +struct _jfieldID; +typedef struct _jfieldID *jfieldID; + +struct _jmethodID; +typedef struct _jmethodID *jmethodID; + +/* Return values from jobjectRefType */ +typedef enum _jobjectType { + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} jobjectRefType; + + +#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */ + +/* + * jboolean constants + */ + +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +/* + * possible return values for JNI functions. + */ + +#define JNI_OK 0 /* success */ +#define JNI_ERR (-1) /* unknown error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ +#define JNI_ENOMEM (-4) /* not enough memory */ +#define JNI_EEXIST (-5) /* VM already created */ +#define JNI_EINVAL (-6) /* invalid arguments */ + +/* + * used in ReleaseScalarArrayElements + */ + +#define JNI_COMMIT 1 +#define JNI_ABORT 2 + +/* + * used in RegisterNatives to describe native method name, signature, + * and function pointer. + */ + +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +/* + * JNI Native Method Interface. + */ + +struct JNINativeInterface_; + +struct JNIEnv_; + +#ifdef __cplusplus +typedef JNIEnv_ JNIEnv; +#else +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +/* + * JNI Invocation Interface. + */ + +struct JNIInvokeInterface_; + +struct JavaVM_; + +#ifdef __cplusplus +typedef JavaVM_ JavaVM; +#else +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + void *reserved3; + jint (JNICALL *GetVersion)(JNIEnv *env); + + jclass (JNICALL *DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + jclass (JNICALL *FindClass) + (JNIEnv *env, const char *name); + + jmethodID (JNICALL *FromReflectedMethod) + (JNIEnv *env, jobject method); + jfieldID (JNICALL *FromReflectedField) + (JNIEnv *env, jobject field); + + jobject (JNICALL *ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); + + jclass (JNICALL *GetSuperclass) + (JNIEnv *env, jclass sub); + jboolean (JNICALL *IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + + jobject (JNICALL *ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); + + jint (JNICALL *Throw) + (JNIEnv *env, jthrowable obj); + jint (JNICALL *ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + jthrowable (JNICALL *ExceptionOccurred) + (JNIEnv *env); + void (JNICALL *ExceptionDescribe) + (JNIEnv *env); + void (JNICALL *ExceptionClear) + (JNIEnv *env); + void (JNICALL *FatalError) + (JNIEnv *env, const char *msg); + + jint (JNICALL *PushLocalFrame) + (JNIEnv *env, jint capacity); + jobject (JNICALL *PopLocalFrame) + (JNIEnv *env, jobject result); + + jobject (JNICALL *NewGlobalRef) + (JNIEnv *env, jobject lobj); + void (JNICALL *DeleteGlobalRef) + (JNIEnv *env, jobject gref); + void (JNICALL *DeleteLocalRef) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + jobject (JNICALL *NewLocalRef) + (JNIEnv *env, jobject ref); + jint (JNICALL *EnsureLocalCapacity) + (JNIEnv *env, jint capacity); + + jobject (JNICALL *AllocObject) + (JNIEnv *env, jclass clazz); + jobject (JNICALL *NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jclass (JNICALL *GetObjectClass) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + jmethodID (JNICALL *GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jobject (JNICALL *CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jobject (JNICALL *CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jboolean (JNICALL *CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jboolean (JNICALL *CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jboolean (JNICALL *CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jbyte (JNICALL *CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jbyte (JNICALL *CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jbyte (JNICALL *CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jchar (JNICALL *CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jchar (JNICALL *CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jshort (JNICALL *CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jshort (JNICALL *CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jint (JNICALL *CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jint (JNICALL *CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jlong (JNICALL *CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jlong (JNICALL *CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jfloat (JNICALL *CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jfloat (JNICALL *CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jdouble (JNICALL *CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jdouble (JNICALL *CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + void (JNICALL *CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + void (JNICALL *CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jobject (JNICALL *CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jobject (JNICALL *CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jboolean (JNICALL *CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jboolean (JNICALL *CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jbyte (JNICALL *CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jbyte (JNICALL *CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jchar (JNICALL *CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jchar (JNICALL *CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jshort (JNICALL *CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jshort (JNICALL *CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jint (JNICALL *CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jint (JNICALL *CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jlong (JNICALL *CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jlong (JNICALL *CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jfloat (JNICALL *CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jfloat (JNICALL *CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jdouble (JNICALL *CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jdouble (JNICALL *CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + void (JNICALL *CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + void (JNICALL *CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + void (JNICALL *CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jfieldID (JNICALL *GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jboolean (JNICALL *GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jbyte (JNICALL *GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jchar (JNICALL *GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jshort (JNICALL *GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jint (JNICALL *GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jlong (JNICALL *GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jfloat (JNICALL *GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jdouble (JNICALL *GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + void (JNICALL *SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + void (JNICALL *SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + void (JNICALL *SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + void (JNICALL *SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + void (JNICALL *SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + void (JNICALL *SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + void (JNICALL *SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + void (JNICALL *SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + void (JNICALL *SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + jmethodID (JNICALL *GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jboolean (JNICALL *CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jboolean (JNICALL *CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jbyte (JNICALL *CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jbyte (JNICALL *CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jchar (JNICALL *CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jshort (JNICALL *CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jint (JNICALL *CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jlong (JNICALL *CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jfloat (JNICALL *CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jdouble (JNICALL *CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + void (JNICALL *CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + void (JNICALL *CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args); + + jfieldID (JNICALL *GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + jobject (JNICALL *GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jboolean (JNICALL *GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jbyte (JNICALL *GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jchar (JNICALL *GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jshort (JNICALL *GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jint (JNICALL *GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jlong (JNICALL *GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jfloat (JNICALL *GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jdouble (JNICALL *GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + void (JNICALL *SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + void (JNICALL *SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + void (JNICALL *SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + void (JNICALL *SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + void (JNICALL *SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + void (JNICALL *SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + void (JNICALL *SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + void (JNICALL *SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + void (JNICALL *SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + jstring (JNICALL *NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + jsize (JNICALL *GetStringLength) + (JNIEnv *env, jstring str); + const jchar *(JNICALL *GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + jstring (JNICALL *NewStringUTF) + (JNIEnv *env, const char *utf); + jsize (JNICALL *GetStringUTFLength) + (JNIEnv *env, jstring str); + const char* (JNICALL *GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + jsize (JNICALL *GetArrayLength) + (JNIEnv *env, jarray array); + + jobjectArray (JNICALL *NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + jobject (JNICALL *GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + void (JNICALL *SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + jbooleanArray (JNICALL *NewBooleanArray) + (JNIEnv *env, jsize len); + jbyteArray (JNICALL *NewByteArray) + (JNIEnv *env, jsize len); + jcharArray (JNICALL *NewCharArray) + (JNIEnv *env, jsize len); + jshortArray (JNICALL *NewShortArray) + (JNIEnv *env, jsize len); + jintArray (JNICALL *NewIntArray) + (JNIEnv *env, jsize len); + jlongArray (JNICALL *NewLongArray) + (JNIEnv *env, jsize len); + jfloatArray (JNICALL *NewFloatArray) + (JNIEnv *env, jsize len); + jdoubleArray (JNICALL *NewDoubleArray) + (JNIEnv *env, jsize len); + + jboolean * (JNICALL *GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + jbyte * (JNICALL *GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + jchar * (JNICALL *GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + jshort * (JNICALL *GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + jint * (JNICALL *GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + jlong * (JNICALL *GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + jfloat * (JNICALL *GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + jdouble * (JNICALL *GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + void (JNICALL *ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + void (JNICALL *ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + void (JNICALL *ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + void (JNICALL *ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + void (JNICALL *ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + void (JNICALL *ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + void (JNICALL *ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + void (JNICALL *ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + void (JNICALL *GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + void (JNICALL *SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf); + void (JNICALL *SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf); + void (JNICALL *SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf); + void (JNICALL *SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf); + void (JNICALL *SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); + void (JNICALL *SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf); + void (JNICALL *SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf); + void (JNICALL *SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf); + + jint (JNICALL *RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + jint (JNICALL *UnregisterNatives) + (JNIEnv *env, jclass clazz); + + jint (JNICALL *MonitorEnter) + (JNIEnv *env, jobject obj); + jint (JNICALL *MonitorExit) + (JNIEnv *env, jobject obj); + + jint (JNICALL *GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + void (JNICALL *GetStringRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); + void (JNICALL *GetStringUTFRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); + + void * (JNICALL *GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + void (JNICALL *ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void *carray, jint mode); + + const jchar * (JNICALL *GetStringCritical) + (JNIEnv *env, jstring string, jboolean *isCopy); + void (JNICALL *ReleaseStringCritical) + (JNIEnv *env, jstring string, const jchar *cstring); + + jweak (JNICALL *NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + void (JNICALL *DeleteWeakGlobalRef) + (JNIEnv *env, jweak ref); + + jboolean (JNICALL *ExceptionCheck) + (JNIEnv *env); + + jobject (JNICALL *NewDirectByteBuffer) + (JNIEnv* env, void* address, jlong capacity); + void* (JNICALL *GetDirectBufferAddress) + (JNIEnv* env, jobject buf); + jlong (JNICALL *GetDirectBufferCapacity) + (JNIEnv* env, jobject buf); + + /* New JNI 1.6 Features */ + + jobjectRefType (JNICALL *GetObjectRefType) + (JNIEnv* env, jobject obj); +}; + +/* + * We use inlined functions for C++ so that programmers can write: + * + * env->FindClass("java/lang/String") + * + * in C++ rather than: + * + * (*env)->FindClass(env, "java/lang/String") + * + * in C. + */ + +struct JNIEnv_ { + const struct JNINativeInterface_ *functions; +#ifdef __cplusplus + + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jmethodID FromReflectedMethod(jobject method) { + return functions->FromReflectedMethod(this,method); + } + jfieldID FromReflectedField(jobject field) { + return functions->FromReflectedField(this,field); + } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { + return functions->ToReflectedMethod(this, cls, methodID, isStatic); + } + + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { + return functions->ToReflectedField(this,cls,fieldID,isStatic); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jint PushLocalFrame(jint capacity) { + return functions->PushLocalFrame(this,capacity); + } + jobject PopLocalFrame(jobject result) { + return functions->PopLocalFrame(this,result); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + + jobject NewLocalRef(jobject ref) { + return functions->NewLocalRef(this,ref); + } + jint EnsureLocalCapacity(jint capacity) { + return functions->EnsureLocalCapacity(this,capacity); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + const jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + const jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + const jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + const jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + const jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + const jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + const jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + const jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + const jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { + functions->GetStringRegion(this,str,start,len,buf); + } + void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { + functions->GetStringUTFRegion(this,str,start,len,buf); + } + + void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { + return functions->GetPrimitiveArrayCritical(this,array,isCopy); + } + void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { + functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); + } + + const jchar * GetStringCritical(jstring string, jboolean *isCopy) { + return functions->GetStringCritical(this,string,isCopy); + } + void ReleaseStringCritical(jstring string, const jchar *cstring) { + functions->ReleaseStringCritical(this,string,cstring); + } + + jweak NewWeakGlobalRef(jobject obj) { + return functions->NewWeakGlobalRef(this,obj); + } + void DeleteWeakGlobalRef(jweak ref) { + functions->DeleteWeakGlobalRef(this,ref); + } + + jboolean ExceptionCheck() { + return functions->ExceptionCheck(this); + } + + jobject NewDirectByteBuffer(void* address, jlong capacity) { + return functions->NewDirectByteBuffer(this, address, capacity); + } + void* GetDirectBufferAddress(jobject buf) { + return functions->GetDirectBufferAddress(this, buf); + } + jlong GetDirectBufferCapacity(jobject buf) { + return functions->GetDirectBufferCapacity(this, buf); + } + jobjectRefType GetObjectRefType(jobject obj) { + return functions->GetObjectRefType(this, obj); + } + +#endif /* __cplusplus */ +}; + +typedef struct JavaVMOption { + char *optionString; + void *extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; + + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +typedef struct JavaVMAttachArgs { + jint version; + + char *name; + jobject group; +} JavaVMAttachArgs; + +/* These will be VM-specific. */ + +#define JDK1_2 +#define JDK1_4 + +/* End VM-specific. */ + +struct JNIInvokeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM *vm); + + jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); + + jint (JNICALL *DetachCurrentThread)(JavaVM *vm); + + jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); + + jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); +}; + +struct JavaVM_ { + const struct JNIInvokeInterface_ *functions; +#ifdef __cplusplus + + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + jint AttachCurrentThread(void **penv, void *args) { + return functions->AttachCurrentThread(this, penv, args); + } + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void **penv, jint version) { + return functions->GetEnv(this, penv, version); + } + jint AttachCurrentThreadAsDaemon(void **penv, void *args) { + return functions->AttachCurrentThreadAsDaemon(this, penv, args); + } +#endif +}; + +#ifdef _JNI_IMPLEMENTATION_ +#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT +#else +#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT +#endif +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetDefaultJavaVMInitArgs(void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); + +/* Defined by native libraries. */ +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved); + +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved); + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVASOFT_JNI_H_ */ + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/jni_md.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/jni_md.h new file mode 100644 index 00000000..9ac4718e --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/jni_md.h @@ -0,0 +1,19 @@ +/* + * %W% %E% + * + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#define JNIEXPORT __declspec(dllexport) +#define JNIIMPORT __declspec(dllimport) +#define JNICALL __stdcall + +typedef long jint; +typedef __int64 jlong; +typedef signed char jbyte; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/libexpatMT.lib b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/libexpatMT.lib new file mode 100644 index 00000000..2436f617 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/libexpatMT.lib differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/org_simantics_fmu_FMUControlJNI.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/org_simantics_fmu_FMUControlJNI.h new file mode 100644 index 00000000..20599879 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/org_simantics_fmu_FMUControlJNI.h @@ -0,0 +1,181 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_simantics_fmu_FMUControlJNI */ + +#ifndef _Included_org_simantics_fmu_FMUControlJNI +#define _Included_org_simantics_fmu_FMUControlJNI +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: loadFMUFile_ + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_loadFMUFile_1 + (JNIEnv *, jobject, jstring, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setStepLength_ + * Signature: (Ljava/lang/String;D)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setStepLength_1 + (JNIEnv *, jobject, jstring, jdouble); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: instantiateSimulation_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_instantiateSimulation_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: initializeSimulation_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_initializeSimulation_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: subscribe_ + * Signature: (Ljava/lang/String;[Ljava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_subscribe_1 + (JNIEnv *, jobject, jstring, jobjectArray, jint); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setRealValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;D)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setRealValue_1 + (JNIEnv *, jobject, jstring, jstring, jdouble); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setIntegerValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setIntegerValue_1 + (JNIEnv *, jobject, jstring, jstring, jint); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setBooleanValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;Z)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setBooleanValue_1 + (JNIEnv *, jobject, jstring, jstring, jboolean); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setTime_ + * Signature: (Ljava/lang/String;D)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setTime_1 + (JNIEnv *, jobject, jstring, jdouble); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: simulateStep_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_simulateStep_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getSubscribedResults_ + * Signature: (Ljava/lang/String;[D)[D + */ +JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmu_FMUControlJNI_getSubscribedResults_1 + (JNIEnv *, jobject, jstring, jdoubleArray); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: unloadFMU_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_unloadFMU_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: isInitialized_ + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_simantics_fmu_FMUControlJNI_isInitialized_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getTime_ + * Signature: (Ljava/lang/String;)D + */ +JNIEXPORT jdouble JNICALL Java_org_simantics_fmu_FMUControlJNI_getTime_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getAllVariables_ + * Signature: (Ljava/lang/String;)[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmu_FMUControlJNI_getAllVariables_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: filterVariables_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmu_FMUControlJNI_filterVariables_1 + (JNIEnv *, jobject, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getLastErrorMessage_ + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_simantics_fmu_FMUControlJNI_getLastErrorMessage_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getRealValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)D + */ +JNIEXPORT jdouble JNICALL Java_org_simantics_fmu_FMUControlJNI_getRealValue_1 + (JNIEnv *, jobject, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getStringValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_simantics_fmu_FMUControlJNI_getStringValue_1 + (JNIEnv *, jobject, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getIntegerValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_getIntegerValue_1 + (JNIEnv *, jobject, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getBooleanValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_simantics_fmu_FMUControlJNI_getBooleanValue_1 + (JNIEnv *, jobject, jstring, jstring); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/sim_support.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/sim_support.h new file mode 100644 index 00000000..a2a5180a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/sim_support.h @@ -0,0 +1,31 @@ +/* ------------------------------------------------------------------------- + * sim_support.h + * Functions used by the FMU simulatios fmusim_me and fmusim_cs. + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +// Used 7z options, version 4.57: +// -x Extracts files from an archive with their full paths in the current dir, or in an output dir if specified +// -aoa Overwrite All existing files without prompt +// -o Specifies a destination directory where files are to be extracted +#define UNZIP_CMD "7z x -aoa -o" +#define XML_FILE "modelDescription.xml" +#define DLL_DIR "binaries\\win32\\" +#define RESULT_FILE "result.csv" +#define BUFSIZE 4096 + +// return codes of the 7z command line tool +#define SEVEN_ZIP_NO_ERROR 0 // success +#define SEVEN_ZIP_WARNING 1 // e.g., one or more files were locked during zip +#define SEVEN_ZIP_ERROR 2 +#define SEVEN_ZIP_COMMAND_LINE_ERROR 7 +#define SEVEN_ZIP_OUT_OF_MEMORY 8 +#define SEVEN_ZIP_STOPPED_BY_USER 255 + +void fmuLogger(fmiComponent c, fmiString instanceName, fmiStatus status, fmiString category, fmiString message, ...); +int unzip(const char *zipPath, const char *outPath); +void parseArguments(int argc, char *argv[], char** fmuFileName, double* tEnd, double* h, int* loggingOn, char* csv_separator); +int loadFMU(FMU *fmu, const char* fmuFileName, const char* tmpPath); +void outputRow(FMU *fmu, fmiComponent c, double time, FILE* file, char separator, boolean header); +int error(const char* message); +void printHelp(const char* fmusim); diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/stack.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/stack.h new file mode 100644 index 00000000..a52977fa --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/stack.h @@ -0,0 +1,28 @@ +/* ------------------------------------------------------------------------- + * stack.c + * A stack of pointers. + * Copyright 2010 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#ifndef STACK_H +#define STACK_H + +typedef struct { + void** stack; + int stackSize; // allocated size of stack + int stackPos; // array index of top element, -1 if stack is empty. + int initialSize; // how many element to allocate initially + int inc; // how many elements to allocate when stack gets full +} Stack; + +Stack* stackNew(int initialSize, int inc); +int stackIsEmpty(Stack* s); +int stackPush(Stack* s, void* e); +void* stackPeek(Stack* s); +void* stackPop(Stack* s); +void** stackPopAllAsArray(Stack* s, int *size); +void** stackLastPopedAsArray0(Stack* s, int n); +void stackFree(Stack* s); + +#endif // STACK_H + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/trees.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/trees.h new file mode 100644 index 00000000..d35639d8 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/xml_parser.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/xml_parser.h new file mode 100644 index 00000000..0730d56b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/xml_parser.h @@ -0,0 +1,159 @@ +/* ------------------------------------------------------------------------- + * xml_parser.h + * A parser for file modelVariables.xml of an FMU. + * Supports "FMI for Model Exchange 1.0" and "FMI for Co-Simulation 1.0". + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#ifndef xml_parser_h +#define xml_parser_h + +// define XML_STATIC before including expat.h +// to prevent error when linking with libexpatMT.lib +#define XML_STATIC +#include "expat.h" +#include "stack.h" + +typedef unsigned int fmiValueReference; +#define fmiUndefinedValueReference (fmiValueReference)(-1) + +#define SIZEOF_ELM 31 +extern const char *elmNames[SIZEOF_ELM]; + +#define SIZEOF_ATT 47 +extern const char *attNames[SIZEOF_ATT]; + +#define SIZEOF_ENU 13 +extern const char *enuNames[SIZEOF_ENU]; + +// Elements +typedef enum { + elm_fmiModelDescription,elm_UnitDefinitions,elm_BaseUnit,elm_DisplayUnitDefinition,elm_TypeDefinitions, + elm_Type,elm_RealType,elm_IntegerType,elm_BooleanType,elm_StringType,elm_EnumerationType,elm_Item, + elm_DefaultExperiment,elm_VendorAnnotations,elm_Tool,elm_Annotation,elm_ModelVariables,elm_ScalarVariable, + elm_DirectDependency,elm_Name,elm_Real,elm_Integer,elm_Boolean,elm_String,elm_Enumeration, + elm_Implementation,elm_CoSimulation_StandAlone,elm_CoSimulation_Tool,elm_Model,elm_File,elm_Capabilities +} Elm; + +// Attributes +typedef enum { + att_fmiVersion,att_displayUnit,att_gain,att_offset,att_unit,att_name,att_description,att_quantity,att_relativeQuantity, + att_min,att_max,att_nominal,att_declaredType,att_start,att_fixed,att_startTime,att_stopTime,att_tolerance,att_value, + att_valueReference,att_variability,att_causality,att_alias,att_modelName,att_modelIdentifier,att_guid,att_author, + att_version,att_generationTool,att_generationDateAndTime,att_variableNamingConvention,att_numberOfContinuousStates, + att_numberOfEventIndicators,att_input, + att_canHandleVariableCommunicationStepSize,att_canHandleEvents,att_canRejectSteps,att_canInterpolateInputs, + att_maxOutputDerivativeOrder,att_canRunAsynchronuously,att_canSignalEvents,att_canBeInstantiatedOnlyOncePerProcess, + att_canNotUseMemoryManagementFunctions,att_entryPoint,att_manualStart,att_type +} Att; + +// Enumeration values +typedef enum { + enu_flat,enu_structured,enu_constant,enu_parameter,enu_discrete,enu_continuous, + enu_input,enu_output,enu_internal,enu_none,enu_noAlias,enu_alias,enu_negatedAlias +} Enu; + +// AST node for element +// DisplayUnitDefinition, RealType, IntegerType, BooleanType, StringType, DefaultExperiment, +// Item, Annotation, Name, Real, Integer, Boolean, String, Enumeration, Capabilities, File +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number +} Element; + +// AST node for element that has a list of elements +// BaseUnit, EnumerationType, Tool, DirectDependency, Model +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + Element** list; // null-terminated array of pointers to elements, not null +} ListElement; + +// AST node for element Type +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, an even number + Element* typeSpec; // one of RealType, IntegerType etc. +} Type; + +// AST node for element ScalarVariable +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + Element* typeSpec; // one of Real, Integer, etc + Element** directDependencies; // null or null-terminated list of Name +} ScalarVariable; + +// AST node for element CoSimulation_StandAlone and CoSimulation_Tool +typedef struct { + Elm type; // one of elm_CoSimulation_StandAlone and elm_CoSimulation_Tool + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + Element* capabilities; // a set of capability attributes + ListElement* model; // non-NULL to support tool coupling, NULL for standalone +} CoSimulation; + +// AST node for element ModelDescription +typedef struct { + Elm type; // element type + const char** attributes; // null or n attribute value strings + int n; // size of attributes, even number + ListElement** unitDefinitions; // NULL or null-terminated list of BaseUnits + Type** typeDefinitions; // NULL or null-terminated list of Types + Element* defaultExperiment; // NULL or DefaultExperiment + ListElement** vendorAnnotations; // NULL or null-terminated list of Tools + ScalarVariable** modelVariables; // NULL or null-terminated list of ScalarVariable + CoSimulation* cosimulation; // NULL if this ModelDescription is for model exchange only +} ModelDescription; + +// types of AST nodes used to represent an element +typedef enum { + astElement, + astListElement, + astType, + astScalarVariable, + astCoSimulation, + astModelDescription +} AstNodeType; + +// Possible results when retrieving an attribute value from an element +typedef enum { + valueMissing, + valueDefined, + valueIllegal +} ValueStatus; + +// Public methods: Parsing and low-level AST access +ModelDescription* parse(const char* xmlPath); +const char* getString(void* element, Att a); +double getDouble (void* element, Att a, ValueStatus* vs); +int getInt (void* element, Att a, ValueStatus* vs); +unsigned int getUInt (void* element, Att a, ValueStatus* vs); +char getBoolean (void* element, Att a, ValueStatus* vs); +Enu getEnumValue (void* element, Att a, ValueStatus* vs); +void freeElement (void* element); + +// Convenience methods for AST access. To be used afer successful validation only. +const char* getModelIdentifier(ModelDescription* md); +int getNumberOfStates(ModelDescription* md); +int getNumberOfEventIndicators(ModelDescription* md); +const char* getName(void* element); +Enu getCausality(void* scalarVariable); +Enu getVariability(void* scalarVariable); +Enu getAlias(void* scalarVariable); +fmiValueReference getValueReference(void* scalarVariable); +ScalarVariable* getVariableByName(ModelDescription* md, const char* name); +ScalarVariable* getVariable(ModelDescription* md, fmiValueReference vr, Elm type); +Type* getDeclaredType(ModelDescription* md, const char* declaredType); +const char* getString2(ModelDescription* md, void* sv, Att a); +const char * getDescription(ModelDescription* md, ScalarVariable* sv); +const char * getVariableAttributeString(ModelDescription* md, fmiValueReference vr, Elm type, Att a); +double getVariableAttributeDouble(ModelDescription* md, fmiValueReference vr, Elm type, Att a, ValueStatus* vs); +double getNominal(ModelDescription* md, fmiValueReference vr); + +#endif // xml_parser_h + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/zutil.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/zutil.h new file mode 100644 index 00000000..dff1112f --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/include/zutil.h @@ -0,0 +1,248 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/fmu_control.cpp b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/fmu_control.cpp new file mode 100644 index 00000000..e3952fee --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/fmu_control.cpp @@ -0,0 +1,944 @@ +/* ------------------------------------------------------------------------- + * fmu_control.c + * Simulation controls for fmus + * + * Free libraries and tools used to implement this simulator: + * - header files from the FMU specification + * - eXpat 2.0.1 XML parser, see http://expat.sourceforge.net + * - 7z.exe 4.57 zip and unzip tool, see http://www.7-zip.org <---------- Replace with zlib + * Author: Teemu Lempinen + * Copyright 2012 Semantum Oy + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern "C" { + #include "fmi_me.h" + #include "sim_support.h" +} + +#define PRINT(fmt,args) { FILE *fp = fopen("R:\\Simantics\\Sysdyn\\log.txt", "ab"); fprintf(fp, fmt, args); fclose(fp); } + +#include +#define GetCurrentDir _getcwd + +using namespace std; + + +struct FMUControlStruct { + double step; // simulation step length + fmiReal currentTime; // current simulation time + + fmiComponent c; // instance of the fmu + ScalarVariable** vars; // model variables + + fmiEventInfo eventInfo; // updated by calls to initialize and eventUpdate + const char* guid; // global unique id of the fmu + fmiCallbackFunctions callbacks; // called by the model during simulation + fmiStatus fmiFlag; // return code of the fmu functions + + map indexes; // indexes for variable names in vars-table + map::iterator it; + + int nx; // number of state variables + double *x; // continuous states + double *xdot; // the crresponding derivatives in same order + int nz; // number of state event indicators + double *z; // state event indicators + double *prez; // previous values of state event indicators + + bool initialized; // has the fmu been initialized + + vector subscription; // result subscriptions + vector allVariables; // all variables in an initialized model + vector fmiValueReferences; // all value references + + string lastErrorMessage; + + FMU fmu; +}; + +map fmus; // indexes for variable names in vars-table + + +int throwException(JNIEnv *env, string message) { + jclass newExcCls; + newExcCls = env->FindClass("java/lang/Exception"); + if (newExcCls == NULL) { + /* Unable to find the exception class, give up. */ + return 0; + } + env->ThrowNew(newExcCls, message.c_str()); + return 0; +} + +bool exists(string id) { + map::iterator it = fmus.find(id); + if(it != fmus.end()) { + return true; + } else { + return false; + } +} + + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_loadFMUFile_1 + (JNIEnv *env, jobject obj, jstring id, jstring path, jstring tempDir) { + HMODULE module = NULL; + const char *fmuId = env->GetStringUTFChars(id, 0); + const char *fmuPath = env->GetStringUTFChars(path, 0); + const char *fmuTempDir = env->GetStringUTFChars(tempDir, 0); + + if(exists(fmuId)) { + // If a model has been loaded with this id, remove its contents. + // Old dll is released after loading the new from a different directory + FMUControlStruct& fmuStruct = fmus[fmuId]; + module = (HMODULE)fmuStruct.fmu.dllHandle; + if (fmuStruct.c!=NULL) fmuStruct.fmu.freeModelInstance(fmuStruct.c); + if (fmuStruct.x!=NULL) free(fmuStruct.x); + if (fmuStruct.xdot!= NULL) free(fmuStruct.xdot); + if (fmuStruct.z!= NULL) free(fmuStruct.z); + if (fmuStruct.prez!= NULL) free(fmuStruct.prez); + FMU& fmu = fmuStruct.fmu; + ModelDescription *md = fmu.modelDescription; + freeElement(md); + } else { + // Create new control struct + fmus.insert( pair(string(fmuId), FMUControlStruct()) ); + FMUControlStruct& fmuStruct = fmus[fmuId]; + fmuStruct.currentTime = 0; + + fmuStruct.c = NULL; + fmuStruct.x = NULL; + fmuStruct.xdot = NULL; + fmuStruct.z = NULL; + fmuStruct.prez = NULL; + } + + FMUControlStruct& fmuStruct = fmus[fmuId]; + // Extract fmu from fmuPath to fmuTempDir and load it to fmuStruct.fmu + int ret = loadFMU(&fmuStruct.fmu, fmuPath, fmuTempDir); + if(fmuStruct.fmu.modelDescription != NULL) { + fmuStruct.vars = fmuStruct.fmu.modelDescription->modelVariables; + + fmuStruct.fmiValueReferences.clear(); + + int i; + for (i=0; fmuStruct.vars[i]; i++) { + fmuStruct.fmiValueReferences.push_back(getValueReference(fmuStruct.vars[i])); + } + + } else { + fmuStruct.vars = NULL; + } + + if(module != NULL) { + /* + * If there was a previously loaded fmu for this id, unload its dll here. + * This is done only after loading the new model dll to ensure that + * related dlls are not unloaded + */ + FreeLibrary(module); + } + + env->ReleaseStringUTFChars(id, fmuId); + env->ReleaseStringUTFChars(path, fmuPath); + env->ReleaseStringUTFChars(tempDir, fmuTempDir); + fflush(stdout); + + /* + * Possible error messages from sim_support.c for loadFMU + * -1. FMU path not found + * -2. Unzip failed + * -3. Loading model description failed + * -4. FMU dll load failed + */ + switch(ret) { + case -1: + ret = throwException(env, "FMU path not found"); + break; + case -2: + ret = throwException(env, "FMU Unzip failed"); + break; + case -3: + ret = throwException(env, "Loading model description failed"); + break; + case -4: + ret = throwException(env, "FMU dll load failed"); + break; + } + + return ret; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setStepLength_1 + (JNIEnv *env, jobject obj, jstring id, jdouble stepLength) { + int ret = 1; + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + fmuStruct.step = stepLength; + } else { + ret = 0; + } + + env->ReleaseStringUTFChars(id, fmuId); + return ret; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_subscribe_1 + (JNIEnv *env, jobject obj, jstring id, jobjectArray names, jint size) { + + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + size_t count = env->GetArrayLength(names); + + + // Reinitialize subscription + fmuStruct.subscription.clear(); + if(fmuStruct.subscription.capacity() < count) + fmuStruct.subscription.reserve(count); + + // Add values in order + map::iterator it; + for (size_t i=0; iGetObjectArrayElement(names, i); + const char *name = env->GetStringUTFChars(string, 0); + it = fmuStruct.indexes.find(name); + + if(it != fmuStruct.indexes.end()) { + // Found the subscribed element + fmuStruct.subscription.push_back(fmuStruct.fmiValueReferences[fmuStruct.indexes[name]]); + } else { + // Element not found, use index -1 + fmuStruct.subscription.push_back(-1); + } + env->ReleaseStringUTFChars(string, name); + } + env->ReleaseStringUTFChars(id, fmuId); + return 1; + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "Subscribe: Model id " + message + " not found"); + } +} + +bool referenceExists(FMUControlStruct fmuStruct, string variable) { + map::iterator it = fmuStruct.indexes.find(variable); + if(it != fmuStruct.indexes.end()) { + return true; + } else { + return false; + } +} + +// Remember to check if reference exists +fmiValueReference getReference(FMUControlStruct fmuStruct, string variable) { + return fmuStruct.fmiValueReferences[fmuStruct.indexes[variable]]; +} + +// Get string representation of a scalar variable type +string getTypeString(ScalarVariable* sv) { + switch (sv->typeSpec->type){ + case elm_Integer: + return "Integer"; + case elm_Enumeration: + return "Enumeration"; + case elm_Real: + return "Real"; + case elm_Boolean: + return "Boolean"; + default: + return "No type"; + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setRealValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring parameter, jdouble value) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + const char *name = env->GetStringUTFChars(parameter, 0); + string nameString = name; + string modelId = fmuId; + if(!referenceExists(fmuStruct, name)) { + string errorMessage = "setRealValue: Model (id " + modelId + ") does not contain variable: " + nameString; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } else { + // Check variable type + ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]]; + switch (sv->typeSpec->type){ + case elm_Real: + break; // ok + default: { + string errorMessage = "setRealValue: " + nameString + " is not of type Real. (type: + " + getTypeString(sv) + ")"; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } + } + + // Change value + fmiValueReference vr = getReference(fmuStruct, name); + fmuStruct.fmu.setReal(fmuStruct.c, &vr, 1, &value); + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return 1; + } + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "setRealValue: Model id " + message + " not found"); + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setIntegerValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring parameter, jint value) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + const char *name = env->GetStringUTFChars(parameter, 0); + string nameString = name; + string modelId = fmuId; + if(!referenceExists(fmuStruct, name)) { + string errorMessage = "setIntegerValue: Model (id " + modelId + ") does not contain variable: " + nameString; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } else { + // Check variable type + ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]]; + switch (sv->typeSpec->type){ + case elm_Integer: + break; // ok + default: { + string errorMessage = "setIntegerValue: " + nameString + " is not of type Integer. (type: + " + getTypeString(sv) + ")"; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } + } + + // Change value + fmiValueReference vr = getReference(fmuStruct, name); + const int intValue = (int) value; + fmuStruct.fmu.setInteger(fmuStruct.c, &vr, 1, &intValue); + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return 1; + } + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "setIntegerValue: Model id " + message + " not found"); + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setBooleanValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring parameter, jboolean value) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + const char *name = env->GetStringUTFChars(parameter, 0); + string nameString = name; + string modelId = fmuId; + if(!referenceExists(fmuStruct, name)) { + string errorMessage = "setBooleanValue: Model (id " + modelId + ") does not contain variable: " + nameString; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } else { + // Check variable type + ScalarVariable* sv = fmuStruct.vars[fmuStruct.indexes[name]]; + switch (sv->typeSpec->type){ + case elm_Boolean: + break; // ok + default: { + string errorMessage = "setBooleanValue: " + nameString + " is not of type Boolean. (type: + " + getTypeString(sv) + ")"; + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, errorMessage); + } + } + + // Change value + fmiValueReference vr = getReference(fmuStruct, name); + fmiBoolean result = 1; + if(value == 0) + result = 0; + fmuStruct.fmu.setBoolean(fmuStruct.c, &vr, 1, &result); + env->ReleaseStringUTFChars(parameter, name); + env->ReleaseStringUTFChars(id, fmuId); + return 1; + } + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "setBooleanValue: Model id " + message + " not found"); + } +} + +JNIEXPORT jboolean JNICALL Java_org_simantics_fmu_FMUControlJNI_isInitialized_1 + (JNIEnv *env, jobject obj, jstring id) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + return fmuStruct.initialized; + } else { + env->ReleaseStringUTFChars(id, fmuId); + return false; + } +} + + +JNIEXPORT jdouble JNICALL Java_org_simantics_fmu_FMUControlJNI_getTime_1 + (JNIEnv *env, jobject obj, jstring id) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + return fmuStruct.currentTime; + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + throwException(env, "getTime: Model id " + message + " not found"); + return 0.0; + } +} + +double getRealValue(FMUControlStruct fmuStruct, int index) { + ScalarVariable *sv = fmuStruct.vars[index]; + fmiValueReference vr = fmuStruct.fmiValueReferences[index]; + double real; + fmiInteger integer; + fmiBoolean fmibool; + + switch (sv->typeSpec->type){ + case elm_Real: + fmuStruct.fmu.getReal(fmuStruct.c, &vr, 1, &real); + break; + case elm_Integer: + case elm_Enumeration: + fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &integer); + real = (double)integer; + break; + case elm_Boolean: + fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &fmibool); + if(fmibool == fmiTrue) + real = 1.0; + else + real = 0.0; + break; + } + return real; +} + +JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmu_FMUControlJNI_getSubscribedResults_1 + (JNIEnv *env, jobject obj, jstring id, jdoubleArray result) { + + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + + jboolean isCopy; + jdouble* resultElements = env -> GetDoubleArrayElements(result, &isCopy); + jsize n = env -> GetArrayLength(result); + + /* + int i; + for (i = 0; i < n; i++) { + if(fmuStruct.subscription.empty() || fmuStruct.fmu.modelDescription == NULL) { + // no subscription or model not initialized + resultElements[i] = 0; + } else if(fmuStruct.subscription[i] < 0) { + // Variable does not exist + resultElements[i] = 0; + } else { + // Get value + resultElements[i] = getRealValue(fmuStruct, fmuStruct.subscription[i]); + } + } + */ + + fmuStruct.fmu.getReal(fmuStruct.c, &fmuStruct.subscription[0], n, resultElements); + + if (isCopy == JNI_TRUE) { + env -> ReleaseDoubleArrayElements(result, resultElements, 0); + } + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + throwException(env, "getSubscribedResults: Model id " + message + " not found"); + } + + return result; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_instantiateSimulation_1 + (JNIEnv *env, jobject obj, jstring id) { + + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + + int k; + string s; + + + FMU& fmu = fmuStruct.fmu; + + //ModelDescription* md = fmu.modelDescription; + if(fmu.modelDescription == NULL) + return throwException(env, "No FMU loaded"); + + fmuStruct.currentTime = 0; // start time + + // instantiate the fmu + fmuStruct.guid = getString(fmu.modelDescription, att_guid); + fmuStruct.callbacks.logger = fmuLogger; + fmuStruct.callbacks.allocateMemory = calloc; + fmuStruct.callbacks.freeMemory = free; + fmuStruct.c = fmu.instantiateModel(getModelIdentifier(fmu.modelDescription), fmuStruct.guid, fmuStruct.callbacks, fmiFalse); + if (!fmuStruct.c) return throwException(env, "could not instantiate model"); + + // allocate memory + fmuStruct.nx = getNumberOfStates(fmu.modelDescription); + fmuStruct.nz = getNumberOfEventIndicators(fmu.modelDescription); // + + fmuStruct.x = (double *) calloc(fmuStruct.nx, sizeof(double)); + fmuStruct.xdot = (double *) calloc(fmuStruct.nx, sizeof(double)); + + if (fmuStruct.nz>0) { // + fmuStruct.z = (double *) calloc(fmuStruct.nz, sizeof(double)); // + fmuStruct.prez = (double *) calloc(fmuStruct.nz, sizeof(double)); // + } + + //if (!x || !xdot) return error("out of memory"); + if (!fmuStruct.x || !fmuStruct.xdot || fmuStruct.nz>0 && (!fmuStruct.z || !fmuStruct.prez)) return throwException(env, "out of memory"); + + // set the start time + fmuStruct.fmiFlag = fmu.setTime(fmuStruct.c, fmuStruct.currentTime); + if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not set time"); + + // Clear all variables -vector + fmuStruct.allVariables.clear(); + + // Initialize variable index map and variable vector + fmuStruct.indexes.clear(); + for (k=0; fmuStruct.vars[k]; k++) { + ScalarVariable* sv = fmuStruct.vars[k]; + s = getName(sv); + fmuStruct.indexes.insert ( pair(s,k) ); + } + + // Set initialized flag to 0 + fmuStruct.initialized = false; + + fflush(stdout); + return 1; + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "instantiateSimulation: Model id " + message + " not found"); + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_initializeSimulation_1 + (JNIEnv *env, jobject obj, jstring id) { + + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + + FMU& fmu = fmuStruct.fmu; + + if(fmu.modelDescription == NULL) + return throwException(env, "No FMU loaded"); + + if(fmuStruct.initialized == true) + return throwException(env, "FMU already initialized. Instantiate it first."); + + fmiBoolean toleranceControlled = fmiFalse; + + fmuStruct.fmiFlag = fmu.initialize(fmuStruct.c, toleranceControlled, fmuStruct.currentTime, &(fmuStruct.eventInfo)); + if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not initialize model"); + + fmuStruct.initialized = true; + + fflush(stdout); + return 1; + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "initializeSimulation: Model id " + message + " not found"); + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setTime_1 + (JNIEnv *env, jobject obj, jstring id, jdouble time) { + + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + + FMU& fmu = fmuStruct.fmu; + + fmu.setTime(fmuStruct.c, time); + return 1; + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "setTime: Model id " + message + " not found"); + } +} + +jobjectArray filterVariables(JNIEnv *env, jobject obj, jstring id, string regexp) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + jobjectArray ret; + size_t i; + string s; + // all variables -vector is empty - fill it. + // it is cleared when a new model is initialized. + if(fmuStruct.allVariables.size() < 1) { + for (i=0; fmuStruct.vars[i]; i++) { + ScalarVariable* sv = fmuStruct.vars[i]; + s = getName(sv); + tr1::regex rx(regexp); + if(regex_match(s.begin(), s.end(), rx)) + fmuStruct.allVariables.push_back(s); + } + } + + ret= (jobjectArray)env->NewObjectArray(fmuStruct.allVariables.size(), + env->FindClass("java/lang/String"), + env->NewStringUTF("")); + + for(i=0;iSetObjectArrayElement(ret,i,env->NewStringUTF(fmuStruct.allVariables[i].c_str())); + } + return ret; + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + throwException(env, "getAllVariables: Model id " + message + " not found"); + return (jobjectArray)env->NewObjectArray(0, + env->FindClass("java/lang/String"), + env->NewStringUTF("")); + } +} + +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmu_FMUControlJNI_getAllVariables_1 + (JNIEnv *env, jobject obj, jstring id) { + return filterVariables(env, obj, id, "(.*)"); +} + +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmu_FMUControlJNI_filterVariables_1 + (JNIEnv *env, jobject obj, jstring id, jstring regexp) { + const char *rx = env->GetStringUTFChars(regexp, 0); + jobjectArray result = filterVariables(env, obj, id, rx); + env->ReleaseStringUTFChars(regexp, rx); + return result; +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_simulateStep_1 + (JNIEnv *env, jobject obj, jstring id) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + + if(&fmuStruct.fmu == NULL || fmuStruct.fmu.modelDescription == NULL || &fmuStruct.vars == NULL) { + return throwException(env, "Simulate step failed - fmu not loaded"); + } + + if(fmuStruct.x == NULL) { + return throwException(env, "Simulate step failed - fmu not instantiated"); + } + + if(fmuStruct.initialized == false) { + fmiBoolean toleranceControlled = fmiFalse; + fmuStruct.fmiFlag = fmuStruct.fmu.initialize(fmuStruct.c, toleranceControlled, fmuStruct.currentTime, &(fmuStruct.eventInfo)); + if (fmuStruct.fmiFlag > fmiWarning) return throwException(env, "could not initialize model"); + fmuStruct.initialized = true; + } + + FMU& fmu = fmuStruct.fmu; + int debug = 0; // DEBUG ON = 1, OFF = 0 + + int i; + double dt, tPre, tEnd = fmuStruct.currentTime + fmuStruct.step; + + fmiBoolean timeEvent, stateEvent, stepEvent; + fmiStatus fmiFlag; // return code of the fmu functions + fmiValueReference vr; + + + + /* Simulate the duration of one step. The simulation may be done in + * multiple parts if events occur + */ + while (fmuStruct.currentTime < tEnd) { + // get current state and derivatives + fmiFlag = fmu.getContinuousStates(fmuStruct.c, fmuStruct.x, fmuStruct.nx); + if (fmiFlag > fmiWarning) + return throwException(env, "could not retrieve states"); + + fmiFlag = fmu.getDerivatives(fmuStruct.c, fmuStruct.xdot, fmuStruct.nx); + if (fmiFlag > fmiWarning) + return throwException(env, "could not retrieve derivatives"); + + // advance time + tPre = fmuStruct.currentTime; + fmuStruct.currentTime = min(fmuStruct.currentTime+fmuStruct.step, tEnd); + timeEvent = fmuStruct.eventInfo.upcomingTimeEvent && fmuStruct.eventInfo.nextEventTime < fmuStruct.currentTime; + + if (timeEvent) fmuStruct.currentTime = fmuStruct.eventInfo.nextEventTime; + dt = fmuStruct.currentTime - tPre; + fmiFlag = fmu.setTime(fmuStruct.c, fmuStruct.currentTime); + if (fmiFlag > fmiWarning) throwException(env, "could not set time"); + + if(referenceExists(fmuStruct, "time")) { + vr = getReference(fmuStruct, "time"); + if(vr != NULL) { + fmu.setReal(fmuStruct.c, &vr, 1, &(fmuStruct.currentTime)); + } + } + + if(debug) + printf("Actual time: %lf\n", fmuStruct.currentTime); + + if (fmiFlag > fmiWarning) + return throwException(env, "could not set time"); + + // perform one step + for (i=0; i fmiWarning) + return throwException(env, "could not set states"); + + // Check for step event, e.g. dynamic state selection + fmiFlag = fmu.completedIntegratorStep(fmuStruct.c, &stepEvent); + if (fmiFlag > fmiWarning) return throwException(env, "could not complete intgrator step"); + + for (i=0; i fmiWarning) return throwException(env, "could not retrieve event indicators"); + stateEvent = FALSE; + for (i=0; i fmiWarning) return throwException(env, "could not perform event update"); + + } // if event + + } + + fflush(stdout); + return 1; + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "simulateStep: Model id " + message + " not found"); + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_unloadFMU_1 + (JNIEnv *env, jobject obj, jstring id) { + /* terminate crashes -Teemu + if(! eventInfo.terminateSimulation) ; + fmu.terminate(c); + */ + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct& fmuStruct = fmus[fmuId]; + fmus.erase(fmuId); + env->ReleaseStringUTFChars(id, fmuId); + if(fmuStruct.fmu.modelDescription != NULL) { + + fmuStruct.fmu.freeModelInstance(fmuStruct.c); + freeElement(fmuStruct.fmu.modelDescription); + FreeLibrary((HMODULE)fmuStruct.fmu.dllHandle); + if (fmuStruct.x!=NULL) free(fmuStruct.x); + if (fmuStruct.xdot!= NULL) free(fmuStruct.xdot); + if (fmuStruct.z!= NULL) free(fmuStruct.z); + if (fmuStruct.prez!= NULL) free(fmuStruct.prez); + return 1; + + } else { + + if (fmuStruct.x!=NULL) free(fmuStruct.x); + if (fmuStruct.xdot!= NULL) free(fmuStruct.xdot); + if (fmuStruct.z!= NULL) free(fmuStruct.z); + if (fmuStruct.prez!= NULL) free(fmuStruct.prez); + return throwException(env, "FMU not loaded"); + } + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "unloadFMU: Model id " + message + " not found"); + } +} + +JNIEXPORT jstring JNICALL Java_org_simantics_fmu_FMUControlJNI_getLastErrorMessage_1 + (JNIEnv *env, jobject obj, jstring id) { + return env->NewStringUTF("No errors"); +} + +JNIEXPORT jdouble JNICALL Java_org_simantics_fmu_FMUControlJNI_getRealValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring variable) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + const char *name = env->GetStringUTFChars(variable, 0); + + if(referenceExists(fmuStruct, name)) { + fmiValueReference vr = getReference(fmuStruct, name); + + double real; + fmuStruct.fmu.getReal(fmuStruct.c, &vr, 1, &real); + env->ReleaseStringUTFChars(variable, name); + + return real; + + } else { + string nameString = name; + string message = "Variable " + nameString + " not found"; + env->ReleaseStringUTFChars(variable, name); + return throwException(env, message); + } + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "unloadFMU: Model id " + message + " not found"); + } + +} + +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_getIntegerValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring variable) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + const char *name = env->GetStringUTFChars(variable, 0); + + if(referenceExists(fmuStruct, name)) { + fmiValueReference vr = getReference(fmuStruct, name); + int result; + fmuStruct.fmu.getInteger(fmuStruct.c, &vr, 1, &result); + env->ReleaseStringUTFChars(variable, name); + return result; + + } else { + string nameString = name; + string message = "Variable " + nameString + " not found"; + env->ReleaseStringUTFChars(variable, name); + return throwException(env, message); + } + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "unloadFMU: Model id " + message + " not found"); + } + +} + +JNIEXPORT jboolean JNICALL Java_org_simantics_fmu_FMUControlJNI_getBooleanValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring variable) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + const char *name = env->GetStringUTFChars(variable, 0); + + if(referenceExists(fmuStruct, name)) { + fmiValueReference vr = getReference(fmuStruct, name); + fmiBoolean result; + fmuStruct.fmu.getBoolean(fmuStruct.c, &vr, 1, &result); + env->ReleaseStringUTFChars(variable, name); + return result; + + } else { + string nameString = name; + string message = "Variable " + nameString + " not found"; + env->ReleaseStringUTFChars(variable, name); + return throwException(env, message); + } + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return throwException(env, "unloadFMU: Model id " + message + " not found"); + } + +} + +JNIEXPORT jstring JNICALL Java_org_simantics_fmu_FMUControlJNI_getStringValue_1 + (JNIEnv *env, jobject obj, jstring id, jstring variable) { + const char *fmuId = env->GetStringUTFChars(id, 0); + if(exists(fmuId)) { + FMUControlStruct fmuStruct = fmus[fmuId]; + env->ReleaseStringUTFChars(id, fmuId); + const char *name = env->GetStringUTFChars(variable, 0); + + if(referenceExists(fmuStruct, name)) { + fmiValueReference vr = getReference(fmuStruct, name); + fmiString result; + fmuStruct.fmu.getString(fmuStruct.c, &vr, 1, &result); + env->ReleaseStringUTFChars(variable, name); + return env->NewStringUTF(result); + + } else { + string nameString = name; + string message = "Variable " + nameString + " not found"; + env->ReleaseStringUTFChars(variable, name); + return 0; //throwException(env, message); + } + + } else { + string message = fmuId; + env->ReleaseStringUTFChars(id, fmuId); + return 0; //throwException(env, "unloadFMU: Model id " + message + " not found"); + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/sim_support.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/sim_support.c new file mode 100644 index 00000000..b13dd783 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/sim_support.c @@ -0,0 +1,508 @@ +/* ------------------------------------------------------------------------- + * sim_support.c + * Functions used by both FMU simulators fmusim_me and fmusim_cs + * to parse command-line arguments, to unzip and load an fmu, + * to write CSV file, and more. + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +#ifdef FMI_COSIMULATION +#include "fmi_cs.h" +#else +#include "fmi_me.h" +#endif + +#include "sim_support.h" +#include "fmuExtract.h" + +int unzip(const char *zipPath, const char *outPath) { + //int code; + //char cwd[BUFSIZE]; + //char binPath[BUFSIZE]; + //int n = strlen(UNZIP_CMD) + strlen(outPath) + 1 + strlen(zipPath) + 9; + //char* cmd = (char*)calloc(sizeof(char), n); + + //// remember current directory + //if (!GetCurrentDirectory(BUFSIZE, cwd)) { + // printf ("error: Could not get current directory\n"); + // return 0; // error + //} + // + //// change to %FMUSDK_HOME%\bin to find 7z.dll and 7z.exe + //if (!GetEnvironmentVariable("FMUSDK_HOME", binPath, BUFSIZE)) { + // if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + // printf ("error: Environment variable FMUSDK_HOME not defined\n"); + // } + // else { + // printf ("error: Could not get value of FMUSDK_HOME\n"); + // } + // return 0; // error + //} + //strcat(binPath, "\\bin"); + //if (!SetCurrentDirectory(binPath)) { + // printf ("error: could not change to directory '%s'\n", binPath); + // return 0; // error + //} + + //// run the unzip command + //// remove "> NUL" to see the unzip protocol + //sprintf(cmd, "%s%s \"%s\" > NUL", UNZIP_CMD, outPath, zipPath); + //// printf("cmd='%s'\n", cmd); + //code = system(cmd); + //free(cmd); + //if (code!=SEVEN_ZIP_NO_ERROR) { + // switch (code) { + // printf("7z: "); + // case SEVEN_ZIP_WARNING: printf("warning\n"); break; + // case SEVEN_ZIP_ERROR: printf("error\n"); break; + // case SEVEN_ZIP_COMMAND_LINE_ERROR: printf("command line error\n"); break; + // case SEVEN_ZIP_OUT_OF_MEMORY: printf("out of memory\n"); break; + // case SEVEN_ZIP_STOPPED_BY_USER: printf("stopped by user\n"); break; + // default: printf("unknown problem\n"); + // } + //} + // + //// restore current directory + //SetCurrentDirectory(cwd); + // + //return (code==SEVEN_ZIP_NO_ERROR || code==SEVEN_ZIP_WARNING) ? 1 : 0; + + // Get current directory + TCHAR s[260]; + DWORD a = GetCurrentDirectory(260, s); + + int ret = unzipFMU(zipPath, outPath); // unzip changes the current directory + + // Restore current direcory + SetCurrentDirectory(s); + return ret; +} + +// fileName is an absolute path, e.g. C:\test\a.fmu +// or relative to the current dir, e.g. ..\test\a.fmu +// Does not check for existence of the file +static char* getFmuPath(const char* fileName){ + char pathName[MAX_PATH]; + int n = GetFullPathName(fileName, MAX_PATH, pathName, NULL); + return n ? strdup(pathName) : NULL; +} + +int tmpPathRequests = 0; +static char* getTmpPath() { + char tmpPath[BUFSIZE]; + if(! GetTempPath(BUFSIZE, tmpPath)) { + printf ("error: Could not find temporary disk space\n"); + return NULL; + } + if(tmpPathRequests % 2 == 0) { + strcat(tmpPath, "fmu\\"); + tmpPathRequests++; + } else { + strcat(tmpPath, "fmu2\\"); + tmpPathRequests = 0; + } + + makedir(tmpPath); + + return strdup(tmpPath); +} + +static void* getAdr(int* s, FMU *fmu, const char* functionName){ + char name[BUFSIZE]; + void* fp; + sprintf(name, "%s_%s", getModelIdentifier(fmu->modelDescription), functionName); + fp = GetProcAddress(fmu->dllHandle, name); + if (!fp) { + printf ("warning: Function %s not found in dll\n", name); + *s = 0; // mark dll load as 'failed' + } + return fp; +} + +// Load the given dll and set function pointers in fmu +// Return 0 to indicate failure +static int loadDll(const char* dllPath, FMU *fmu) { + int x = 1, s = 1; + HANDLE h = LoadLibrary(dllPath); + if (!h) { + printf("error: Could not load %s\n", dllPath); + return 0; // failure + } + fmu->dllHandle = h; + +#ifdef FMI_COSIMULATION + fmu->getTypesPlatform = (fGetTypesPlatform) getAdr(&s, fmu, "fmiGetTypesPlatform"); + if (s==0) { + s = 1; // work around bug for FMUs exported using Dymola 2012 and SimulationX 3.x + fmu->getTypesPlatform = (fGetTypesPlatform) getAdr(&s, fmu, "fmiGetModelTypesPlatform"); + if (s==1) printf(" using fmiGetModelTypesPlatform instead\n", dllPath); + } + fmu->instantiateSlave = (fInstantiateSlave) getAdr(&s, fmu, "fmiInstantiateSlave"); + fmu->initializeSlave = (fInitializeSlave) getAdr(&s, fmu, "fmiInitializeSlave"); + fmu->terminateSlave = (fTerminateSlave) getAdr(&s, fmu, "fmiTerminateSlave"); + fmu->resetSlave = (fResetSlave) getAdr(&s, fmu, "fmiResetSlave"); + fmu->freeSlaveInstance = (fFreeSlaveInstance) getAdr(&s, fmu, "fmiFreeSlaveInstance"); + fmu->setRealInputDerivatives = (fSetRealInputDerivatives) getAdr(&s, fmu, "fmiSetRealInputDerivatives"); + fmu->getRealOutputDerivatives = (fGetRealOutputDerivatives) getAdr(&s, fmu, "fmiGetRealOutputDerivatives"); + fmu->cancelStep = (fCancelStep) getAdr(&s, fmu, "fmiCancelStep"); + fmu->doStep = (fDoStep) getAdr(&s, fmu, "fmiDoStep"); + // SimulationX 3.4 and 3.5 do not yet export getStatus and getXStatus: do not count this as failure here + fmu->getStatus = (fGetStatus) getAdr(&x, fmu, "fmiGetStatus"); + fmu->getRealStatus = (fGetRealStatus) getAdr(&x, fmu, "fmiGetRealStatus"); + fmu->getIntegerStatus = (fGetIntegerStatus) getAdr(&x, fmu, "fmiGetIntegerStatus"); + fmu->getBooleanStatus = (fGetBooleanStatus) getAdr(&x, fmu, "fmiGetBooleanStatus"); + fmu->getStringStatus = (fGetStringStatus) getAdr(&x, fmu, "fmiGetStringStatus"); + +#else // FMI for Model Exchange 1.0 + fmu->getModelTypesPlatform = (fGetModelTypesPlatform) getAdr(&s, fmu, "fmiGetModelTypesPlatform"); + fmu->instantiateModel = (fInstantiateModel) getAdr(&s, fmu, "fmiInstantiateModel"); + fmu->freeModelInstance = (fFreeModelInstance) getAdr(&s, fmu, "fmiFreeModelInstance"); + fmu->setTime = (fSetTime) getAdr(&s, fmu, "fmiSetTime"); + fmu->setContinuousStates = (fSetContinuousStates)getAdr(&s, fmu, "fmiSetContinuousStates"); + fmu->completedIntegratorStep = (fCompletedIntegratorStep)getAdr(&s, fmu, "fmiCompletedIntegratorStep"); + fmu->initialize = (fInitialize) getAdr(&s, fmu, "fmiInitialize"); + fmu->getDerivatives = (fGetDerivatives) getAdr(&s, fmu, "fmiGetDerivatives"); + fmu->getEventIndicators = (fGetEventIndicators) getAdr(&s, fmu, "fmiGetEventIndicators"); + fmu->eventUpdate = (fEventUpdate) getAdr(&s, fmu, "fmiEventUpdate"); + fmu->getContinuousStates = (fGetContinuousStates)getAdr(&s, fmu, "fmiGetContinuousStates"); + fmu->getNominalContinuousStates = (fGetNominalContinuousStates)getAdr(&s, fmu, "fmiGetNominalContinuousStates"); + fmu->getStateValueReferences = (fGetStateValueReferences)getAdr(&s, fmu, "fmiGetStateValueReferences"); + fmu->terminate = (fTerminate) getAdr(&s, fmu, "fmiTerminate"); +#endif + fmu->getVersion = (fGetVersion) getAdr(&s, fmu, "fmiGetVersion"); + fmu->setDebugLogging = (fSetDebugLogging) getAdr(&s, fmu, "fmiSetDebugLogging"); + fmu->setReal = (fSetReal) getAdr(&s, fmu, "fmiSetReal"); + fmu->setInteger = (fSetInteger) getAdr(&s, fmu, "fmiSetInteger"); + fmu->setBoolean = (fSetBoolean) getAdr(&s, fmu, "fmiSetBoolean"); + fmu->setString = (fSetString) getAdr(&s, fmu, "fmiSetString"); + fmu->getReal = (fGetReal) getAdr(&s, fmu, "fmiGetReal"); + fmu->getInteger = (fGetInteger) getAdr(&s, fmu, "fmiGetInteger"); + fmu->getBoolean = (fGetBoolean) getAdr(&s, fmu, "fmiGetBoolean"); + fmu->getString = (fGetString) getAdr(&s, fmu, "fmiGetString"); + return s; +} + +static void printModelDescription(ModelDescription* md){ + Element* e = (Element*)md; + int i; + printf("%s\n", elmNames[e->type]); + for (i=0; in; i+=2) + printf(" %s=%s\n", e->attributes[i], e->attributes[i+1]); +#ifdef FMI_COSIMULATION + if (!md->cosimulation) { + printf("error: No Implementation element found in model description. This FMU is not for Co-Simulation.\n"); + exit(EXIT_FAILURE); + } + e = md->cosimulation->capabilities; + printf("%s\n", elmNames[e->type]); + for (i=0; in; i+=2) + printf(" %s=%s\n", e->attributes[i], e->attributes[i+1]); +#endif // FMI_COSIMULATION +} + +/* + * return: 1 for successful laod or number for error. + * -1. FMU path not found + * -2. Unzip failed + * -3. Loading model description failed + * -4. FMU dll load failed + */ +int loadFMU(FMU *fmu, const char* fmuFileName, const char* tmpPath) { + char* fmuPath; + char* xmlPath; + char* dllPath; + unsigned old_clock = clock(); + unsigned current_clock = 0;//will be assigned later + + // get absolute path to FMU, NULL if not found + fmuPath = getFmuPath(fmuFileName); + if (!fmuPath) return -1; // path not found + + // unzip the FMU to the tmpPath directory + if (unzip(fmuPath, tmpPath)) return -2; // unzip failed + + // parse tmpPath\modelDescription.xml + xmlPath = calloc(sizeof(char), strlen(tmpPath) + strlen(XML_FILE) + 1); + sprintf(xmlPath, "%s%s", tmpPath, XML_FILE); + fmu->modelDescription = parse(xmlPath); + free(xmlPath); + if (!fmu->modelDescription) return -3; // loading model description failed + + // printModelDescription(fmu.modelDescription); + // fflush(stdout); + + // load the FMU dll + dllPath = calloc(sizeof(char), strlen(tmpPath) + strlen(DLL_DIR) + + strlen( getModelIdentifier(fmu->modelDescription)) + strlen(".dll") + 1); + sprintf(dllPath,"%s%s%s.dll", tmpPath, DLL_DIR, getModelIdentifier(fmu->modelDescription)); + if (!loadDll(dllPath, fmu)) return -4; // loading dll failed + + free(dllPath); + free(fmuPath); + + return 1; +} + +static void doubleToCommaString(char* buffer, double r){ + char* comma; + sprintf(buffer, "%.16g", r); + comma = strchr(buffer, '.'); + if (comma) *comma = ','; +} + +// output time and all non-alias variables in CSV format +// if separator is ',', columns are separated by ',' and '.' is used for floating-point numbers. +// otherwise, the given separator (e.g. ';' or '\t') is to separate columns, and ',' is used +// as decimal dot in floating-point numbers. +void outputRow(FMU *fmu, fmiComponent c, double time, FILE* file, char separator, boolean header) { + int k; + fmiReal r; + fmiInteger i; + fmiBoolean b; + fmiString s; + fmiValueReference vr; + ScalarVariable** vars = fmu->modelDescription->modelVariables; + char buffer[32]; + + // print first column + if (header) + fprintf(file, "time"); + else { + if (separator==',') + fprintf(file, "%.16g", time); + else { + // separator is e.g. ';' or '\t' + doubleToCommaString(buffer, time); + fprintf(file, "%s", buffer); + } + } + + // print all other columns + for (k=0; vars[k]; k++) { + ScalarVariable* sv = vars[k]; + if (getAlias(sv)!=enu_noAlias) continue; + if (header) { + // output names only + if (separator==',') { + // treat array element, e.g. print a[1, 2] as a[1.2] + char* s = getName(sv); + fprintf(file, "%c", separator); + while (*s) { + if (*s!=' ') fprintf(file, "%c", *s==',' ? '.' : *s); + s++; + } + } + else + fprintf(file, "%c%s", separator, getName(sv)); + } + else { + // output values + vr = getValueReference(sv); + switch (sv->typeSpec->type){ + case elm_Real: + fmu->getReal(c, &vr, 1, &r); + if (separator==',') + fprintf(file, ",%.16g", r); + else { + // separator is e.g. ';' or '\t' + doubleToCommaString(buffer, r); + fprintf(file, "%c%s", separator, buffer); + } + break; + case elm_Integer: + case elm_Enumeration: + fmu->getInteger(c, &vr, 1, &i); + fprintf(file, "%c%d", separator, i); + break; + case elm_Boolean: + fmu->getBoolean(c, &vr, 1, &b); + fprintf(file, "%c%d", separator, b); + break; + case elm_String: + fmu->getString(c, &vr, 1, &s); + fprintf(file, "%c%s", separator, s); + break; + default: + fprintf(file, "%cNoValueForType=%d", separator,sv->typeSpec->type); + } + } + } // for + + // terminate this row + fprintf(file, "\n"); +} + +static const char* fmiStatusToString(fmiStatus status){ + switch (status){ + case fmiOK: return "ok"; + case fmiWarning: return "warning"; + case fmiDiscard: return "discard"; + case fmiError: return "error"; + case fmiFatal: return "fatal"; +#ifdef FMI_COSIMULATION + case fmiPending: return "fmiPending"; +#endif + default: return "?"; + } +} + +// search a fmu for the given variable +// return NULL if not found or vr = fmiUndefinedValueReference +static ScalarVariable* getSV(FMU* fmu, char type, fmiValueReference vr) { + int i; + Elm tp; + ScalarVariable** vars = fmu->modelDescription->modelVariables; + if (vr==fmiUndefinedValueReference) return NULL; + switch (type) { + case 'r': tp = elm_Real; break; + case 'i': tp = elm_Integer; break; + case 'b': tp = elm_Boolean; break; + case 's': tp = elm_String; break; + } + for (i=0; vars[i]; i++) { + ScalarVariable* sv = vars[i]; + if (vr==getValueReference(sv) && tp==sv->typeSpec->type) + return sv; + } + return NULL; +} + +// replace e.g. #r1365# by variable name and ## by # in message +// copies the result to buffer +static void replaceRefsInMessage(const char* msg, char* buffer, int nBuffer, FMU* fmu){ + int i=0; // position in msg + int k=0; // position in buffer + int n; + char c = msg[i]; + while (c!='\0' && k < nBuffer) { + if (c!='#') { + buffer[k++]=c; + i++; + c = msg[i]; + } + else { + char* end = strchr(msg+i+1, '#'); + if (!end) { + printf("unmatched '#' in '%s'\n", msg); + buffer[k++]='#'; + break; + } + n = end - (msg+i); + if (n==1) { + // ## detected, output # + buffer[k++]='#'; + i += 2; + c = msg[i]; + } + else { + char type = msg[i+1]; // one of ribs + fmiValueReference vr; + int nvr = sscanf(msg+i+2, "%u", &vr); + if (nvr==1) { + // vr of type detected, e.g. #r12# + ScalarVariable* sv = getSV(fmu, type, vr); + const char* name = sv ? getName(sv) : "?"; + sprintf(buffer+k, "%s", name); + k += strlen(name); + i += (n+1); + c = msg[i]; + } + else { + // could not parse the number + printf("illegal value reference at position %d in '%s'\n", i+2, msg); + buffer[k++]='#'; + break; + } + } + } + } // while + buffer[k] = '\0'; +} + +#define MAX_MSG_SIZE 1000 +void fmuLogger(FMU *fmu, fmiComponent c, fmiString instanceName, fmiStatus status, + fmiString category, fmiString message, ...) { + char msg[MAX_MSG_SIZE]; + char* copy; + va_list argp; + + // replace C format strings + va_start(argp, message); + vsprintf(msg, message, argp); + + // replace e.g. ## and #r12# + copy = strdup(msg); + replaceRefsInMessage(copy, msg, MAX_MSG_SIZE, fmu); + free(copy); + + // print the final message + if (!instanceName) instanceName = "?"; + if (!category) category = "?"; + printf("%s %s (%s): %s\n", fmiStatusToString(status), instanceName, category, msg); +} + +int error(const char* message){ + printf("%s\n", message); + return 0; +} + +void parseArguments(int argc, char *argv[], char** fmuFileName, double* tEnd, double* h, int* loggingOn, char* csv_separator) { + // parse command line arguments + if (argc>1) { + *fmuFileName = argv[1]; + } + else { + printf("error: no fmu file\n"); + printHelp(argv[0]); + exit(EXIT_FAILURE); + } + if (argc>2) { + if (sscanf(argv[2],"%lf", tEnd) != 1) { + printf("error: The given end time (%s) is not a number\n", argv[2]); + exit(EXIT_FAILURE); + } + } + if (argc>3) { + if (sscanf(argv[3],"%lf", h) != 1) { + printf("error: The given stepsize (%s) is not a number\n", argv[3]); + exit(EXIT_FAILURE); + } + } + if (argc>4) { + if (sscanf(argv[4],"%d", loggingOn) != 1 || *loggingOn<0 || *loggingOn>1) { + printf("error: The given logging flag (%s) is not boolean\n", argv[4]); + exit(EXIT_FAILURE); + } + } + if (argc>5) { + if (strlen(argv[5]) != 1) { + printf("error: The given CSV separator char (%s) is not valid\n", argv[5]); + exit(EXIT_FAILURE); + } + switch (argv[5][0]) { + case 'c': *csv_separator = ','; break; // comma + case 's': *csv_separator = ';'; break; // semicolon + default: *csv_separator = argv[5][0]; break; // any other char + } + } + if (argc>6) { + printf("warning: Ignoring %d additional arguments: %s ...\n", argc-6, argv[6]); + printHelp(argv[0]); + } +} + +void printHelp(const char* fmusim) { + printf("command syntax: %s \n", fmusim); + printf(" .... path to FMU, relative to current dir or absolute, required\n"); + printf(" ......... end time of simulation, optional, defaults to 1.0 sec\n"); + printf(" ............ step size of simulation, optional, defaults to 0.1 sec\n"); + printf(" .... 1 to activate logging, optional, defaults to 0\n"); + printf(" . separator in csv file, optional, c for ';', s for';', defaults to c\n"); +} + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/stack.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/stack.c new file mode 100644 index 00000000..042b796b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/stack.c @@ -0,0 +1,85 @@ +/* ------------------------------------------------------------------------- + * stack.c + * A stack of pointers. + * Copyright 2010 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#include +#include +#include +#include "stack.h" + +Stack* stackNew(int initialSize, int inc){ + Stack* s = (Stack*)malloc(sizeof(Stack)); + s->stack = NULL; + s->stackSize = 0; + s->stackPos = -1; + s->initialSize = initialSize; + s->inc = inc; + return s; +} + +int stackIsEmpty(Stack* s) { + return s->stackPos == -1; +} + +// add an element to stack and grow stack if required +// returns 1 to indicate success and 0 for error +int stackPush(Stack* s, void* e) { + s->stackPos++; + if (s->stackPos==s->stackSize){ + s->stackSize += (s->stack ? s->inc: s->initialSize); + s->stack = (void**) realloc(s->stack, s->stackSize * sizeof(void*)); + if (!s->stack) return 0; // error; + } + s->stack[s->stackPos] = e; + return 1; // success +} + +// return top element (possibly NULL), if stack not empty +// runtime error if stack is empty +void* stackPeek(Stack* s){ + assert(!stackIsEmpty(s)); + return s->stack[s->stackPos]; +} + +// remove top element (possibly NULL) from stack and return it +// runtime error if stack is empty +void* stackPop(Stack* s){ + assert(!stackIsEmpty(s)); + return s->stack[s->stackPos--]; +} + +// return the last n elements as null terminated array, +// or NULL if memory allocation fails +void** stackLastPopedAsArray0(Stack* s, int n){ + int i; + void** array = (void**)malloc((n + 1)*sizeof(void*)); + if (! array) return NULL; // failure + for (i=0; istack[i+ s->stackPos + 1]; + } + array[n]=NULL; // terminating NULL + return array; +} + +// return stack as possibly empty array, or NULL if memory allocation fails +// On sucessful return, the stack is empty. +void** stackPopAllAsArray(Stack* s, int *size) { + int i; + void** array = (void**)malloc((s->stackPos + 1)*sizeof(void*)); + if (! array) return NULL; // failure + *size = s->stackPos + 1; + for (i=0; i<*size; i++) + array[i] = s->stack[i]; + s->stackPos = -1; + return array; +} + +// release the given stack +void stackFree(Stack* s){ + if (s->stack) free(s->stack); + free(s); +} + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/xml_parser.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/xml_parser.c new file mode 100644 index 00000000..93e62162 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSimulator/src/xml_parser.c @@ -0,0 +1,860 @@ +/* ------------------------------------------------------------------------- + * xml_Parser.c + * A parser for file modelVariables.xml of an FMU. + * The parser creates an AST (abstract syntax tree) for a given XML file. + * The root node of the AST is of type ModelDescription. + * Validation already performed by this parser + * - check for match of open/close elements (performed by Expat) + * - ceck element, attribute and enum value names, all case sensitive + * - check for each element that is has the expected parent element + * - check for correct sequence of elements + * - check that all decalaredType values reference an existing Type + * Validation to be performed by this parser + * - check for each attribute value that it is of the expected type + * - check that required attributes are present + * - check that dependencies are only declared for outputs and + * refer only to inputs + * Author: Jakob Mauss + * Copyright 2011 QTronic GmbH. All rights reserved. + * -------------------------------------------------------------------------*/ + +#include +#include +#include +#include "xml_parser.h" + +const char *elmNames[SIZEOF_ELM] = { + "fmiModelDescription","UnitDefinitions","BaseUnit","DisplayUnitDefinition","TypeDefinitions", + "Type","RealType","IntegerType","BooleanType","StringType","EnumerationType","Item", + "DefaultExperiment","VendorAnnotations","Tool","Annotation", "ModelVariables","ScalarVariable", + "DirectDependency","Name","Real","Integer","Boolean","String","Enumeration", + "Implementation","CoSimulation_StandAlone","CoSimulation_Tool","Model","File","Capabilities" +}; + +const char *attNames[SIZEOF_ATT] = { + "fmiVersion","displayUnit","gain","offset","unit","name","description","quantity", "relativeQuantity", + "min","max","nominal","declaredType","start","fixed","startTime","stopTime","tolerance","value", + "valueReference","variability","causality","alias", "modelName","modelIdentifier","guid","author", + "version","generationTool","generationDateAndTime","variableNamingConvention","numberOfContinuousStates", + "numberOfEventIndicators","input", + "canHandleVariableCommunicationStepSize","canHandleEvents","canRejectSteps","canInterpolateInputs", + "maxOutputDerivativeOrder","canRunAsynchronuously","canSignalEvents","canBeInstantiatedOnlyOncePerProcess", + "canNotUseMemoryManagementFunctions","file","entryPoint","manualStart","type" +}; + +const char *enuNames[SIZEOF_ENU] = { + "flat","structured","constant","parameter","discrete","continuous", + "input","output", "internal","none","noAlias","alias","negatedAlias" +}; + +#define ANY_TYPE -1 +#define XMLBUFSIZE 1024 +char text[XMLBUFSIZE]; // XML file is parsed in chunks of length XMLBUFZIZE +XML_Parser parser = NULL; // non-NULL during parsing +Stack* stack = NULL; // the parser stack +char* data = NULL; // buffer that holds element content, see handleData +int skipData=0; // 1 to ignore element content, 0 when recordig content + +// ------------------------------------------------------------------------- +// Low-level functions for inspecting the model description + +const char* getString(void* element, Att a){ + Element* e = (Element*)element; + const char** attr = e->attributes; + int i; + for (i=0; in; i+=2) + if (attr[i]==attNames[a]) return attr[i+1]; + return NULL; +} + +double getDouble(void* element, Att a, ValueStatus* vs){ + double d = 0; + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return d; } + *vs = (1==sscanf(value, "%lf", &d)) ? valueDefined : valueIllegal; + return d; +} + +// getInt() is also used to retrieve Enumeration values from XML, +// e.g. the start value for a variable of user-defined enumeration type. +int getInt(void* element, Att a, ValueStatus* vs){ + int n = 0; + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return n; } + *vs = (1==sscanf(value, "%d", &n)) ? valueDefined : valueIllegal; + return n; +} + +unsigned int getUInt(void* element, Att a, ValueStatus* vs){ + unsigned int u = -1; + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return u; } + *vs = (1==sscanf(value, "%u", &u)) ? valueDefined : valueIllegal; + return u; +} + +char getBoolean(void* element, Att a, ValueStatus* vs){ + const char* value = getString(element, a); + if (!value) { *vs=valueMissing; return 0; }; + *vs = valueDefined; + if (!strcmp(value, "true")) return 1; + if (!strcmp(value, "false")) return 0; + *vs = valueIllegal; + return 0; +} + +static int checkEnumValue(const char* enu); + +// Retrieve the value of the given built-in enum attribute. +// If the value is missing, this is marked in the ValueStatus +// and the corresponding default is returned. +// Returns -1 or a globally unique id for the value such that +// enuNames[id] is the string representation of the enum value. +Enu getEnumValue(void* element, Att a, ValueStatus* vs) { + const char* value = getString(element, a); + Enu id = valueDefined; + if (!value) { + *vs = valueMissing; + switch (a) { + case att_variableNamingConvention: return enu_flat; + case att_variability: return enu_continuous; + case att_causality: return enu_internal; + case att_alias: return enu_noAlias; + default: return -1; + } + } + id = checkEnumValue(value); + if (id==-1) *vs = valueIllegal; + return id; +} + +// ------------------------------------------------------------------------- +// Convenience methods for accessing the model description. +// Use is only safe after the ast has been successfuly validated. + +const char* getModelIdentifier(ModelDescription* md) { + const char* modelId = getString(md, att_modelIdentifier); + assert(modelId); // this is a required attribute + return modelId; +} + +int getNumberOfStates(ModelDescription* md) { + ValueStatus vs; + int n = getUInt(md, att_numberOfContinuousStates, &vs); + assert(vs==valueDefined); // this is a required attribute + return n; +} + +int getNumberOfEventIndicators(ModelDescription* md) { + ValueStatus vs; + int n = getInt(md, att_numberOfEventIndicators, &vs); + assert(vs==valueDefined); // this is a required attribute + return n; +} + +// name is a required attribute of ScalarVariable, Type, Item, Annotation, and Tool +const char* getName(void* element) { + const char* name = getString(element, att_name); + assert(name); // this is a required attribute + return name; +} + +// returns one of: input, output, internal, none +// if value is missing, the default internal is returned +Enu getCausality(void* scalarVariable) { + ValueStatus vs; + return getEnumValue(scalarVariable, att_causality, &vs); +} + +// returns one of constant, parameter, discrete, continuous +// if value is missing, the default continuous is returned +Enu getVariability(void* scalarVariable) { + ValueStatus vs; + return getEnumValue(scalarVariable, att_variability, &vs); +} + +// returns one of noAlias, alias, negatedAlias +// if value is missing, the default noAlias is returned +Enu getAlias(void* scalarVariable) { + ValueStatus vs; + return getEnumValue(scalarVariable, att_alias, &vs); +} + +// the vr is unique only for one of the 4 base data types r,i,b,s and +// may also be fmiUndefinedValueReference = 4294967295 = 0xFFFFFFFF +// here, i means integer or enumeration +fmiValueReference getValueReference(void* scalarVariable) { + ValueStatus vs; + fmiValueReference vr = getUInt(scalarVariable, att_valueReference, &vs); + assert(((Element*)scalarVariable)->type == elm_ScalarVariable); + assert(vs==valueDefined); // this is a reqired attribute + return vr; +} + +// the name is unique within a fmu +ScalarVariable* getVariableByName(ModelDescription* md, const char* name) { + int i; + if (md->modelVariables) + for (i=0; md->modelVariables[i]; i++){ + ScalarVariable* sv = (ScalarVariable*)md->modelVariables[i]; + if (!strcmp(getName(sv), name)) return sv; + } + return NULL; +} + +// Enumeration and Integer have the same base type while +// Real, String, Boolean define own base types. +int sameBaseType(Elm t1, Elm t2){ + return t1==t2 || + t1==elm_Enumeration && t2==elm_Integer || + t2==elm_Enumeration && t1==elm_Integer; +} + +// returns NULL if variable not found or vr==fmiUndefinedValueReference +ScalarVariable* getVariable(ModelDescription* md, fmiValueReference vr, Elm type){ + int i; + if (md->modelVariables && vr!=fmiUndefinedValueReference) + for (i=0; md->modelVariables[i]; i++){ + ScalarVariable* sv = (ScalarVariable*)md->modelVariables[i]; + if (sameBaseType(type, sv->typeSpec->type) && getValueReference(sv) == vr) + return sv; + } + return NULL; +} + +Type* getDeclaredType(ModelDescription* md, const char* declaredType){ + int i; + if (declaredType && md->typeDefinitions) + for (i=0; md->typeDefinitions[i]; i++){ + Type* tp = (Type*)md->typeDefinitions[i]; + if (!strcmp(declaredType, getName(tp))) return tp; + } + return NULL; +} + +const char* getString2(ModelDescription* md, void* tp, Att a) { + Type* type; + const char* value = getString(tp, a); + if (value) return value; // found + // search declared type, if any + type = getDeclaredType(md, getString(tp, att_declaredType)); + return type ? getString(type->typeSpec, a) : NULL; +} + +// Get description from variable or from declared type, or NULL. +const char * getDescription(ModelDescription* md, ScalarVariable* sv) { + const char* value = getString(sv, att_description); + Type* type; + if (value) return value; // found + // search declared type, if any + type = getDeclaredType(md, getString(sv->typeSpec, att_declaredType)); + return type ? getString(type, att_description) : NULL; +} + +// Get attribute value from scalar variable given by vr and type, +// incl. default value provided by declared type, if any. +const char * getVariableAttributeString(ModelDescription* md, + fmiValueReference vr, Elm type, Att a){ + const char* value; + const char* declaredType; + Type* tp; + ScalarVariable* sv = getVariable(md, vr, type); + if (!sv) return NULL; + value = getString(sv->typeSpec, a); + if (value) return value; // found + // search declared type, if any + tp = getDeclaredType(md, getString(sv->typeSpec, att_declaredType)); + return tp ? getString(tp->typeSpec, a) : NULL; +} + +// Get attribute value from scalar variable given by vr and type, +// incl. default value provided by declared type, if any. +double getVariableAttributeDouble(ModelDescription* md, + fmiValueReference vr, Elm type, Att a, ValueStatus* vs){ + double d = 0; + const char* value = getVariableAttributeString(md, vr, type, a); + if (!value) { *vs = valueMissing; return d; } + *vs = (1==sscanf(value, "%lf", &d)) ? valueDefined : valueIllegal; + return d; +} + +// Get nominal value from real variable or its declared type. +// Return 1, if no nominal value is defined. +double getNominal(ModelDescription* md, fmiValueReference vr){ + ValueStatus vs; + double nominal = getVariableAttributeDouble(md, vr, elm_Real, att_nominal, &vs); + return vs==valueDefined ? nominal : 1.0; +} + +// ------------------------------------------------------------------------- +// Various checks that log an error and stop the parser + +// Returns 0 to indicate error +static int checkPointer(const void* ptr){ + if (! ptr) { + printf("Out of memory\n"); + if (parser) XML_StopParser(parser, XML_FALSE); + return 0; // error + } + return 1; // success +} + +static int checkName(const char* name, const char* kind, const char* array[], int n){ + int i; + for (i=0; itype == e) return 1; // success + logFatalTypeError(elmNames[e], elm->type); + return 0; // error +} + +// Returns 0 to indicate error +// Verify that the next stack element exists and is of the given type +// If e==ANY_TYPE, the type check is ommited +static int checkPeek(Elm e) { + if (stackIsEmpty(stack)){ + printf("Illegal document structure, expected %s\n", elmNames[e]); + XML_StopParser(parser, XML_FALSE); + return 0; // error + } + return e==ANY_TYPE ? 1 : checkElementType(stackPeek(stack), e); +} + +// Returns NULL to indicate error +// Get the next stack element, it is of the given type. +// If e==ANY_TYPE, the type check is ommited +static void* checkPop(Elm e){ + return checkPeek(e) ? stackPop(stack) : NULL; +} + +// ------------------------------------------------------------------------- +// Helper + +AstNodeType getAstNodeType(Elm e){ + switch (e) { + case elm_fmiModelDescription: + return astModelDescription; + case elm_Type: + return astType; + case elm_ScalarVariable: + return astScalarVariable; + case elm_CoSimulation_StandAlone: + case elm_CoSimulation_Tool: + return astCoSimulation; + case elm_BaseUnit: + case elm_EnumerationType: + case elm_Tool: + case elm_UnitDefinitions: + case elm_TypeDefinitions: + case elm_VendorAnnotations: + case elm_ModelVariables: + case elm_DirectDependency: + case elm_Model: + return astListElement; + default: + return astElement; + } +} + +// Returns 0 to indicate error +// Copies the attr array and all values. +// Replaces all attribute names by constant literal strings. +// Converts the null-terminated array into an array of known size n. +int addAttributes(Element* el, const char** attr) { + int n, a; + const char** att = NULL; + for (n=0; attr[n]; n+=2); + if (n>0) { + att = calloc(n, sizeof(char*)); + if (!checkPointer(att)) return 0; + } + for (n=0; attr[n]; n+=2) { + char* value = strdup(attr[n+1]); + if (!checkPointer(value)) return 0; + a = checkAttribute(attr[n]); + if (a == -1) return 0; // illegal attribute error + att[n ] = attNames[a]; // no heap memory + att[n+1] = value; // heap memory + } + el->attributes = att; // NULL if n=0 + el->n = n; + return 1; // success +} + +// Returns NULL to indicate error +Element* newElement(Elm type, int size, const char** attr) { + Element* e = (Element*)calloc(1, size); + if (!checkPointer(e)) return NULL; + e->type = type; + e->attributes = NULL; + e->n=0; + if (!addAttributes(e, attr)) return NULL; + return e; +} + +// ------------------------------------------------------------------------- +// callback functions called by the XML parser + +// Create and push a new element node +static void XMLCALL startElement(void *context, const char *elm, const char **attr) { + Elm el; + void* e; + int size; + el = checkElement(elm); + if (el==-1) return; // error + skipData = (el != elm_Name); // skip element content for all elements but Name + switch(getAstNodeType(el)){ + case astElement: size = sizeof(Element); break; + case astListElement: size = sizeof(ListElement); break; + case astType: size = sizeof(Type); break; + case astScalarVariable: size = sizeof(ScalarVariable); break; + case astCoSimulation: size = sizeof(CoSimulation); break; + case astModelDescription: size = sizeof(ModelDescription); break; + default: assert(0); + } + e = newElement(el, size, attr); + checkPointer(e); + stackPush(stack, e); +} + +// Pop all elements of the given type from stack and +// add it to the ListElement that follows. +// The ListElement remains on the stack. +static void popList(Elm e) { + int n = 0; + Element** array; + Element* elm = stackPop(stack); + while (elm->type == e) { + elm = stackPop(stack); + n++; + } + stackPush(stack, elm); // push ListElement back to stack + array = (Element**)stackLastPopedAsArray0(stack, n); // NULL terminated list + if (getAstNodeType(elm->type)!=astListElement) return; // failure + ((ListElement*)elm)->list = array; + return; // success only if list!=NULL +} + +// Pop the children from the stack and +// check for correct type and sequence of children +static void XMLCALL endElement(void *context, const char *elm) { + Elm el; + el = checkElement(elm); + switch(el) { + case elm_fmiModelDescription: + { + ModelDescription* md; + ListElement** ud = NULL; // NULL or list of BaseUnits + Type** td = NULL; // NULL or list of Types + Element* de = NULL; // NULL or DefaultExperiment + ListElement** va = NULL; // NULL or list of Tools + ScalarVariable** mv = NULL; // NULL or list of ScalarVariable + CoSimulation *cs = NULL; // NULL or CoSimulation + ListElement* child; + + child = checkPop(ANY_TYPE); + if (child->type == elm_CoSimulation_StandAlone || child->type == elm_CoSimulation_Tool) { + cs = (CoSimulation*)child; + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_ModelVariables){ + mv = (ScalarVariable**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_VendorAnnotations){ + va = (ListElement**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_DefaultExperiment){ + de = (Element*)child; + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_TypeDefinitions){ + td = (Type**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (child->type == elm_UnitDefinitions){ + ud = (ListElement**)child->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + // work around bug of SimulationX 3.4 and 3.5 which places Implementation at wrong location + if (!cs && (child->type == elm_CoSimulation_StandAlone || child->type == elm_CoSimulation_Tool)) { + cs = (CoSimulation*)child; + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (!checkElementType(child, elm_fmiModelDescription)) return; + md = (ModelDescription*)child; + md->modelVariables = mv; + md->vendorAnnotations = va; + md->defaultExperiment = de; + md->typeDefinitions = td; + md->unitDefinitions = ud; + md->cosimulation = cs; + stackPush(stack, md); + break; + } + case elm_Implementation: + { + // replace Implementation element + void* cs = checkPop(ANY_TYPE); + void* im = checkPop(elm_Implementation); + stackPush(stack, cs); + free(im); + el = ((Element*)cs)->type; + break; + } + case elm_CoSimulation_StandAlone: + { + Element* ca = checkPop(elm_Capabilities); + CoSimulation* cs = checkPop(elm_CoSimulation_StandAlone); + if (!ca || !cs) return; + cs->capabilities = ca; + stackPush(stack, cs); + break; + } + case elm_CoSimulation_Tool: + { + ListElement* mo = checkPop(elm_Model); + Element* ca = checkPop(elm_Capabilities); + CoSimulation* cs = checkPop(elm_CoSimulation_Tool); + if (!ca || !mo || !cs) return; + cs->capabilities = ca; + cs->model = mo; + stackPush(stack, cs); + break; + } + case elm_Type: + { + Type* tp; + Element* ts = checkPop(ANY_TYPE); + if (!ts) return; + if (!checkPeek(elm_Type)) return; + tp = (Type*)stackPeek(stack); + switch (ts->type) { + case elm_RealType: + case elm_IntegerType: + case elm_BooleanType: + case elm_StringType: + case elm_EnumerationType: + break; + default: + logFatalTypeError("RealType or similar", ts->type); + return; + } + tp->typeSpec = ts; + break; + } + case elm_ScalarVariable: + { + ScalarVariable* sv; + Element** list = NULL; + Element* child = checkPop(ANY_TYPE); + if (!child) return; + if (child->type==elm_DirectDependency){ + list = ((ListElement*)child)->list; + free(child); + child = checkPop(ANY_TYPE); + if (!child) return; + } + if (!checkPeek(elm_ScalarVariable)) return; + sv = (ScalarVariable*)stackPeek(stack); + switch (child->type) { + case elm_Real: + case elm_Integer: + case elm_Boolean: + case elm_String: + case elm_Enumeration: + break; + default: + logFatalTypeError("Real or similar", child->type); + return; + } + sv->directDependencies = list; + sv->typeSpec = child; + break; + } + case elm_ModelVariables: popList(elm_ScalarVariable); break; + case elm_VendorAnnotations: popList(elm_Tool);break; + case elm_Tool: popList(elm_Annotation); break; + case elm_TypeDefinitions: popList(elm_Type); break; + case elm_EnumerationType: popList(elm_Item); break; + case elm_UnitDefinitions: popList(elm_BaseUnit); break; + case elm_BaseUnit: popList(elm_DisplayUnitDefinition); break; + case elm_DirectDependency: popList(elm_Name); break; + case elm_Model: popList(elm_File); break; + case elm_Name: + { + // Exception: the name value is represented as element content. + // All other values of the XML file are represented using attributes. + Element* name = checkPop(elm_Name); + if (!name) return; + name->n = 2; + name->attributes = malloc(2*sizeof(char*)); + name->attributes[0] = attNames[att_input]; + name->attributes[1] = data; + data = NULL; + skipData = 1; // stop recording element content + stackPush(stack, name); + break; + } + case -1: return; // illegal element error + default: // must be a leaf Element + assert(getAstNodeType(el)==astElement); + break; + } + // All children of el removed from the stack. + // The top element must be of type el now. + checkPeek(el); +} + +// Called to handle element data, e.g. "xy" in xy +// Can be called many times, e.g. with "x" and then with "y" in the example above. +// Feature in expat: +// For some reason, if the element data is the empty string (Eg. ) +// instead of an empty string with len == 0 we get "\n". The workaround is +// to replace this with the empty string whenever we encounter "\n". +void XMLCALL handleData(void *context, const XML_Char *s, int len) { + int n; + if (skipData) return; + if (!data) { + // start a new data string + if (len == 1 && s[0] == '\n') { + data = strdup(""); + } else { + data = malloc(len + 1); + strncpy(data, s, len); + data[len] = '\0'; + } + } + else { + // continue existing string + n = strlen(data) + len; + data = realloc(data, n+1); + strncat(data, s, len); + data[n] = '\0'; + } + return; +} + +// ------------------------------------------------------------------------- +// printing + +static void printList(int indent, void** list); + +void printElement(int indent, void* element){ + int i; + Element* e = (Element*)element; + if (!e) return; + // print attributes + for (i=0; itype]); + for (i=0; in; i+=2) + printf(" %s=%s", e->attributes[i], e->attributes[i+1]); + printf("\n"); + // print child nodes + indent += 2; + switch (getAstNodeType(e->type)) { + case astListElement: + printList(indent, ((ListElement*)e)->list); + break; + case astScalarVariable: + printElement(indent, ((Type*)e)->typeSpec); + printList(indent, ((ScalarVariable*)e)->directDependencies); + break; + case astType: + printElement(indent, ((Type*)e)->typeSpec); + break; + case astCoSimulation: { + CoSimulation* cs = (CoSimulation*)e; + printElement(indent, cs->capabilities); + printElement(indent, cs->model); + break; + } + case astModelDescription: { + ModelDescription *md = (ModelDescription*)e; + printList(indent, md->unitDefinitions); + printList(indent, md->typeDefinitions); + printElement(indent, md->defaultExperiment); + printList(indent, md->vendorAnnotations); + printList(indent, md->modelVariables); + printElement(indent, md->cosimulation); + break; + } + } +} + +static void printList(int indent, void** list){ + int i; + if (list) for (i=0; list[i]; i++) + printElement(indent, list[i]); +} + +// ------------------------------------------------------------------------- +// free memory of the AST + +static void freeList(void** list); + +void freeElement(void* element){ + int i; + Element* e = (Element*)element; + if (!e) return; + // free attributes + for (i=0; in; i+=2) + free(e->attributes[i+1]); + if (e->attributes) free(e->attributes); + // free child nodes + switch (getAstNodeType(e->type)) { + case astListElement: + freeList(((ListElement*)e)->list); + break; + case astScalarVariable: + freeList(((ScalarVariable*)e)->directDependencies); + case astType: + freeElement(((Type*)e)->typeSpec); + break; + case astCoSimulation: { + CoSimulation* cs = (CoSimulation*)e; + freeElement(cs->capabilities); + freeElement(cs->model); + break; + } + case astModelDescription: { + ModelDescription* md = (ModelDescription*)e; + freeList(md->unitDefinitions); + freeList(md->typeDefinitions); + freeElement(md->defaultExperiment); + freeList(md->vendorAnnotations); + freeList(md->modelVariables); + freeElement(md->cosimulation); + break; + } + } + // free the struct + free(e); +} + +static void freeList(void** list){ + int i; + if (!list) return; + for (i=0; list[i]; i++) + freeElement(list[i]); + free(list); +} + +// ------------------------------------------------------------------------- +// Validation - done after parsing to report all errors + +ModelDescription* validate(ModelDescription* md) { + int error = 0; + int i; + if (md->modelVariables) + for (i=0; md->modelVariables[i]; i++){ + ScalarVariable* sv = (ScalarVariable*)md->modelVariables[i]; + char* declaredType = getString(sv->typeSpec, att_declaredType); + Type* decltype = getDeclaredType(md, declaredType); + if (declaredType && decltype==NULL) { + printf("Warning: Declared type %s of variable %s not found in modelDescription.xml\n", declaredType, getName(sv)); + error++; + } + } + if (error) { + printf("Error: Found %d error in modelDescription.xml\n", error); + return NULL; + } + return md; +} + +// ------------------------------------------------------------------------- +// Entry function parse() of the XML parser + +static void cleanup(FILE *file) { + stackFree(stack); + stack = NULL; + XML_ParserFree(parser); + parser = NULL; + fclose(file); +} + +// Returns NULL to indicate failure +// Otherwise, return the root node md of the AST. +// The receiver must call freeElement(md) to release AST memory. +ModelDescription* parse(const char* xmlPath) { + ModelDescription* md = NULL; + FILE *file; + int done = 0; + stack = stackNew(100, 10); + if (!checkPointer(stack)) return NULL; // failure + parser = XML_ParserCreate(NULL); + if (!checkPointer(parser)) return NULL; // failure + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, handleData); + file = fopen(xmlPath, "rb"); + if (file == NULL) { + printf("Cannot open file '%s'\n", xmlPath); + XML_ParserFree(parser); + return NULL; // failure + } + while (!done) { + int n = fread(text, sizeof(char), XMLBUFSIZE, file); + if (n != XMLBUFSIZE) done = 1; + if (!XML_Parse(parser, text, n, done)){ + printf("Parse error in file %s at line %d:\n%s\n", + xmlPath, + XML_GetCurrentLineNumber(parser), + XML_ErrorString(XML_GetErrorCode(parser))); + while (! stackIsEmpty(stack)) md = stackPop(stack); + if (md) freeElement(md); + cleanup(file); + return NULL; // failure + } + } + md = stackPop(stack); + assert(stackIsEmpty(stack)); + cleanup(file); + //printElement(1, md); // debug + return validate(md); // success if all refs are valid +} + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSolution.sln b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSolution.sln new file mode 100644 index 00000000..f3f21f80 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/FMUSolution.sln @@ -0,0 +1,46 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FMUSimulator", "FMUSimulator\FMUSimulator.vcxproj", "{9838038D-09A3-43A5-AB97-B5B5C763DF43}" + ProjectSection(ProjectDependencies) = postProject + {C52F9E7B-498A-42BE-8DB4-85A15694382A} = {C52F9E7B-498A-42BE-8DB4-85A15694382A} + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "zlib-1.2.6\contrib\vstudio\vc10\miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlib-1.2.6\contrib\vstudio\vc10\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9838038D-09A3-43A5-AB97-B5B5C763DF43}.Debug|Win32.ActiveCfg = Debug|Win32 + {9838038D-09A3-43A5-AB97-B5B5C763DF43}.Debug|Win32.Build.0 = Debug|Win32 + {9838038D-09A3-43A5-AB97-B5B5C763DF43}.Release|Win32.ActiveCfg = Release|Win32 + {9838038D-09A3-43A5-AB97-B5B5C763DF43}.Release|Win32.Build.0 = Release|Win32 + {9838038D-09A3-43A5-AB97-B5B5C763DF43}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {9838038D-09A3-43A5-AB97-B5B5C763DF43}.ReleaseWithoutAsm|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/CMakeLists.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/CMakeLists.txt new file mode 100644 index 00000000..0a56ff6f --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/CMakeLists.txt @@ -0,0 +1,199 @@ +cmake_minimum_required(VERSION 2.4.4) +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) + +project(zlib C) + +if(NOT DEFINED BUILD_SHARED_LIBS) + option(BUILD_SHARED_LIBS "Build a shared library form of zlib" ON) +endif() + +include(CheckTypeSize) +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckCSourceCompiles) +enable_testing() + +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(stddef.h HAVE_STDDEF_H) + +# +# Check to see if we have large file support +# +set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) +# We add these other definitions here because CheckTypeSize.cmake +# in CMake 2.4.x does not automatically do so and we want +# compatibility with CMake 2.4.x. +if(HAVE_SYS_TYPES_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) +endif() +if(HAVE_STDINT_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) +endif() +if(HAVE_STDDEF_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) +endif() +check_type_size(off64_t OFF64_T) +if(HAVE_OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) # clear variable + +# +# Check for fseeko +# +check_function_exists(fseeko HAVE_FSEEKO) +if(NOT HAVE_FSEEKO) + add_definitions(-DNO_FSEEKO) +endif() + +# +# Check for unistd.h +# +check_include_file(unistd.h Z_HAVE_UNISTD_H) + +if(MSVC) + set(CMAKE_DEBUG_POSTFIX "d") + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) +endif() + +if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) + # If we're doing an out of source build and the user has a zconf.h + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) + message(FATAL_ERROR + "You must remove ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h " + "from the source tree. This file is included with zlib " + "but CMake generates this file for you automatically " + "in the build directory.") + endif() +endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + + +#============================================================================ +# zlib +#============================================================================ + +set(ZLIB_PUBLIC_HDRS + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h + zlib.h +) +set(ZLIB_PRIVATE_HDRS + crc32.h + deflate.h + gzguts.h + inffast.h + inffixed.h + inflate.h + inftrees.h + trees.h + zutil.h +) +set(ZLIB_SRCS + adler32.c + compress.c + crc32.c + deflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c + inflate.c + infback.c + inftrees.c + inffast.c + trees.c + uncompr.c + zutil.c +) + +if(NOT MINGW) + set(ZLIB_SRCS ${ZLIB_SRCS} + win32/zlib1.rc # If present will override custom build rule below. + ) +endif() + +# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) +string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([0-9A-Za-z.]+)\".*" + "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) + +if(MINGW) + # This gets us DLL resource information when compiling on MinGW. + if(NOT CMAKE_RC_COMPILER) + SET(CMAKE_RC_COMPILER windres.exe) + endif() + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj + COMMAND ${CMAKE_RC_COMPILER} + -D GCC_WINDRES + -I ${CMAKE_CURRENT_SOURCE_DIR} + -I ${CMAKE_CURRENT_BINARY_DIR} + -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj + -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) + set(ZLIB_SRCS ${ZLIB_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) +endif(MINGW) + +add_library(zlib ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) + +set_target_properties(zlib PROPERTIES SOVERSION 1) + +if(NOT CYGWIN) + # This property causes shared libraries on Linux to have the full version + # encoded into their final filename. We disable this on Cygwin because + # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll + # seems to be the default. + # + # This has no effect with MSVC, on that platform the version info for + # the DLL comes from the resource file win32/zlib1.rc + set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) +endif() + +if(UNIX) + # On unix-like platforms the library is almost always called libz + set_target_properties(zlib PROPERTIES OUTPUT_NAME z) +elseif(BUILD_SHARED_LIBS AND WIN32) + # Creates zlib1.dll when building shared library version + set_target_properties(zlib PROPERTIES SUFFIX "1.dll") +endif() + +if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) + install(TARGETS zlib + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib ) +endif() +if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) + install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION include) +endif() +if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) + install(FILES zlib.3 DESTINATION share/man/man3) +endif() + +#============================================================================ +# Example binaries +#============================================================================ + +add_executable(example test/example.c) +target_link_libraries(example zlib) +add_test(example example) + +add_executable(minigzip test/minigzip.c) +target_link_libraries(minigzip zlib) + +if(HAVE_OFF64_T) + add_executable(example64 test/example.c) + target_link_libraries(example64 zlib) + set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") + add_test(example64 example64) + + add_executable(minigzip64 test/minigzip.c) + target_link_libraries(minigzip64 zlib) + set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") +endif() diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/ChangeLog b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/ChangeLog new file mode 100644 index 00000000..6fa5d441 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/ChangeLog @@ -0,0 +1,1347 @@ + + ChangeLog file for zlib + +Changes in 1.2.6 (29 Jan 2012) +- Update the Pascal interface in contrib/pascal +- Fix function numbers for gzgetc_ in zlibvc.def files +- Fix configure.ac for contrib/minizip [Schiffer] +- Fix large-entry detection in minizip on 64-bit systems [Schiffer] +- Have ./configure use the compiler return code for error indication +- Fix CMakeLists.txt for cross compilation [McClure] +- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] +- Fix compilation of contrib/minizip on FreeBSD [Marquez] +- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] +- Include io.h for Turbo C / Borland C on all platforms [Truta] +- Make version explicit in contrib/minizip/configure.ac [Bosmans] +- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] +- Minor cleanup up contrib/minizip/unzip.c [Vollant] +- Fix bug when compiling minizip with C++ [Vollant] +- Protect for long name and extra fields in contrib/minizip [Vollant] +- Avoid some warnings in contrib/minizip [Vollant] +- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip +- Add missing libs to minizip linker command +- Add support for VPATH builds in contrib/minizip +- Add an --enable-demos option to contrib/minizip/configure +- Add the generation of configure.log by ./configure +- Exit when required parameters not provided to win32/Makefile.gcc +- Have gzputc return the character written instead of the argument +- Use the -m option on ldconfig for BSD systems [Tobias] +- Correct in zlib.map when deflateResetKeep was added + +Changes in 1.2.5.3 (15 Jan 2012) +- Restore gzgetc function for binary compatibility +- Do not use _lseeki64 under Borland C++ [Truta] +- Update win32/Makefile.msc to build test/*.c [Truta] +- Remove old/visualc6 given CMakefile and other alternatives +- Update AS400 build files and documentation [Monnerat] +- Update win32/Makefile.gcc to build test/*.c [Truta] +- Permit stronger flushes after Z_BLOCK flushes +- Avoid extraneous empty blocks when doing empty flushes +- Permit Z_NULL arguments to deflatePending +- Allow deflatePrime() to insert bits in the middle of a stream +- Remove second empty static block for Z_PARTIAL_FLUSH +- Write out all of the available bits when using Z_BLOCK +- Insert the first two strings in the hash table after a flush + +Changes in 1.2.5.2 (17 Dec 2011) +- fix ld error: unable to find version dependency 'ZLIB_1.2.5' +- use relative symlinks for shared libs +- Avoid searching past window for Z_RLE strategy +- Assure that high-water mark initialization is always applied in deflate +- Add assertions to fill_window() in deflate.c to match comments +- Update python link in README +- Correct spelling error in gzread.c +- Fix bug in gzgets() for a concatenated empty gzip stream +- Correct error in comment for gz_make() +- Change gzread() and related to ignore junk after gzip streams +- Allow gzread() and related to continue after gzclearerr() +- Allow gzrewind() and gzseek() after a premature end-of-file +- Simplify gzseek() now that raw after gzip is ignored +- Change gzgetc() to a macro for speed (~40% speedup in testing) +- Fix gzclose() to return the actual error last encountered +- Always add large file support for windows +- Include zconf.h for windows large file support +- Include zconf.h.cmakein for windows large file support +- Update zconf.h.cmakein on make distclean +- Merge vestigial vsnprintf determination from zutil.h to gzguts.h +- Clarify how gzopen() appends in zlib.h comments +- Correct documentation of gzdirect() since junk at end now ignored +- Add a transparent write mode to gzopen() when 'T' is in the mode +- Update python link in zlib man page +- Get inffixed.h and MAKEFIXED result to match +- Add a ./config --solo option to make zlib subset with no libary use +- Add undocumented inflateResetKeep() function for CAB file decoding +- Add --cover option to ./configure for gcc coverage testing +- Add #define ZLIB_CONST option to use const in the z_stream interface +- Add comment to gzdopen() in zlib.h to use dup() when using fileno() +- Note behavior of uncompress() to provide as much data as it can +- Add files in contrib/minizip to aid in building libminizip +- Split off AR options in Makefile.in and configure +- Change ON macro to Z_ARG to avoid application conflicts +- Facilitate compilation with Borland C++ for pragmas and vsnprintf +- Include io.h for Turbo C / Borland C++ +- Move example.c and minigzip.c to test/ +- Simplify incomplete code table filling in inflate_table() +- Remove code from inflate.c and infback.c that is impossible to execute +- Test the inflate code with full coverage +- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) +- Add deflateResetKeep and fix inflateResetKeep to retain dictionary +- Fix gzwrite.c to accommodate reduced memory zlib compilation +- Have inflate() with Z_FINISH avoid the allocation of a window +- Do not set strm->adler when doing raw inflate +- Fix gzeof() to behave just like feof() when read is not past end of file +- Fix bug in gzread.c when end-of-file is reached +- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF +- Document gzread() capability to read concurrently written files +- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] + +Changes in 1.2.5.1 (10 Sep 2011) +- Update FAQ entry on shared builds (#13) +- Avoid symbolic argument to chmod in Makefile.in +- Fix bug and add consts in contrib/puff [Oberhumer] +- Update contrib/puff/zeros.raw test file to have all block types +- Add full coverage test for puff in contrib/puff/Makefile +- Fix static-only-build install in Makefile.in +- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] +- Add libz.a dependency to shared in Makefile.in for parallel builds +- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out +- Replace $(...) with `...` in configure for non-bash sh [Bowler] +- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] +- Add solaris* to Linux* in configure to allow gcc use [Groffen] +- Add *bsd* to Linux* case in configure [Bar-Lev] +- Add inffast.obj to dependencies in win32/Makefile.msc +- Correct spelling error in deflate.h [Kohler] +- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc +- Add test to configure for GNU C looking for gcc in output of $cc -v +- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] +- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not +- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense +- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) +- Make stronger test in zconf.h to include unistd.h for LFS +- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] +- Fix zlib.h LFS support when Z_PREFIX used +- Add updated as400 support (removed from old) [Monnerat] +- Avoid deflate sensitivity to volatile input data +- Avoid division in adler32_combine for NO_DIVIDE +- Clarify the use of Z_FINISH with deflateBound() amount of space +- Set binary for output file in puff.c +- Use u4 type for crc_table to avoid conversion warnings +- Apply casts in zlib.h to avoid conversion warnings +- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] +- Improve inflateSync() documentation to note indeterminancy +- Add deflatePending() function to return the amount of pending output +- Correct the spelling of "specification" in FAQ [Randers-Pehrson] +- Add a check in configure for stdarg.h, use for gzprintf() +- Check that pointers fit in ints when gzprint() compiled old style +- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] +- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] +- Add debug records in assmebler code [Londer] +- Update RFC references to use http://tools.ietf.org/html/... [Li] +- Add --archs option, use of libtool to configure for Mac OS X [Borstel] + +Changes in 1.2.5 (19 Apr 2010) +- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] +- Default to libdir as sharedlibdir in configure [Nieder] +- Update copyright dates on modified source files +- Update trees.c to be able to generate modified trees.h +- Exit configure for MinGW, suggesting win32/Makefile.gcc +- Check for NULL path in gz_open [Homurlu] + +Changes in 1.2.4.5 (18 Apr 2010) +- Set sharedlibdir in configure [Torok] +- Set LDFLAGS in Makefile.in [Bar-Lev] +- Avoid mkdir objs race condition in Makefile.in [Bowler] +- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays +- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C +- Don't use hidden attribute when it is a warning generator (e.g. Solaris) + +Changes in 1.2.4.4 (18 Apr 2010) +- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] +- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty +- Try to use bash or ksh regardless of functionality of /bin/sh +- Fix configure incompatibility with NetBSD sh +- Remove attempt to run under bash or ksh since have better NetBSD fix +- Fix win32/Makefile.gcc for MinGW [Bar-Lev] +- Add diagnostic messages when using CROSS_PREFIX in configure +- Added --sharedlibdir option to configure [Weigelt] +- Use hidden visibility attribute when available [Frysinger] + +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + +Changes in 1.2.4.1 (28 Mar 2010) +- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] +- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] +- Restore "for debugging" comment on sprintf() in gzlib.c +- Remove fdopen for MVS from gzguts.h +- Put new README-WIN32.txt in win32 [Rowe] +- Add check for shell to configure and invoke another shell if needed +- Fix big fat stinking bug in gzseek() on uncompressed files +- Remove vestigial F_OPEN64 define in zutil.h +- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE +- Avoid errors on non-LFS systems when applications define LFS macros +- Set EXE to ".exe" in configure for MINGW [Kahle] +- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] +- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] +- Add DLL install in win32/makefile.gcc [Bar-Lev] +- Allow Linux* or linux* from uname in configure [Bar-Lev] +- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] +- Add cross-compilation prefixes to configure [Bar-Lev] +- Match type exactly in gz_load() invocation in gzread.c +- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func +- Provide prototypes for *64 functions when building zlib without LFS +- Don't use -lc when linking shared library on MinGW +- Remove errno.h check in configure and vestigial errno code in zutil.h + +Changes in 1.2.4 (14 Mar 2010) +- Fix VER3 extraction in configure for no fourth subversion +- Update zlib.3, add docs to Makefile.in to make .pdf out of it +- Add zlib.3.pdf to distribution +- Don't set error code in gzerror() if passed pointer is NULL +- Apply destination directory fixes to CMakeLists.txt [Lowman] +- Move #cmakedefine's to a new zconf.in.cmakein +- Restore zconf.h for builds that don't use configure or cmake +- Add distclean to dummy Makefile for convenience +- Update and improve INDEX, README, and FAQ +- Update CMakeLists.txt for the return of zconf.h [Lowman] +- Update contrib/vstudio/vc9 and vc10 [Vollant] +- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc +- Apply license and readme changes to contrib/asm686 [Raiter] +- Check file name lengths and add -c option in minigzip.c [Li] +- Update contrib/amd64 and contrib/masmx86/ [Vollant] +- Avoid use of "eof" parameter in trees.c to not shadow library variable +- Update make_vms.com for removal of zlibdefs.h [Zinser] +- Update assembler code and vstudio projects in contrib [Vollant] +- Remove outdated assembler code contrib/masm686 and contrib/asm586 +- Remove old vc7 and vc8 from contrib/vstudio +- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] +- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() +- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] +- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) +- Fix bug in void-returning vsprintf() case in gzwrite.c +- Fix name change from inflate.h in contrib/inflate86/inffas86.c +- Check if temporary file exists before removing in make_vms.com [Zinser] +- Fix make install and uninstall for --static option +- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] +- Update readme.txt in contrib/masmx64 and masmx86 to assemble + +Changes in 1.2.3.9 (21 Feb 2010) +- Expunge gzio.c +- Move as400 build information to old +- Fix updates in contrib/minizip and contrib/vstudio +- Add const to vsnprintf test in configure to avoid warnings [Weigelt] +- Delete zconf.h (made by configure) [Weigelt] +- Change zconf.in.h to zconf.h.in per convention [Weigelt] +- Check for NULL buf in gzgets() +- Return empty string for gzgets() with len == 1 (like fgets()) +- Fix description of gzgets() in zlib.h for end-of-file, NULL return +- Update minizip to 1.1 [Vollant] +- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c +- Note in zlib.h that gzerror() should be used to distinguish from EOF +- Remove use of snprintf() from gzlib.c +- Fix bug in gzseek() +- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] +- Fix zconf.h generation in CMakeLists.txt [Lowman] +- Improve comments in zconf.h where modified by configure + +Changes in 1.2.3.8 (13 Feb 2010) +- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] +- Use z_off64_t in gz_zero() and gz_skip() to match state->skip +- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) +- Revert to Makefile.in from 1.2.3.6 (live with the clutter) +- Fix missing error return in gzflush(), add zlib.h note +- Add *64 functions to zlib.map [Levin] +- Fix signed/unsigned comparison in gz_comp() +- Use SFLAGS when testing shared linking in configure +- Add --64 option to ./configure to use -m64 with gcc +- Fix ./configure --help to correctly name options +- Have make fail if a test fails [Levin] +- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] +- Remove assembler object files from contrib + +Changes in 1.2.3.7 (24 Jan 2010) +- Always gzopen() with O_LARGEFILE if available +- Fix gzdirect() to work immediately after gzopen() or gzdopen() +- Make gzdirect() more precise when the state changes while reading +- Improve zlib.h documentation in many places +- Catch memory allocation failure in gz_open() +- Complete close operation if seek forward in gzclose_w() fails +- Return Z_ERRNO from gzclose_r() if close() fails +- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL +- Return zero for gzwrite() errors to match zlib.h description +- Return -1 on gzputs() error to match zlib.h description +- Add zconf.in.h to allow recovery from configure modification [Weigelt] +- Fix static library permissions in Makefile.in [Weigelt] +- Avoid warnings in configure tests that hide functionality [Weigelt] +- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] +- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] +- Avoid access of uninitialized data for first inflateReset2 call [Gomes] +- Keep object files in subdirectories to reduce the clutter somewhat +- Remove default Makefile and zlibdefs.h, add dummy Makefile +- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ +- Remove zlibdefs.h completely -- modify zconf.h instead + +Changes in 1.2.3.6 (17 Jan 2010) +- Avoid void * arithmetic in gzread.c and gzwrite.c +- Make compilers happier with const char * for gz_error message +- Avoid unused parameter warning in inflate.c +- Avoid signed-unsigned comparison warning in inflate.c +- Indent #pragma's for traditional C +- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() +- Correct email address in configure for system options +- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] +- Update zlib.map [Brown] +- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] +- Apply various fixes to CMakeLists.txt [Lowman] +- Add checks on len in gzread() and gzwrite() +- Add error message for no more room for gzungetc() +- Remove zlib version check in gzwrite() +- Defer compression of gzprintf() result until need to +- Use snprintf() in gzdopen() if available +- Remove USE_MMAP configuration determination (only used by minigzip) +- Remove examples/pigz.c (available separately) +- Update examples/gun.c to 1.6 + +Changes in 1.2.3.5 (8 Jan 2010) +- Add space after #if in zutil.h for some compilers +- Fix relatively harmless bug in deflate_fast() [Exarevsky] +- Fix same problem in deflate_slow() +- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] +- Add deflate_rle() for faster Z_RLE strategy run-length encoding +- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding +- Change name of "write" variable in inffast.c to avoid library collisions +- Fix premature EOF from gzread() in gzio.c [Brown] +- Use zlib header window size if windowBits is 0 in inflateInit2() +- Remove compressBound() call in deflate.c to avoid linking compress.o +- Replace use of errno in gz* with functions, support WinCE [Alves] +- Provide alternative to perror() in minigzip.c for WinCE [Alves] +- Don't use _vsnprintf on later versions of MSVC [Lowman] +- Add CMake build script and input file [Lowman] +- Update contrib/minizip to 1.1 [Svensson, Vollant] +- Moved nintendods directory from contrib to . +- Replace gzio.c with a new set of routines with the same functionality +- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above +- Update contrib/minizip to 1.1b +- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h + +Changes in 1.2.3.4 (21 Dec 2009) +- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility +- Update comments in configure and Makefile.in for default --shared +- Fix test -z's in configure [Marquess] +- Build examplesh and minigzipsh when not testing +- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h +- Import LDFLAGS from the environment in configure +- Fix configure to populate SFLAGS with discovered CFLAGS options +- Adapt make_vms.com to the new Makefile.in [Zinser] +- Add zlib2ansi script for C++ compilation [Marquess] +- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) +- Add AMD64 assembler code for longest match to contrib [Teterin] +- Include options from $SFLAGS when doing $LDSHARED +- Simplify 64-bit file support by introducing z_off64_t type +- Make shared object files in objs directory to work around old Sun cc +- Use only three-part version number for Darwin shared compiles +- Add rc option to ar in Makefile.in for when ./configure not run +- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* +- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile +- Protect against _FILE_OFFSET_BITS being defined when compiling zlib +- Rename Makefile.in targets allstatic to static and allshared to shared +- Fix static and shared Makefile.in targets to be independent +- Correct error return bug in gz_open() by setting state [Brown] +- Put spaces before ;;'s in configure for better sh compatibility +- Add pigz.c (parallel implementation of gzip) to examples/ +- Correct constant in crc32.c to UL [Leventhal] +- Reject negative lengths in crc32_combine() +- Add inflateReset2() function to work like inflateEnd()/inflateInit2() +- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] +- Correct typo in doc/algorithm.txt [Janik] +- Fix bug in adler32_combine() [Zhu] +- Catch missing-end-of-block-code error in all inflates and in puff + Assures that random input to inflate eventually results in an error +- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ +- Update ENOUGH and its usage to reflect discovered bounds +- Fix gzerror() error report on empty input file [Brown] +- Add ush casts in trees.c to avoid pedantic runtime errors +- Fix typo in zlib.h uncompress() description [Reiss] +- Correct inflate() comments with regard to automatic header detection +- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) +- Put new version of gzlog (2.0) in examples with interruption recovery +- Add puff compile option to permit invalid distance-too-far streams +- Add puff TEST command options, ability to read piped input +- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but + _LARGEFILE64_SOURCE not defined +- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart +- Fix deflateSetDictionary() to use all 32K for output consistency +- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) +- Clear bytes after deflate lookahead to avoid use of uninitialized data +- Change a limit in inftrees.c to be more transparent to Coverity Prevent +- Update win32/zlib.def with exported symbols from zlib.h +- Correct spelling errors in zlib.h [Willem, Sobrado] +- Allow Z_BLOCK for deflate() to force a new block +- Allow negative bits in inflatePrime() to delete existing bit buffer +- Add Z_TREES flush option to inflate() to return at end of trees +- Add inflateMark() to return current state information for random access +- Add Makefile for NintendoDS to contrib [Costa] +- Add -w in configure compile tests to avoid spurious warnings [Beucler] +- Fix typos in zlib.h comments for deflateSetDictionary() +- Fix EOF detection in transparent gzread() [Maier] + +Changes in 1.2.3.3 (2 October 2006) +- Make --shared the default for configure, add a --static option +- Add compile option to permit invalid distance-too-far streams +- Add inflateUndermine() function which is required to enable above +- Remove use of "this" variable name for C++ compatibility [Marquess] +- Add testing of shared library in make test, if shared library built +- Use ftello() and fseeko() if available instead of ftell() and fseek() +- Provide two versions of all functions that use the z_off_t type for + binary compatibility -- a normal version and a 64-bit offset version, + per the Large File Support Extension when _LARGEFILE64_SOURCE is + defined; use the 64-bit versions by default when _FILE_OFFSET_BITS + is defined to be 64 +- Add a --uname= option to configure to perhaps help with cross-compiling + +Changes in 1.2.3.2 (3 September 2006) +- Turn off silly Borland warnings [Hay] +- Use off64_t and define _LARGEFILE64_SOURCE when present +- Fix missing dependency on inffixed.h in Makefile.in +- Rig configure --shared to build both shared and static [Teredesai, Truta] +- Remove zconf.in.h and instead create a new zlibdefs.h file +- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] +- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] + +Changes in 1.2.3.1 (16 August 2006) +- Add watcom directory with OpenWatcom make files [Daniel] +- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] +- Update make_vms.com [Zinser] +- Use -fPIC for shared build in configure [Teredesai, Nicholson] +- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [BŠck] +- Add some FAQ entries about the contrib directory +- Update the MVS question in the FAQ +- Avoid extraneous reads after EOF in gzio.c [Brown] +- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] +- Add comments to zlib.h about gzerror() usage [Brown] +- Set extra flags in gzip header in gzopen() like deflate() does +- Make configure options more compatible with double-dash conventions + [Weigelt] +- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] +- Fix uninstall target in Makefile.in [Truta] +- Add pkgconfig support [Weigelt] +- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] +- Replace set_data_type() with a more accurate detect_data_type() in + trees.c, according to the txtvsbin.txt document [Truta] +- Swap the order of #include and #include "zlib.h" in + gzio.c, example.c and minigzip.c [Truta] +- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, + Truta] (where?) +- Fix target "clean" from win32/Makefile.bor [Truta] +- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] +- Update zlib www home address in win32/DLL_FAQ.txt [Truta] +- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] +- Enable browse info in the "Debug" and "ASM Debug" configurations in + the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] +- Add pkgconfig support [Weigelt] +- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, + for use in win32/zlib1.rc [Polushin, Rowe, Truta] +- Add a document that explains the new text detection scheme to + doc/txtvsbin.txt [Truta] +- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] +- Move algorithm.txt into doc/ [Truta] +- Synchronize FAQ with website +- Fix compressBound(), was low for some pathological cases [Fearnley] +- Take into account wrapper variations in deflateBound() +- Set examples/zpipe.c input and output to binary mode for Windows +- Update examples/zlib_how.html with new zpipe.c (also web site) +- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems + that gcc became pickier in 4.0) +- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain + un-versioned, the patch adds versioning only for symbols introduced in + zlib-1.2.0 or later. It also declares as local those symbols which are + not designed to be exported." [Levin] +- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure +- Do not initialize global static by default in trees.c, add a response + NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] +- Don't use strerror() in gzio.c under WinCE [Yakimov] +- Don't use errno.h in zutil.h under WinCE [Yakimov] +- Move arguments for AR to its usage to allow replacing ar [Marot] +- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] +- Improve inflateInit() and inflateInit2() documentation +- Fix structure size comment in inflate.h +- Change configure help option from --h* to --help [Santos] + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Add zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/FAQ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/FAQ new file mode 100644 index 00000000..99b7cf92 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/FAQ @@ -0,0 +1,368 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://zlib.net/ which may have more recent information. +The lastest zlib FAQ is at http://zlib.net/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. See the + file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the + precompiled DLL are found in the zlib web site at http://zlib.net/ . + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://marknelson.us/1997/01/01/zlib-engine/ + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress(), the length of the compressed + buffer is equal to the available size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not zero. + When setting the parameter flush equal to Z_FINISH, also make sure that + avail_out is big enough to allow processing all pending input. Note that a + Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be + made with more input or output space. A Z_BUF_ERROR may in fact be + unavoidable depending on how the functions are used, since it is not + possible to tell whether or not there is more output pending when + strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a + heavily annotated example. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h . Examples of zlib usage are in the files test/example.c + and test/minigzip.c, with more in examples/ . + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple package. + zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of zlib. + Please try to reproduce the problem with a small program and send the + corresponding source to us at zlib@gzip.org . Do not send multi-megabyte + data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + By default a shared (and a static) library is built for Unix. So: + + make distclean + ./configure + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to + it. You can check the version at the top of zlib.h or with the + ZLIB_VERSION symbol defined in zlib.h . + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See http://www.pdflib.com/ . To modify PDF forms, see + http://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip formats + use the same compressed data format internally, but have different headers + and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about a + single file, such as the name and last modification date. The zlib format + on the other hand was designed for in-memory and communication channel + applications, and has a much more compact header and trailer and uses a + faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode the + gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's *Init* functions + allow for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + Yes. It has been tested on 64-bit machines, and has no dependence on any + data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format than + does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically use + Z_FULL_FLUSH, carefully write all the pending data at those points, and + keep an index of those locations, then you can start decompression at those + points. You have to be careful to not use Z_FULL_FLUSH too often, since it + can significantly degrade compression. Alternatively, you can scan a + deflate stream once to generate an index, and then use that index for + random access. See examples/zran.c . + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + It has in the past, but we have not heard of any recent evidence. There + were working ports of zlib 1.1.4 to MVS, but those links no longer work. + If you know of recent, successful applications of zlib on these operating + systems, please let us know. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at to + understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + http://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit only + if the compiler's "long" type is 32 bits. If the compiler's "long" type is + 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib is + compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of an 8K string space (or other value as set by + gzbuffer()), other than the caller of gzprintf() assuring that the output + will not exceed 8K. On the other hand, if zlib is compiled to use + snprintf() or vsnprintf(), which should normally be the case, then there is + no vulnerability. The ./configure script will display warnings if an + insecure variation of sprintf() will be used by gzprintf(). Also the + zlibCompileFlags() function will return information on what variant of + sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + http://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability, and versions + 1.2.1 and 1.2.2 were subject to an access exception when decompressing + invalid compressed data. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: http://zlib.net/ . + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly as well as contradicted each other. So now, we simply + make sure that the code always works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of deflate + is not affected. This only started showing up recently since zlib 1.2.x + uses malloc() by default for allocations, whereas earlier versions used + calloc(), which zeros out the allocated memory. Even though the code was + correct, versions 1.2.4 and later was changed to not stimulate these + checkers. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very + weak and can be broken with freely available programs. To get strong + encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib + compression. For PKZIP compatible "encryption", look at + http://www.info-zip.org/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion with + the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specification in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. In + any case, the compression improvements are so modest compared to other more + modern approaches, that it's not worth the effort to implement. + +41. I'm having a problem with the zip functions in zlib, can you help? + + There are no zip functions in zlib. You are probably using minizip by + Giles Vollant, which is found in the contrib directory of zlib. It is not + part of zlib. In fact none of the stuff in contrib is part of zlib. The + files in there are not supported by the zlib authors. You need to contact + the authors of the respective contribution for help. + +42. The match.asm code in contrib is under the GNU General Public License. + Since it's part of zlib, doesn't that mean that all of zlib falls under the + GNU GPL? + + No. The files in contrib are not part of zlib. They were contributed by + other authors and are provided as a convenience to the user within the zlib + distribution. Each item in contrib has its own license. + +43. Is zlib subject to export controls? What is its ECCN? + + zlib is not subject to export controls, and so is classified as EAR99. + +44. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/INDEX b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/INDEX new file mode 100644 index 00000000..246f5f47 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/INDEX @@ -0,0 +1,67 @@ +CMakeLists.txt cmake build file +ChangeLog history of changes +FAQ Frequently Asked Questions about zlib +INDEX this file +Makefile dummy Makefile that tells you to ./configure +Makefile.in template for Unix Makefile +README guess what +configure configure script for Unix +make_vms.com makefile for VMS +test/example.c zlib usages examples for build testing +test/minigzip.c minimal gzip-like functionality for build testing +test/infcover.c inf*.c code coverage for build coverage testing +treebuild.xml XML description of source file dependencies +zconf.h.cmakein zconf.h template for cmake +zconf.h.in zconf.h template for configure +zlib.3 Man page for zlib +zlib.3.pdf Man page in PDF format +zlib.map Linux symbol information +zlib.pc.in Template for pkg-config descriptor +zlib2ansi perl script to convert source files for C++ compilation + +amiga/ makefiles for Amiga SAS C +as400/ makefiles for AS/400 +doc/ documentation for formats and algorithms +msdos/ makefiles for MSDOS +nintendods/ makefile for Nintendo DS +old/ makefiles for various architectures and zlib documentation + files that have not yet been updated for zlib 1.2.x +qnx/ makefiles for QNX +watcom/ makefiles for OpenWatcom +win32/ makefiles for Windows + + zlib public header files (required for library use): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +crc32.h +deflate.c +deflate.h +gzclose.c +gzguts.h +gzlib.c +gzread.c +gzwrite.c +infback.c +inffast.c +inffast.h +inffixed.h +inflate.c +inflate.h +inftrees.c +inftrees.h +trees.c +trees.h +uncompr.c +zutil.c +zutil.h + + source files for sample programs +See examples/README.examples + + unsupported contributions by third parties +See contrib/README.contrib diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/Makefile b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/Makefile new file mode 100644 index 00000000..6bba86c7 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/Makefile @@ -0,0 +1,5 @@ +all: + -@echo "Please use ./configure first. Thank you." + +distclean: + make -f Makefile.in distclean diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/Makefile.in b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/Makefile.in new file mode 100644 index 00000000..ea430bf2 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/Makefile.in @@ -0,0 +1,285 @@ +# Makefile for zlib +# Copyright (C) 1995-2011 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static + +# To use the asm code, type: +# cp contrib/asm?86/match.S ./match.S +# make LOC=-DASMV OBJA=match.o + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +SFLAGS=-O +LDFLAGS= +TEST_LDFLAGS=-L. libz.a +LDSHARED=$(CC) +CPP=$(CC) -E + +STATICLIB=libz.a +SHAREDLIB=libz.so +SHAREDLIBV=libz.so.1.2.6 +SHAREDLIBM=libz.so.1 +LIBS=$(STATICLIB) $(SHAREDLIBV) + +AR=ar +ARFLAGS=rc +RANLIB=ranlib +LDCONFIG=ldconfig +LDSHAREDLIBC=-lc +TAR=tar +SHELL=/bin/sh +EXE= + +prefix = /usr/local +exec_prefix = ${prefix} +libdir = ${exec_prefix}/lib +sharedlibdir = ${libdir} +includedir = ${prefix}/include +mandir = ${prefix}/share/man +man3dir = ${mandir}/man3 +pkgconfigdir = ${libdir}/pkgconfig +tempfile := $(shell mktemp -u __XXXXXX) + +OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o +OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o +OBJC = $(OBJZ) $(OBJG) + +PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo +PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo +PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) + +# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo +OBJA = +PIC_OBJA = + +OBJS = $(OBJC) $(OBJA) + +PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA) + +all: static shared + +static: example$(EXE) minigzip$(EXE) + +shared: examplesh$(EXE) minigzipsh$(EXE) + +all64: example64$(EXE) minigzip64$(EXE) + +check: test + +test: all teststatic testshared + +teststatic: static + @if echo hello world | ./minigzip | ./minigzip -d && ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; false; \ + fi + -@rm -f foo.gz + +testshared: shared + @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ + DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ + SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ + if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh; then \ + echo ' *** zlib shared test OK ***'; \ + else \ + echo ' *** zlib shared test FAILED ***'; false; \ + fi + -@rm -f foo.gz + +test64: all64 + @if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64; then \ + echo ' *** zlib 64-bit test OK ***'; \ + else \ + echo ' *** zlib 64-bit test FAILED ***'; false; \ + fi + -@rm -f foo.gz + +infcover.o: test/infcover.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/infcover.c + +infcover: infcover.o libz.a + $(CC) $(CFLAGS) -o $@ infcover.o libz.a + +cover: infcover + rm -f *.gcda + ./infcover + gcov inf*.c + +libz.a: $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +match.o: match.S + $(CPP) match.S > _match.s + $(CC) -c _match.s + mv _match.o match.o + rm -f _match.s + +match.lo: match.S + $(CPP) match.S > _match.s + $(CC) -c -fPIC _match.s + mv _match.o match.lo + rm -f _match.s + +example.o: test/example.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/example.c + +minigzip.o: test/minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c + +example64.o: test/example.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/example.c + +minigzip64.o: test/minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/minigzip.c + +.SUFFIXES: .lo + +.c.lo: + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $< + -@mv objs/$*.o $@ + +placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a + $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) + rm -f $(SHAREDLIB) $(SHAREDLIBM) + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIBM) + -@rmdir objs + +example$(EXE): example.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) + +minigzip$(EXE): minigzip.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) + +examplesh$(EXE): example.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV) + +minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV) + +example64$(EXE): example64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) + +minigzip64$(EXE): minigzip64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS) + +install-libs: $(LIBS) + -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi + -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi + -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi + -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi + -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + cp $(STATICLIB) $(DESTDIR)$(libdir) + chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) + -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1 + -@if test -n "$(SHAREDLIBV)"; then \ + cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \ + echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \ + chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ + echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \ + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \ + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ + ($(LDCONFIG) || true) >/dev/null 2>&1; \ + fi + cp zlib.3 $(DESTDIR)$(man3dir) + chmod 644 $(DESTDIR)$(man3dir)/zlib.3 + cp zlib.pc $(DESTDIR)$(pkgconfigdir) + chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc +# The ranlib in install is needed on NeXTSTEP which checks file times +# ldconfig is for Linux + +install: install-libs + -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi + cp zlib.h zconf.h $(DESTDIR)$(includedir) + chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h + +uninstall: + cd $(DESTDIR)$(includedir); rm -f zlib.h zconf.h + cd $(DESTDIR)$(libdir); rm -f libz.a; \ + if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ + rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ + fi + cd $(DESTDIR)$(man3dir); rm -f zlib.3 + cd $(DESTDIR)$(pkgconfigdir); rm -f zlib.pc + +docs: zlib.3.pdf + +zlib.3.pdf: zlib.3 + groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf + +zconf.h.cmakein: zconf.h.in + -@echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" > $(tempfile) + -@sed -f $(tempfile) zconf.h.in > zconf.h.cmakein + -@touch -r zconf.h.in zconf.h.cmakein + -@rm $(tempfile) + +zconf: zconf.h.in + cp -p zconf.h.in zconf.h + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ \ + example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ + example64$(EXE) minigzip64$(EXE) \ + infcover \ + libz.* foo.gz so_locations \ + _match.s maketree contrib/infback9/*.o + rm -rf objs + rm -f *.gcda *.gcno *.gcov + rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov + +maintainer-clean: distclean +distclean: clean zconf zconf.h.cmakein docs + rm -f Makefile zlib.pc configure.log + -@rm -f .DS_Store + -@printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile + -@printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile + -@touch -r Makefile.in Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o zutil.o: zutil.h zlib.h zconf.h +gzclose.o gzlib.o gzread.o gzwrite.o: zlib.h zconf.h gzguts.h +compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h +crc32.o: zutil.h zlib.h zconf.h crc32.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +infback.o inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h + +adler32.lo zutil.lo: zutil.h zlib.h zconf.h +gzclose.lo gzlib.lo gzread.lo gzwrite.lo: zlib.h zconf.h gzguts.h +compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h +crc32.lo: zutil.h zlib.h zconf.h crc32.h +deflate.lo: deflate.h zutil.h zlib.h zconf.h +infback.lo inflate.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h +inffast.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.lo: zutil.h zlib.h zconf.h inftrees.h +trees.lo: deflate.h zutil.h zlib.h zconf.h trees.h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/README b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/README new file mode 100644 index 00000000..09070e2c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/README @@ -0,0 +1,115 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.6 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +http://marknelson.us/1997/01/01/zlib-engine/ . + +The changes made in version 1.2.6 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package, documented at +http://java.sun.com/developer/technicalArticles/Programming/compression/ . + +A Perl interface to zlib written by Paul Marquess is available +at CPAN (Comprehensive Perl Archive Network) sites, including +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://docs.python.org/library/zlib.html . + +zlib is built into tcl: http://wiki.tcl.tk/4610 . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS or BEOS. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2012 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/adler32.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/adler32.c new file mode 100644 index 00000000..a868f073 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/adler32.c @@ -0,0 +1,179 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + +#define BASE 65521 /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/amiga/Makefile.pup b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/amiga/Makefile.pup new file mode 100644 index 00000000..8940c120 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/amiga/Makefile.pup @@ -0,0 +1,69 @@ +# Amiga powerUP (TM) Makefile +# makefile for libpng and SAS C V6.58/7.00 PPC compiler +# Copyright (C) 1998 by Andreas R. Kleinert + +LIBNAME = libzip.a + +CC = scppc +CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \ + OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER +AR = ppc-amigaos-ar cr +RANLIB = ppc-amigaos-ranlib +LD = ppc-amigaos-ld -r +LDFLAGS = -o +LDLIBS = LIB:scppc.a LIB:end.o +RM = delete quiet + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example minigzip + +check: test +test: all + example + echo hello world | minigzip | minigzip -d + +$(LIBNAME): $(OBJS) + $(AR) $@ $(OBJS) + -$(RANLIB) $@ + +example: example.o $(LIBNAME) + $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS) + +minigzip: minigzip.o $(LIBNAME) + $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS) + +mostlyclean: clean +clean: + $(RM) *.o example minigzip $(LIBNAME) foo.gz + +zip: + zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \ + descrip.mms *.[ch] + +tgz: + cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \ + zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: crc32.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzclose.o: zlib.h zconf.h gzguts.h +gzlib.o: zlib.h zconf.h gzguts.h +gzread.o: zlib.h zconf.h gzguts.h +gzwrite.o: zlib.h zconf.h gzguts.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/amiga/Makefile.sas b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/amiga/Makefile.sas new file mode 100644 index 00000000..749e2915 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/amiga/Makefile.sas @@ -0,0 +1,68 @@ +# SMakefile for zlib +# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly +# Osma Ahvenlampi +# Amiga, SAS/C 6.56 & Smake + +CC=sc +CFLAGS=OPT +#CFLAGS=OPT CPU=68030 +#CFLAGS=DEBUG=LINE +LDFLAGS=LIB z.lib + +SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \ + NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \ + DEF=POSTINC + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: SCOPTIONS example minigzip + +check: test +test: all + example + echo hello world | minigzip | minigzip -d + +install: z.lib + copy clone zlib.h zconf.h INCLUDE: + copy clone z.lib LIB: + +z.lib: $(OBJS) + oml z.lib r $(OBJS) + +example: example.o z.lib + $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS) + +minigzip: minigzip.o z.lib + $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS) + +mostlyclean: clean +clean: + -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS + +SCOPTIONS: Makefile.sas + copy to $@ 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/configure b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/configure new file mode 100644 index 00000000..780317ce --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/configure @@ -0,0 +1,720 @@ +#!/bin/sh +# configure script for zlib. +# +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static +# +# To impose specific compiler or flags or install directory, use for example: +# prefix=$HOME CC=cc CFLAGS="-O4" ./configure +# or for csh/tcsh users: +# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) + +# Incorrect settings of CC or CFLAGS may prevent creating a shared library. +# If you have problems, try without defining CC and CFLAGS before reporting +# an error. + +echo -------------------- >> configure.log +echo $0 $* >> configure.log +date >> configure.log + +if [ -n "${CHOST}" ]; then + uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`" + CROSS_PREFIX="${CHOST}-" +fi + +STATICLIB=libz.a +VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` +VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < zlib.h` +VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h` +VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h` +if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then + AR=${AR-"${CROSS_PREFIX}ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +else + AR=${AR-"ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +fi +ARFLAGS=${ARFLAGS-"rc"} +if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then + RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} + test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log +else + RANLIB=${RANLIB-"ranlib"} +fi +if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then + NM=${NM-"${CROSS_PREFIX}nm"} + test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log +else + NM=${NM-"nm"} +fi +LDCONFIG=${LDCONFIG-"ldconfig"} +LDSHAREDLIBC="${LDSHAREDLIBC--lc}" +ARCHS= +prefix=${prefix-/usr/local} +exec_prefix=${exec_prefix-'${prefix}'} +libdir=${libdir-'${exec_prefix}/lib'} +sharedlibdir=${sharedlibdir-'${libdir}'} +includedir=${includedir-'${prefix}/include'} +mandir=${mandir-'${prefix}/share/man'} +shared_ext='.so' +shared=1 +solo=0 +cover=0 +zprefix=0 +build64=0 +gcc=0 +old_cc="$CC" +old_cflags="$CFLAGS" +OBJC='$(OBJZ) $(OBJG)' +PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)' + +while test $# -ge 1 +do +case "$1" in + -h* | --help) + echo 'usage:' | tee -a configure.log + echo ' configure [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log + echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log + echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log + exit 0 ;; + -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;; + --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;; + -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;; + -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;; + -p* | --prefix) prefix="$2"; shift; shift ;; + -e* | --eprefix) exec_prefix="$2"; shift; shift ;; + -l* | --libdir) libdir="$2"; shift; shift ;; + -i* | --includedir) includedir="$2"; shift; shift ;; + -s* | --shared | --enable-shared) shared=1; shift ;; + -t | --static) shared=0; shift ;; + --solo) solo=1; shift ;; + --cover) cover=1; shift ;; + -z* | --zprefix) zprefix=1; shift ;; + -6* | --64) build64=1; shift ;; + -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;; + --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; + --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; + *) echo "unknown option: $1"; echo "$0 --help for help" | tee -a configure.log; exit 1 ;; + esac +done + +test=ztest$$ + +show() +{ + case "$*" in + *$test.c*) + echo === $test.c === >> configure.log + cat $test.c >> configure.log + echo === >> configure.log;; + esac + echo $* >> configure.log +} + +cat > $test.c </dev/null; then + try() + { + show $* + test "`( $* ) 2>&1 | tee -a configure.log`" = "" + } + echo - using any output from compiler to indicate an error >> configure.log +else + try() + { + show $* + ( $* ) >> configure.log 2>&1 + ret=$? + if test $ret -ne 0; then + echo "(exit code "$ret")" >> configure.log + fi + return $ret + } +fi + +echo >> configure.log + +cat > $test.c <&1` in + *gcc*) gcc=1 ;; +esac + +show $cc -c $cflags $test.c +if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) >> configure.log 2>&1; then + echo ... using gcc >> configure.log + CC="$cc" + CFLAGS="${CFLAGS--O3} ${ARCHS}" + SFLAGS="${CFLAGS--O3} -fPIC" + LDFLAGS="${LDFLAGS} ${ARCHS}" + if test $build64 -eq 1; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + fi + if test "${ZLIBGCCWARN}" = "YES"; then + CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" + fi + if test -z "$uname"; then + uname=`(uname -s || echo unknown) 2>/dev/null` + fi + case "$uname" in + Linux* | linux* | GNU | GNU/* | solaris*) + LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;; + *BSD | *bsd* | DragonFly) + LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} + LDCONFIG="ldconfig -m" ;; + CYGWIN* | Cygwin* | cygwin* | OS/2*) + EXE='.exe' ;; + MINGW* | mingw*) +# temporary bypass + rm -f $test.[co] $test $test$shared_ext + echo "Please use win32/Makefile.gcc instead." | tee -a configure.log + exit 1 + LDSHARED=${LDSHARED-"$cc -shared"} + LDSHAREDLIBC="" + EXE='.exe' ;; + QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 + # (alain.bonnefoy@icbt.com) + LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;; + HP-UX*) + LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} + case `(uname -m || echo unknown) 2>/dev/null` in + ia64) + shared_ext='.so' + SHAREDLIB='libz.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='libz.sl' ;; + esac ;; + Darwin* | darwin*) + shared_ext='.dylib' + SHAREDLIB=libz$shared_ext + SHAREDLIBV=libz.$VER$shared_ext + SHAREDLIBM=libz.$VER1$shared_ext + LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} + AR="libtool" + ARFLAGS="-o" ;; + *) LDSHARED=${LDSHARED-"$cc -shared"} ;; + esac +else + # find system name and corresponding cc options + CC=${CC-cc} + gcc=0 + echo ... using $CC >> configure.log + if test -z "$uname"; then + uname=`(uname -sr || echo unknown) 2>/dev/null` + fi + case "$uname" in + HP-UX*) SFLAGS=${CFLAGS-"-O +z"} + CFLAGS=${CFLAGS-"-O"} +# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} + LDSHARED=${LDSHARED-"ld -b"} + case `(uname -m || echo unknown) 2>/dev/null` in + ia64) + shared_ext='.so' + SHAREDLIB='libz.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='libz.sl' ;; + esac ;; + IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} + CFLAGS=${CFLAGS-"-ansi -O2"} + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; + OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDFLAGS="${LDFLAGS} -Wl,-rpath,." + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;; + OSF1*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; + QNX*) SFLAGS=${CFLAGS-"-4 -O"} + CFLAGS=${CFLAGS-"-4 -O"} + LDSHARED=${LDSHARED-"cc"} + RANLIB=${RANLIB-"true"} + AR="cc" + ARFLAGS="-A" ;; + SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} + CFLAGS=${CFLAGS-"-O3"} + LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;; + SunOS\ 5* | solaris*) + LDSHARED=${LDSHARED-"cc -G"} + case `(uname -m || echo unknown) 2>/dev/null` in + i86*) + SFLAGS=${CFLAGS-"-xpentium -fast -KPIC -R."} + CFLAGS=${CFLAGS-"-xpentium -fast"} ;; + *) + SFLAGS=${CFLAGS-"-fast -xcg92 -KPIC -R."} + CFLAGS=${CFLAGS-"-fast -xcg92"} ;; + esac ;; + SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} + CFLAGS=${CFLAGS-"-O2"} + LDSHARED=${LDSHARED-"ld"} ;; + SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} + CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"} + LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;; + UNIX_System_V\ 4.2.0) + SFLAGS=${CFLAGS-"-KPIC -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"} ;; + UNIX_SV\ 4.2MP) + SFLAGS=${CFLAGS-"-Kconform_pic -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"} ;; + OpenUNIX\ 5) + SFLAGS=${CFLAGS-"-KPIC -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"} ;; + AIX*) # Courtesy of dbakker@arrayasolutions.com + SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + LDSHARED=${LDSHARED-"xlc -G"} ;; + # send working options for other systems to zlib@gzip.org + *) SFLAGS=${CFLAGS-"-O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -shared"} ;; + esac +fi + +SHAREDLIB=${SHAREDLIB-"libz$shared_ext"} +SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"} +SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} + +echo >> configure.log + +if test $shared -eq 1; then + echo Checking for shared library support... | tee -a configure.log + # we must test in two steps (cc then ld), required at least on SunOS 4.x + if try $CC -w -c $SFLAGS $test.c && + try $LDSHARED $SFLAGS -o $test$shared_ext $test.o; then + echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log + elif test -z "$old_cc" -a -z "$old_cflags"; then + echo No shared library support. | tee -a configure.log + shared=0; + else + echo 'No shared library support; try without defining CC and CFLAGS' | tee -a configure.log + shared=0; + fi +fi +if test $shared -eq 0; then + LDSHARED="$CC" + ALL="static" + TEST="all teststatic" + SHAREDLIB="" + SHAREDLIBV="" + SHAREDLIBM="" + echo Building static library $STATICLIB version $VER with $CC. | tee -a configure.log +else + ALL="static shared" + TEST="all teststatic testshared" +fi + +CPP=${CPP-"$CC -E"} +case $CFLAGS in + *ASMV*) + echo >> configure.log + show "$NM $test.o | grep _hello" + if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then + CPP="$CPP -DNO_UNDERLINE" + echo Checking for underline in external names... No. | tee -a configure.log + else + echo Checking for underline in external names... Yes. | tee -a configure.log + fi ;; +esac + +echo >> configure.log + +cat > $test.c < +off64_t dummy = 0; +EOF +if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then + CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" + SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" + ALL="${ALL} all64" + TEST="${TEST} test64" + echo "Checking for off64_t... Yes." | tee -a configure.log + echo "Checking for fseeko... Yes." | tee -a configure.log +else + echo "Checking for off64_t... No." | tee -a configure.log + echo >> configure.log + cat > $test.c < +int main(void) { + fseeko(NULL, 0, 0); + return 0; +} +EOF + if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for fseeko... Yes." | tee -a configure.log + else + CFLAGS="${CFLAGS} -DNO_FSEEKO" + SFLAGS="${SFLAGS} -DNO_FSEEKO" + echo "Checking for fseeko... No." | tee -a configure.log + fi +fi + +cp -p zconf.h.in zconf.h + +echo >> configure.log + +cat > $test.c < +int main() { return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo "Checking for unistd.h... Yes." | tee -a configure.log +else + echo "Checking for unistd.h... No." | tee -a configure.log +fi + +echo >> configure.log + +cat > $test.c < +int main() { return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo "Checking for stdarg.h... Yes." | tee -a configure.log +else + echo "Checking for stdarg.h... No." | tee -a configure.log +fi + +if test $zprefix -eq 1; then + sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo >> configure.log + echo "Using z_ prefix on all symbols." | tee -a configure.log +fi + +if test $solo -eq 1; then + sed '/#define ZCONF_H/a\ +#define Z_SOLO + +' < zconf.h > zconf.temp.h + mv zconf.temp.h zconf.h +OBJC='$(OBJZ)' +PIC_OBJC='$(PIC_OBJZ)' +fi + +if test $cover -eq 1; then + CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage" +fi + +echo >> configure.log + +cat > $test.c < +#include +#include "zconf.h" +int main() +{ +#ifndef STDC + choke me +#endif + return 0; +} +EOF + +if try $CC -c $CFLAGS $test.c; then + echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log + + echo >> configure.log + cat > $test.c < +#include +int mytest(const char *fmt, ...) +{ + char buf[20]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return 0; +} +int main() +{ + return (mytest("Hello%d\n", 1)); +} +EOF + if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +#include +int mytest(const char *fmt, ...) +{ + int n; + char buf[20]; + va_list ap; + va_start(ap, fmt); + n = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return n; +} +int main() +{ + return (mytest("Hello%d\n", 1)); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_vsnprintf_void" + SFLAGS="$SFLAGS -DHAS_vsnprintf_void" + echo "Checking for return value of vsnprintf()... No." | tee -a configure.log + echo " WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + else + CFLAGS="$CFLAGS -DNO_vsnprintf" + SFLAGS="$SFLAGS -DNO_vsnprintf" + echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log + echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log + echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +#include +int mytest(const char *fmt, ...) +{ + int n; + char buf[20]; + va_list ap; + va_start(ap, fmt); + n = vsprintf(buf, fmt, ap); + va_end(ap); + return n; +} +int main() +{ + return (mytest("Hello%d\n", 1)); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_vsprintf_void" + SFLAGS="$SFLAGS -DHAS_vsprintf_void" + echo "Checking for return value of vsprintf()... No." | tee -a configure.log + echo " WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + fi +else + echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +int mytest() +{ + char buf[20]; + snprintf(buf, sizeof(buf), "%s", "foo"); + return 0; +} +int main() +{ + return (mytest()); +} +EOF + + if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +int mytest() +{ + char buf[20]; + return snprintf(buf, sizeof(buf), "%s", "foo"); +} +int main() +{ + return (mytest()); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of snprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_snprintf_void" + SFLAGS="$SFLAGS -DHAS_snprintf_void" + echo "Checking for return value of snprintf()... No." | tee -a configure.log + echo " WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + else + CFLAGS="$CFLAGS -DNO_snprintf" + SFLAGS="$SFLAGS -DNO_snprintf" + echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log + echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log + echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +int mytest() +{ + char buf[20]; + return sprintf(buf, "%s", "foo"); +} +int main() +{ + return (mytest()); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of sprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_sprintf_void" + SFLAGS="$SFLAGS -DHAS_sprintf_void" + echo "Checking for return value of sprintf()... No." | tee -a configure.log + echo " WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + fi +fi + +if test "$gcc" -eq 1; then + echo >> configure.log + cat > $test.c <= 33) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif +int ZLIB_INTERNAL foo; +int main() +{ + return 0; +} +EOF + if try $CC -c $CFLAGS $test.c; then + echo "Checking for attribute(visibility) support... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DNO_VIZ" + SFLAGS="$SFLAGS -DNO_VIZ" + echo "Checking for attribute(visibility) support... No." | tee -a configure.log + fi +fi + +rm -f $test.[co] $test $test$shared_ext $test.gcno + +# show the results in the log +echo >> configure.log +echo ALL = $ALL >> configure.log +echo AR = $AR >> configure.log +echo ARFLAGS = $ARFLAGS >> configure.log +echo CC = $CC >> configure.log +echo CFLAGS = $CFLAGS >> configure.log +echo CPP = $CPP >> configure.log +echo EXE = $EXE >> configure.log +echo LDCONFIG = $LDCONFIG >> configure.log +echo LDFLAGS = $LDFLAGS >> configure.log +echo LDSHARED = $LDSHARED >> configure.log +echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log +echo OBJC = $OBJC >> configure.log +echo PIC_OBJC = $PIC_OBJC >> configure.log +echo RANLIB = $RANLIB >> configure.log +echo SFLAGS = $SFLAGS >> configure.log +echo SHAREDLIB = $SHAREDLIB >> configure.log +echo SHAREDLIBM = $SHAREDLIBM >> configure.log +echo SHAREDLIBV = $SHAREDLIBV >> configure.log +echo STATICLIB = $STATICLIB >> configure.log +echo TEST = $TEST >> configure.log +echo VER = $VER >> configure.log +echo exec_prefix = $exec_prefix >> configure.log +echo includedir = $includedir >> configure.log +echo libdir = $libdir >> configure.log +echo mandir = $mandir >> configure.log +echo prefix = $prefix >> configure.log +echo sharedlibdir = $sharedlibdir >> configure.log +echo uname = $uname >> configure.log +echo -------------------- >> configure.log +echo >> configure.log +echo >> configure.log + +# udpate Makefile +sed < Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^CPP *=/s#=.*#=$CPP# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^LDCONFIG *=/s#=.*#=$LDCONFIG# +/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^OBJC *=/s#=.*#= $OBJC# +/^PIC_OBJC *=/s#=.*#= $PIC_OBJC# +/^all: */s#:.*#: $ALL# +/^test: */s#:.*#: $TEST# +" > Makefile + +sed < zlib.pc.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^CPP *=/s#=.*#=$CPP# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +" | sed -e " +s/\@VERSION\@/$VER/g; +" > zlib.pc diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/README.contrib b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/README.contrib new file mode 100644 index 00000000..dd2285d9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/README.contrib @@ -0,0 +1,77 @@ +All files under this contrib directory are UNSUPPORTED. There were +provided by users of zlib and were not tested by the authors of zlib. +Use at your own risk. Please contact the authors of the contributions +for help about these, not the zlib authors. Thanks. + + +ada/ by Dmitriy Anisimkov + Support for Ada + See http://zlib-ada.sourceforge.net/ + +amd64/ by Mikhail Teterin + asm code for AMD64 + See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393 + +asm686/ by Brian Raiter + asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax + See http://www.muppetlabs.com/~breadbox/software/assembly.html + +blast/ by Mark Adler + Decompressor for output of PKWare Data Compression Library (DCL) + +delphi/ by Cosmin Truta + Support for Delphi and C++ Builder + +dotzlib/ by Henrik Ravn + Support for Microsoft .Net and Visual C++ .Net + +gcc_gvmat64/by Gilles Vollant + GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64 + assembler to replace longest_match() and inflate_fast() + +infback9/ by Mark Adler + Unsupported diffs to infback to decode the deflate64 format + +inflate86/ by Chris Anderson + Tuned x86 gcc asm code to replace inflate_fast() + +iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + +iostream2/ by Tyge Løvset + Another C++ I/O streams interface + +iostream3/ by Ludwig Schwardt + and Kevin Ruland + Yet another C++ I/O streams interface + +masmx64/ by Gilles Vollant + x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to + replace longest_match() and inflate_fast(), also masm x86 + 64-bits translation of Chris Anderson inflate_fast() + +masmx86/ by Gilles Vollant + x86 asm code to replace longest_match() and inflate_fast(), + for Visual C++ and MASM (32 bits). + Based on Brian Raiter (asm686) and Chris Anderson (inflate86) + +minizip/ by Gilles Vollant + Mini zip and unzip based on zlib + Includes Zip64 support by Mathias Svensson + See http://www.winimage.com/zLibDll/unzip.html + +pascal/ by Bob Dellaca et al. + Support for Pascal + +puff/ by Mark Adler + Small, low memory usage inflate. Also serves to provide an + unambiguous description of the deflate format. + +testzlib/ by Gilles Vollant + Example of the use of zlib + +untgz/ by Pedro A. Aranda Gutierrez + A very simple tar.gz file extractor using zlib + +vstudio/ by Gilles Vollant + Building a minizip-enhanced zlib with Microsoft Visual Studio diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/buffer_demo.adb b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/buffer_demo.adb new file mode 100644 index 00000000..46b86381 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/buffer_demo.adb @@ -0,0 +1,106 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- +-- +-- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $ + +-- This demo program provided by Dr Steve Sangwine +-- +-- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer +-- of exactly the correct size is used for decompressed data, and the last +-- few bytes passed in to Zlib are checksum bytes. + +-- This program compresses a string of text, and then decompresses the +-- compressed text into a buffer of the same size as the original text. + +with Ada.Streams; use Ada.Streams; +with Ada.Text_IO; + +with ZLib; use ZLib; + +procedure Buffer_Demo is + EOL : Character renames ASCII.LF; + Text : constant String + := "Four score and seven years ago our fathers brought forth," & EOL & + "upon this continent, a new nation, conceived in liberty," & EOL & + "and dedicated to the proposition that `all men are created equal'."; + + Source : Stream_Element_Array (1 .. Text'Length); + for Source'Address use Text'Address; + +begin + Ada.Text_IO.Put (Text); + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes"); + + declare + Compressed_Data : Stream_Element_Array (1 .. Text'Length); + L : Stream_Element_Offset; + begin + Compress : declare + Compressor : Filter_Type; + I : Stream_Element_Offset; + begin + Deflate_Init (Compressor); + + -- Compress the whole of T at once. + + Translate (Compressor, Source, I, Compressed_Data, L, Finish); + pragma Assert (I = Source'Last); + + Close (Compressor); + + Ada.Text_IO.Put_Line + ("Compressed size : " + & Stream_Element_Offset'Image (L) & " bytes"); + end Compress; + + -- Now we decompress the data, passing short blocks of data to Zlib + -- (because this demonstrates the problem - the last block passed will + -- contain checksum information and there will be no output, only a + -- check inside Zlib that the checksum is correct). + + Decompress : declare + Decompressor : Filter_Type; + + Uncompressed_Data : Stream_Element_Array (1 .. Text'Length); + + Block_Size : constant := 4; + -- This makes sure that the last block contains + -- only Adler checksum data. + + P : Stream_Element_Offset := Compressed_Data'First - 1; + O : Stream_Element_Offset; + begin + Inflate_Init (Decompressor); + + loop + Translate + (Decompressor, + Compressed_Data + (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)), + P, + Uncompressed_Data + (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last), + O, + No_Flush); + + Ada.Text_IO.Put_Line + ("Total in : " & Count'Image (Total_In (Decompressor)) & + ", out : " & Count'Image (Total_Out (Decompressor))); + + exit when P = L; + end loop; + + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Decompressed text matches original text : " + & Boolean'Image (Uncompressed_Data = Source)); + end Decompress; + end; +end Buffer_Demo; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/mtest.adb b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/mtest.adb new file mode 100644 index 00000000..c4dfd080 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/mtest.adb @@ -0,0 +1,156 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- +-- Continuous test for ZLib multithreading. If the test would fail +-- we should provide thread safe allocation routines for the Z_Stream. +-- +-- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $ + +with ZLib; +with Ada.Streams; +with Ada.Numerics.Discrete_Random; +with Ada.Text_IO; +with Ada.Exceptions; +with Ada.Task_Identification; + +procedure MTest is + use Ada.Streams; + use ZLib; + + Stop : Boolean := False; + + pragma Atomic (Stop); + + subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#; + + package Random_Elements is + new Ada.Numerics.Discrete_Random (Visible_Symbols); + + task type Test_Task; + + task body Test_Task is + Buffer : Stream_Element_Array (1 .. 100_000); + Gen : Random_Elements.Generator; + + Buffer_First : Stream_Element_Offset; + Compare_First : Stream_Element_Offset; + + Deflate : Filter_Type; + Inflate : Filter_Type; + + procedure Further (Item : in Stream_Element_Array); + + procedure Read_Buffer + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + + ------------- + -- Further -- + ------------- + + procedure Further (Item : in Stream_Element_Array) is + + procedure Compare (Item : in Stream_Element_Array); + + ------------- + -- Compare -- + ------------- + + procedure Compare (Item : in Stream_Element_Array) is + Next_First : Stream_Element_Offset := Compare_First + Item'Length; + begin + if Buffer (Compare_First .. Next_First - 1) /= Item then + raise Program_Error; + end if; + + Compare_First := Next_First; + end Compare; + + procedure Compare_Write is new ZLib.Write (Write => Compare); + begin + Compare_Write (Inflate, Item, No_Flush); + end Further; + + ----------------- + -- Read_Buffer -- + ----------------- + + procedure Read_Buffer + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset) + is + Buff_Diff : Stream_Element_Offset := Buffer'Last - Buffer_First; + Next_First : Stream_Element_Offset; + begin + if Item'Length <= Buff_Diff then + Last := Item'Last; + + Next_First := Buffer_First + Item'Length; + + Item := Buffer (Buffer_First .. Next_First - 1); + + Buffer_First := Next_First; + else + Last := Item'First + Buff_Diff; + Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last); + Buffer_First := Buffer'Last + 1; + end if; + end Read_Buffer; + + procedure Translate is new Generic_Translate + (Data_In => Read_Buffer, + Data_Out => Further); + + begin + Random_Elements.Reset (Gen); + + Buffer := (others => 20); + + Main : loop + for J in Buffer'Range loop + Buffer (J) := Random_Elements.Random (Gen); + + Deflate_Init (Deflate); + Inflate_Init (Inflate); + + Buffer_First := Buffer'First; + Compare_First := Buffer'First; + + Translate (Deflate); + + if Compare_First /= Buffer'Last + 1 then + raise Program_Error; + end if; + + Ada.Text_IO.Put_Line + (Ada.Task_Identification.Image + (Ada.Task_Identification.Current_Task) + & Stream_Element_Offset'Image (J) + & ZLib.Count'Image (Total_Out (Deflate))); + + Close (Deflate); + Close (Inflate); + + exit Main when Stop; + end loop; + end loop Main; + exception + when E : others => + Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E)); + Stop := True; + end Test_Task; + + Test : array (1 .. 4) of Test_Task; + + pragma Unreferenced (Test); + + Dummy : Character; + +begin + Ada.Text_IO.Get_Immediate (Dummy); + Stop := True; +end MTest; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/read.adb b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/read.adb new file mode 100644 index 00000000..1f2efbfe --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/read.adb @@ -0,0 +1,156 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $ + +-- Test/demo program for the generic read interface. + +with Ada.Numerics.Discrete_Random; +with Ada.Streams; +with Ada.Text_IO; + +with ZLib; + +procedure Read is + + use Ada.Streams; + + ------------------------------------ + -- Test configuration parameters -- + ------------------------------------ + + File_Size : Stream_Element_Offset := 100_000; + + Continuous : constant Boolean := False; + -- If this constant is True, the test would be repeated again and again, + -- with increment File_Size for every iteration. + + Header : constant ZLib.Header_Type := ZLib.Default; + -- Do not use Header other than Default in ZLib versions 1.1.4 and older. + + Init_Random : constant := 8; + -- We are using the same random sequence, in case of we catch bug, + -- so we would be able to reproduce it. + + -- End -- + + Pack_Size : Stream_Element_Offset; + Offset : Stream_Element_Offset; + + Filter : ZLib.Filter_Type; + + subtype Visible_Symbols + is Stream_Element range 16#20# .. 16#7E#; + + package Random_Elements is new + Ada.Numerics.Discrete_Random (Visible_Symbols); + + Gen : Random_Elements.Generator; + Period : constant Stream_Element_Offset := 200; + -- Period constant variable for random generator not to be very random. + -- Bigger period, harder random. + + Read_Buffer : Stream_Element_Array (1 .. 2048); + Read_First : Stream_Element_Offset; + Read_Last : Stream_Element_Offset; + + procedure Reset; + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset); + -- this procedure is for generic instantiation of + -- ZLib.Read + -- reading data from the File_In. + + procedure Read is new ZLib.Read + (Read, + Read_Buffer, + Rest_First => Read_First, + Rest_Last => Read_Last); + + ---------- + -- Read -- + ---------- + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) is + begin + Last := Stream_Element_Offset'Min + (Item'Last, + Item'First + File_Size - Offset); + + for J in Item'First .. Last loop + if J < Item'First + Period then + Item (J) := Random_Elements.Random (Gen); + else + Item (J) := Item (J - Period); + end if; + + Offset := Offset + 1; + end loop; + end Read; + + ----------- + -- Reset -- + ----------- + + procedure Reset is + begin + Random_Elements.Reset (Gen, Init_Random); + Pack_Size := 0; + Offset := 1; + Read_First := Read_Buffer'Last + 1; + Read_Last := Read_Buffer'Last; + end Reset; + +begin + Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version); + + loop + for Level in ZLib.Compression_Level'Range loop + + Ada.Text_IO.Put ("Level =" + & ZLib.Compression_Level'Image (Level)); + + -- Deflate using generic instantiation. + + ZLib.Deflate_Init + (Filter, + Level, + Header => Header); + + Reset; + + Ada.Text_IO.Put + (Stream_Element_Offset'Image (File_Size) & " ->"); + + loop + declare + Buffer : Stream_Element_Array (1 .. 1024); + Last : Stream_Element_Offset; + begin + Read (Filter, Buffer, Last); + + Pack_Size := Pack_Size + Last - Buffer'First + 1; + + exit when Last < Buffer'Last; + end; + end loop; + + Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size)); + + ZLib.Close (Filter); + end loop; + + exit when not Continuous; + + File_Size := File_Size + 1; + end loop; +end Read; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/readme.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/readme.txt new file mode 100644 index 00000000..ce4d2cad --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/readme.txt @@ -0,0 +1,65 @@ + ZLib for Ada thick binding (ZLib.Ada) + Release 1.3 + +ZLib.Ada is a thick binding interface to the popular ZLib data +compression library, available at http://www.gzip.org/zlib/. +It provides Ada-style access to the ZLib C library. + + + Here are the main changes since ZLib.Ada 1.2: + +- Attension: ZLib.Read generic routine have a initialization requirement + for Read_Last parameter now. It is a bit incompartible with previous version, + but extends functionality, we could use new parameters Allow_Read_Some and + Flush now. + +- Added Is_Open routines to ZLib and ZLib.Streams packages. + +- Add pragma Assert to check Stream_Element is 8 bit. + +- Fix extraction to buffer with exact known decompressed size. Error reported by + Steve Sangwine. + +- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits + computers. Patch provided by Pascal Obry. + +- Add Status_Error exception definition. + +- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit. + + + How to build ZLib.Ada under GNAT + +You should have the ZLib library already build on your computer, before +building ZLib.Ada. Make the directory of ZLib.Ada sources current and +issue the command: + + gnatmake test -largs -L -lz + +Or use the GNAT project file build for GNAT 3.15 or later: + + gnatmake -Pzlib.gpr -L + + + How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2 + +1. Make a project with all *.ads and *.adb files from the distribution. +2. Build the libz.a library from the ZLib C sources. +3. Rename libz.a to z.lib. +4. Add the library z.lib to the project. +5. Add the libc.lib library from the ObjectAda distribution to the project. +6. Build the executable using test.adb as a main procedure. + + + How to use ZLib.Ada + +The source files test.adb and read.adb are small demo programs that show +the main functionality of ZLib.Ada. + +The routines from the package specifications are commented. + + +Homepage: http://zlib-ada.sourceforge.net/ +Author: Dmitriy Anisimkov + +Contributors: Pascal Obry , Steve Sangwine diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/test.adb b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/test.adb new file mode 100644 index 00000000..90773acf --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/test.adb @@ -0,0 +1,463 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $ + +-- The program has a few aims. +-- 1. Test ZLib.Ada95 thick binding functionality. +-- 2. Show the example of use main functionality of the ZLib.Ada95 binding. +-- 3. Build this program automatically compile all ZLib.Ada95 packages under +-- GNAT Ada95 compiler. + +with ZLib.Streams; +with Ada.Streams.Stream_IO; +with Ada.Numerics.Discrete_Random; + +with Ada.Text_IO; + +with Ada.Calendar; + +procedure Test is + + use Ada.Streams; + use Stream_IO; + + ------------------------------------ + -- Test configuration parameters -- + ------------------------------------ + + File_Size : Count := 100_000; + Continuous : constant Boolean := False; + + Header : constant ZLib.Header_Type := ZLib.Default; + -- ZLib.None; + -- ZLib.Auto; + -- ZLib.GZip; + -- Do not use Header other then Default in ZLib versions 1.1.4 + -- and older. + + Strategy : constant ZLib.Strategy_Type := ZLib.Default_Strategy; + Init_Random : constant := 10; + + -- End -- + + In_File_Name : constant String := "testzlib.in"; + -- Name of the input file + + Z_File_Name : constant String := "testzlib.zlb"; + -- Name of the compressed file. + + Out_File_Name : constant String := "testzlib.out"; + -- Name of the decompressed file. + + File_In : File_Type; + File_Out : File_Type; + File_Back : File_Type; + File_Z : ZLib.Streams.Stream_Type; + + Filter : ZLib.Filter_Type; + + Time_Stamp : Ada.Calendar.Time; + + procedure Generate_File; + -- Generate file of spetsified size with some random data. + -- The random data is repeatable, for the good compression. + + procedure Compare_Streams + (Left, Right : in out Root_Stream_Type'Class); + -- The procedure compearing data in 2 streams. + -- It is for compare data before and after compression/decompression. + + procedure Compare_Files (Left, Right : String); + -- Compare files. Based on the Compare_Streams. + + procedure Copy_Streams + (Source, Target : in out Root_Stream_Type'Class; + Buffer_Size : in Stream_Element_Offset := 1024); + -- Copying data from one stream to another. It is for test stream + -- interface of the library. + + procedure Data_In + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset); + -- this procedure is for generic instantiation of + -- ZLib.Generic_Translate. + -- reading data from the File_In. + + procedure Data_Out (Item : in Stream_Element_Array); + -- this procedure is for generic instantiation of + -- ZLib.Generic_Translate. + -- writing data to the File_Out. + + procedure Stamp; + -- Store the timestamp to the local variable. + + procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count); + -- Print the time statistic with the message. + + procedure Translate is new ZLib.Generic_Translate + (Data_In => Data_In, + Data_Out => Data_Out); + -- This procedure is moving data from File_In to File_Out + -- with compression or decompression, depend on initialization of + -- Filter parameter. + + ------------------- + -- Compare_Files -- + ------------------- + + procedure Compare_Files (Left, Right : String) is + Left_File, Right_File : File_Type; + begin + Open (Left_File, In_File, Left); + Open (Right_File, In_File, Right); + Compare_Streams (Stream (Left_File).all, Stream (Right_File).all); + Close (Left_File); + Close (Right_File); + end Compare_Files; + + --------------------- + -- Compare_Streams -- + --------------------- + + procedure Compare_Streams + (Left, Right : in out Ada.Streams.Root_Stream_Type'Class) + is + Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#); + Left_Last, Right_Last : Stream_Element_Offset; + begin + loop + Read (Left, Left_Buffer, Left_Last); + Read (Right, Right_Buffer, Right_Last); + + if Left_Last /= Right_Last then + Ada.Text_IO.Put_Line ("Compare error :" + & Stream_Element_Offset'Image (Left_Last) + & " /= " + & Stream_Element_Offset'Image (Right_Last)); + + raise Constraint_Error; + + elsif Left_Buffer (0 .. Left_Last) + /= Right_Buffer (0 .. Right_Last) + then + Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal."); + raise Constraint_Error; + + end if; + + exit when Left_Last < Left_Buffer'Last; + end loop; + end Compare_Streams; + + ------------------ + -- Copy_Streams -- + ------------------ + + procedure Copy_Streams + (Source, Target : in out Ada.Streams.Root_Stream_Type'Class; + Buffer_Size : in Stream_Element_Offset := 1024) + is + Buffer : Stream_Element_Array (1 .. Buffer_Size); + Last : Stream_Element_Offset; + begin + loop + Read (Source, Buffer, Last); + Write (Target, Buffer (1 .. Last)); + + exit when Last < Buffer'Last; + end loop; + end Copy_Streams; + + ------------- + -- Data_In -- + ------------- + + procedure Data_In + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) is + begin + Read (File_In, Item, Last); + end Data_In; + + -------------- + -- Data_Out -- + -------------- + + procedure Data_Out (Item : in Stream_Element_Array) is + begin + Write (File_Out, Item); + end Data_Out; + + ------------------- + -- Generate_File -- + ------------------- + + procedure Generate_File is + subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#; + + package Random_Elements is + new Ada.Numerics.Discrete_Random (Visible_Symbols); + + Gen : Random_Elements.Generator; + Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10; + + Buffer_Count : constant Count := File_Size / Buffer'Length; + -- Number of same buffers in the packet. + + Density : constant Count := 30; -- from 0 to Buffer'Length - 2; + + procedure Fill_Buffer (J, D : in Count); + -- Change the part of the buffer. + + ----------------- + -- Fill_Buffer -- + ----------------- + + procedure Fill_Buffer (J, D : in Count) is + begin + for K in 0 .. D loop + Buffer + (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1)) + := Random_Elements.Random (Gen); + + end loop; + end Fill_Buffer; + + begin + Random_Elements.Reset (Gen, Init_Random); + + Create (File_In, Out_File, In_File_Name); + + Fill_Buffer (1, Buffer'Length - 2); + + for J in 1 .. Buffer_Count loop + Write (File_In, Buffer); + + Fill_Buffer (J, Density); + end loop; + + -- fill remain size. + + Write + (File_In, + Buffer + (1 .. Stream_Element_Offset + (File_Size - Buffer'Length * Buffer_Count))); + + Flush (File_In); + Close (File_In); + end Generate_File; + + --------------------- + -- Print_Statistic -- + --------------------- + + procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is + use Ada.Calendar; + use Ada.Text_IO; + + package Count_IO is new Integer_IO (ZLib.Count); + + Curr_Dur : Duration := Clock - Time_Stamp; + begin + Put (Msg); + + Set_Col (20); + Ada.Text_IO.Put ("size ="); + + Count_IO.Put + (Data_Size, + Width => Stream_IO.Count'Image (File_Size)'Length); + + Put_Line (" duration =" & Duration'Image (Curr_Dur)); + end Print_Statistic; + + ----------- + -- Stamp -- + ----------- + + procedure Stamp is + begin + Time_Stamp := Ada.Calendar.Clock; + end Stamp; + +begin + Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version); + + loop + Generate_File; + + for Level in ZLib.Compression_Level'Range loop + + Ada.Text_IO.Put_Line ("Level =" + & ZLib.Compression_Level'Image (Level)); + + -- Test generic interface. + Open (File_In, In_File, In_File_Name); + Create (File_Out, Out_File, Z_File_Name); + + Stamp; + + -- Deflate using generic instantiation. + + ZLib.Deflate_Init + (Filter => Filter, + Level => Level, + Strategy => Strategy, + Header => Header); + + Translate (Filter); + Print_Statistic ("Generic compress", ZLib.Total_Out (Filter)); + ZLib.Close (Filter); + + Close (File_In); + Close (File_Out); + + Open (File_In, In_File, Z_File_Name); + Create (File_Out, Out_File, Out_File_Name); + + Stamp; + + -- Inflate using generic instantiation. + + ZLib.Inflate_Init (Filter, Header => Header); + + Translate (Filter); + Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter)); + + ZLib.Close (Filter); + + Close (File_In); + Close (File_Out); + + Compare_Files (In_File_Name, Out_File_Name); + + -- Test stream interface. + + -- Compress to the back stream. + + Open (File_In, In_File, In_File_Name); + Create (File_Back, Out_File, Z_File_Name); + + Stamp; + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.Out_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => True, + Level => Level, + Strategy => Strategy, + Header => Header); + + Copy_Streams + (Source => Stream (File_In).all, + Target => File_Z); + + -- Flushing internal buffers to the back stream. + + ZLib.Streams.Flush (File_Z, ZLib.Finish); + + Print_Statistic ("Write compress", + ZLib.Streams.Write_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + + Close (File_In); + Close (File_Back); + + -- Compare reading from original file and from + -- decompression stream. + + Open (File_In, In_File, In_File_Name); + Open (File_Back, In_File, Z_File_Name); + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.In_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => True, + Header => Header); + + Stamp; + Compare_Streams (Stream (File_In).all, File_Z); + + Print_Statistic ("Read decompress", + ZLib.Streams.Read_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + Close (File_In); + Close (File_Back); + + -- Compress by reading from compression stream. + + Open (File_Back, In_File, In_File_Name); + Create (File_Out, Out_File, Z_File_Name); + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.In_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => False, + Level => Level, + Strategy => Strategy, + Header => Header); + + Stamp; + Copy_Streams + (Source => File_Z, + Target => Stream (File_Out).all); + + Print_Statistic ("Read compress", + ZLib.Streams.Read_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + + Close (File_Out); + Close (File_Back); + + -- Decompress to decompression stream. + + Open (File_In, In_File, Z_File_Name); + Create (File_Back, Out_File, Out_File_Name); + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.Out_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => False, + Header => Header); + + Stamp; + + Copy_Streams + (Source => Stream (File_In).all, + Target => File_Z); + + Print_Statistic ("Write decompress", + ZLib.Streams.Write_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + Close (File_In); + Close (File_Back); + + Compare_Files (In_File_Name, Out_File_Name); + end loop; + + Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok."); + + exit when not Continuous; + + File_Size := File_Size + 1; + end loop; +end Test; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-streams.adb b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-streams.adb new file mode 100644 index 00000000..b6497bae --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-streams.adb @@ -0,0 +1,225 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $ + +with Ada.Unchecked_Deallocation; + +package body ZLib.Streams is + + ----------- + -- Close -- + ----------- + + procedure Close (Stream : in out Stream_Type) is + procedure Free is new Ada.Unchecked_Deallocation + (Stream_Element_Array, Buffer_Access); + begin + if Stream.Mode = Out_Stream or Stream.Mode = Duplex then + -- We should flush the data written by the writer. + + Flush (Stream, Finish); + + Close (Stream.Writer); + end if; + + if Stream.Mode = In_Stream or Stream.Mode = Duplex then + Close (Stream.Reader); + Free (Stream.Buffer); + end if; + end Close; + + ------------ + -- Create -- + ------------ + + procedure Create + (Stream : out Stream_Type; + Mode : in Stream_Mode; + Back : in Stream_Access; + Back_Compressed : in Boolean; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Header : in Header_Type := Default; + Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size; + Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size) + is + + subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size); + + procedure Init_Filter + (Filter : in out Filter_Type; + Compress : in Boolean); + + ----------------- + -- Init_Filter -- + ----------------- + + procedure Init_Filter + (Filter : in out Filter_Type; + Compress : in Boolean) is + begin + if Compress then + Deflate_Init + (Filter, Level, Strategy, Header => Header); + else + Inflate_Init (Filter, Header => Header); + end if; + end Init_Filter; + + begin + Stream.Back := Back; + Stream.Mode := Mode; + + if Mode = Out_Stream or Mode = Duplex then + Init_Filter (Stream.Writer, Back_Compressed); + Stream.Buffer_Size := Write_Buffer_Size; + else + Stream.Buffer_Size := 0; + end if; + + if Mode = In_Stream or Mode = Duplex then + Init_Filter (Stream.Reader, not Back_Compressed); + + Stream.Buffer := new Buffer_Subtype; + Stream.Rest_First := Stream.Buffer'Last + 1; + Stream.Rest_Last := Stream.Buffer'Last; + end if; + end Create; + + ----------- + -- Flush -- + ----------- + + procedure Flush + (Stream : in out Stream_Type; + Mode : in Flush_Mode := Sync_Flush) + is + Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size); + Last : Stream_Element_Offset; + begin + loop + Flush (Stream.Writer, Buffer, Last, Mode); + + Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last)); + + exit when Last < Buffer'Last; + end loop; + end Flush; + + ------------- + -- Is_Open -- + ------------- + + function Is_Open (Stream : Stream_Type) return Boolean is + begin + return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer); + end Is_Open; + + ---------- + -- Read -- + ---------- + + procedure Read + (Stream : in out Stream_Type; + Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) + is + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset); + + ---------- + -- Read -- + ---------- + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) is + begin + Ada.Streams.Read (Stream.Back.all, Item, Last); + end Read; + + procedure Read is new ZLib.Read + (Read => Read, + Buffer => Stream.Buffer.all, + Rest_First => Stream.Rest_First, + Rest_Last => Stream.Rest_Last); + + begin + Read (Stream.Reader, Item, Last); + end Read; + + ------------------- + -- Read_Total_In -- + ------------------- + + function Read_Total_In (Stream : in Stream_Type) return Count is + begin + return Total_In (Stream.Reader); + end Read_Total_In; + + -------------------- + -- Read_Total_Out -- + -------------------- + + function Read_Total_Out (Stream : in Stream_Type) return Count is + begin + return Total_Out (Stream.Reader); + end Read_Total_Out; + + ----------- + -- Write -- + ----------- + + procedure Write + (Stream : in out Stream_Type; + Item : in Stream_Element_Array) + is + + procedure Write (Item : in Stream_Element_Array); + + ----------- + -- Write -- + ----------- + + procedure Write (Item : in Stream_Element_Array) is + begin + Ada.Streams.Write (Stream.Back.all, Item); + end Write; + + procedure Write is new ZLib.Write + (Write => Write, + Buffer_Size => Stream.Buffer_Size); + + begin + Write (Stream.Writer, Item, No_Flush); + end Write; + + -------------------- + -- Write_Total_In -- + -------------------- + + function Write_Total_In (Stream : in Stream_Type) return Count is + begin + return Total_In (Stream.Writer); + end Write_Total_In; + + --------------------- + -- Write_Total_Out -- + --------------------- + + function Write_Total_Out (Stream : in Stream_Type) return Count is + begin + return Total_Out (Stream.Writer); + end Write_Total_Out; + +end ZLib.Streams; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-streams.ads b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-streams.ads new file mode 100644 index 00000000..f0193c6b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-streams.ads @@ -0,0 +1,114 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $ + +package ZLib.Streams is + + type Stream_Mode is (In_Stream, Out_Stream, Duplex); + + type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class; + + type Stream_Type is + new Ada.Streams.Root_Stream_Type with private; + + procedure Read + (Stream : in out Stream_Type; + Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + + procedure Write + (Stream : in out Stream_Type; + Item : in Ada.Streams.Stream_Element_Array); + + procedure Flush + (Stream : in out Stream_Type; + Mode : in Flush_Mode := Sync_Flush); + -- Flush the written data to the back stream, + -- all data placed to the compressor is flushing to the Back stream. + -- Should not be used untill necessary, becouse it is decreasing + -- compression. + + function Read_Total_In (Stream : in Stream_Type) return Count; + pragma Inline (Read_Total_In); + -- Return total number of bytes read from back stream so far. + + function Read_Total_Out (Stream : in Stream_Type) return Count; + pragma Inline (Read_Total_Out); + -- Return total number of bytes read so far. + + function Write_Total_In (Stream : in Stream_Type) return Count; + pragma Inline (Write_Total_In); + -- Return total number of bytes written so far. + + function Write_Total_Out (Stream : in Stream_Type) return Count; + pragma Inline (Write_Total_Out); + -- Return total number of bytes written to the back stream. + + procedure Create + (Stream : out Stream_Type; + Mode : in Stream_Mode; + Back : in Stream_Access; + Back_Compressed : in Boolean; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Header : in Header_Type := Default; + Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size; + Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size); + -- Create the Comression/Decompression stream. + -- If mode is In_Stream then Write operation is disabled. + -- If mode is Out_Stream then Read operation is disabled. + + -- If Back_Compressed is true then + -- Data written to the Stream is compressing to the Back stream + -- and data read from the Stream is decompressed data from the Back stream. + + -- If Back_Compressed is false then + -- Data written to the Stream is decompressing to the Back stream + -- and data read from the Stream is compressed data from the Back stream. + + -- !!! When the Need_Header is False ZLib-Ada is using undocumented + -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers. + + function Is_Open (Stream : Stream_Type) return Boolean; + + procedure Close (Stream : in out Stream_Type); + +private + + use Ada.Streams; + + type Buffer_Access is access all Stream_Element_Array; + + type Stream_Type + is new Root_Stream_Type with + record + Mode : Stream_Mode; + + Buffer : Buffer_Access; + Rest_First : Stream_Element_Offset; + Rest_Last : Stream_Element_Offset; + -- Buffer for Read operation. + -- We need to have this buffer in the record + -- becouse not all read data from back stream + -- could be processed during the read operation. + + Buffer_Size : Stream_Element_Offset; + -- Buffer size for write operation. + -- We do not need to have this buffer + -- in the record becouse all data could be + -- processed in the write operation. + + Back : Stream_Access; + Reader : Filter_Type; + Writer : Filter_Type; + end record; + +end ZLib.Streams; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-thin.adb b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-thin.adb new file mode 100644 index 00000000..0ca4a712 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-thin.adb @@ -0,0 +1,141 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $ + +package body ZLib.Thin is + + ZLIB_VERSION : constant Chars_Ptr := zlibVersion; + + Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit; + + -------------- + -- Avail_In -- + -------------- + + function Avail_In (Strm : in Z_Stream) return UInt is + begin + return Strm.Avail_In; + end Avail_In; + + --------------- + -- Avail_Out -- + --------------- + + function Avail_Out (Strm : in Z_Stream) return UInt is + begin + return Strm.Avail_Out; + end Avail_Out; + + ------------------ + -- Deflate_Init -- + ------------------ + + function Deflate_Init + (strm : Z_Streamp; + level : Int; + method : Int; + windowBits : Int; + memLevel : Int; + strategy : Int) + return Int is + begin + return deflateInit2 + (strm, + level, + method, + windowBits, + memLevel, + strategy, + ZLIB_VERSION, + Z_Stream_Size); + end Deflate_Init; + + ------------------ + -- Inflate_Init -- + ------------------ + + function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is + begin + return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size); + end Inflate_Init; + + ------------------------ + -- Last_Error_Message -- + ------------------------ + + function Last_Error_Message (Strm : in Z_Stream) return String is + use Interfaces.C.Strings; + begin + if Strm.msg = Null_Ptr then + return ""; + else + return Value (Strm.msg); + end if; + end Last_Error_Message; + + ------------ + -- Set_In -- + ------------ + + procedure Set_In + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt) is + begin + Strm.Next_In := Buffer; + Strm.Avail_In := Size; + end Set_In; + + ------------------ + -- Set_Mem_Func -- + ------------------ + + procedure Set_Mem_Func + (Strm : in out Z_Stream; + Opaque : in Voidp; + Alloc : in alloc_func; + Free : in free_func) is + begin + Strm.opaque := Opaque; + Strm.zalloc := Alloc; + Strm.zfree := Free; + end Set_Mem_Func; + + ------------- + -- Set_Out -- + ------------- + + procedure Set_Out + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt) is + begin + Strm.Next_Out := Buffer; + Strm.Avail_Out := Size; + end Set_Out; + + -------------- + -- Total_In -- + -------------- + + function Total_In (Strm : in Z_Stream) return ULong is + begin + return Strm.Total_In; + end Total_In; + + --------------- + -- Total_Out -- + --------------- + + function Total_Out (Strm : in Z_Stream) return ULong is + begin + return Strm.Total_Out; + end Total_Out; + +end ZLib.Thin; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-thin.ads b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-thin.ads new file mode 100644 index 00000000..d4407eb8 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib-thin.ads @@ -0,0 +1,450 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $ + +with Interfaces.C.Strings; + +with System; + +private package ZLib.Thin is + + -- From zconf.h + + MAX_MEM_LEVEL : constant := 9; -- zconf.h:105 + -- zconf.h:105 + MAX_WBITS : constant := 15; -- zconf.h:115 + -- 32K LZ77 window + -- zconf.h:115 + SEEK_SET : constant := 8#0000#; -- zconf.h:244 + -- Seek from beginning of file. + -- zconf.h:244 + SEEK_CUR : constant := 1; -- zconf.h:245 + -- Seek from current position. + -- zconf.h:245 + SEEK_END : constant := 2; -- zconf.h:246 + -- Set file pointer to EOF plus "offset" + -- zconf.h:246 + + type Byte is new Interfaces.C.unsigned_char; -- 8 bits + -- zconf.h:214 + type UInt is new Interfaces.C.unsigned; -- 16 bits or more + -- zconf.h:216 + type Int is new Interfaces.C.int; + + type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more + -- zconf.h:217 + subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr; + + type ULong_Access is access ULong; + type Int_Access is access Int; + + subtype Voidp is System.Address; -- zconf.h:232 + + subtype Byte_Access is Voidp; + + Nul : constant Voidp := System.Null_Address; + -- end from zconf + + Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125 + -- zlib.h:125 + Z_PARTIAL_FLUSH : constant := 1; -- zlib.h:126 + -- will be removed, use + -- Z_SYNC_FLUSH instead + -- zlib.h:126 + Z_SYNC_FLUSH : constant := 2; -- zlib.h:127 + -- zlib.h:127 + Z_FULL_FLUSH : constant := 3; -- zlib.h:128 + -- zlib.h:128 + Z_FINISH : constant := 4; -- zlib.h:129 + -- zlib.h:129 + Z_OK : constant := 8#0000#; -- zlib.h:132 + -- zlib.h:132 + Z_STREAM_END : constant := 1; -- zlib.h:133 + -- zlib.h:133 + Z_NEED_DICT : constant := 2; -- zlib.h:134 + -- zlib.h:134 + Z_ERRNO : constant := -1; -- zlib.h:135 + -- zlib.h:135 + Z_STREAM_ERROR : constant := -2; -- zlib.h:136 + -- zlib.h:136 + Z_DATA_ERROR : constant := -3; -- zlib.h:137 + -- zlib.h:137 + Z_MEM_ERROR : constant := -4; -- zlib.h:138 + -- zlib.h:138 + Z_BUF_ERROR : constant := -5; -- zlib.h:139 + -- zlib.h:139 + Z_VERSION_ERROR : constant := -6; -- zlib.h:140 + -- zlib.h:140 + Z_NO_COMPRESSION : constant := 8#0000#; -- zlib.h:145 + -- zlib.h:145 + Z_BEST_SPEED : constant := 1; -- zlib.h:146 + -- zlib.h:146 + Z_BEST_COMPRESSION : constant := 9; -- zlib.h:147 + -- zlib.h:147 + Z_DEFAULT_COMPRESSION : constant := -1; -- zlib.h:148 + -- zlib.h:148 + Z_FILTERED : constant := 1; -- zlib.h:151 + -- zlib.h:151 + Z_HUFFMAN_ONLY : constant := 2; -- zlib.h:152 + -- zlib.h:152 + Z_DEFAULT_STRATEGY : constant := 8#0000#; -- zlib.h:153 + -- zlib.h:153 + Z_BINARY : constant := 8#0000#; -- zlib.h:156 + -- zlib.h:156 + Z_ASCII : constant := 1; -- zlib.h:157 + -- zlib.h:157 + Z_UNKNOWN : constant := 2; -- zlib.h:158 + -- zlib.h:158 + Z_DEFLATED : constant := 8; -- zlib.h:161 + -- zlib.h:161 + Z_NULL : constant := 8#0000#; -- zlib.h:164 + -- for initializing zalloc, zfree, opaque + -- zlib.h:164 + type gzFile is new Voidp; -- zlib.h:646 + + type Z_Stream is private; + + type Z_Streamp is access all Z_Stream; -- zlib.h:89 + + type alloc_func is access function + (Opaque : Voidp; + Items : UInt; + Size : UInt) + return Voidp; -- zlib.h:63 + + type free_func is access procedure (opaque : Voidp; address : Voidp); + + function zlibVersion return Chars_Ptr; + + function Deflate (strm : Z_Streamp; flush : Int) return Int; + + function DeflateEnd (strm : Z_Streamp) return Int; + + function Inflate (strm : Z_Streamp; flush : Int) return Int; + + function InflateEnd (strm : Z_Streamp) return Int; + + function deflateSetDictionary + (strm : Z_Streamp; + dictionary : Byte_Access; + dictLength : UInt) + return Int; + + function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int; + -- zlib.h:478 + + function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495 + + function deflateParams + (strm : Z_Streamp; + level : Int; + strategy : Int) + return Int; -- zlib.h:506 + + function inflateSetDictionary + (strm : Z_Streamp; + dictionary : Byte_Access; + dictLength : UInt) + return Int; -- zlib.h:548 + + function inflateSync (strm : Z_Streamp) return Int; -- zlib.h:565 + + function inflateReset (strm : Z_Streamp) return Int; -- zlib.h:580 + + function compress + (dest : Byte_Access; + destLen : ULong_Access; + source : Byte_Access; + sourceLen : ULong) + return Int; -- zlib.h:601 + + function compress2 + (dest : Byte_Access; + destLen : ULong_Access; + source : Byte_Access; + sourceLen : ULong; + level : Int) + return Int; -- zlib.h:615 + + function uncompress + (dest : Byte_Access; + destLen : ULong_Access; + source : Byte_Access; + sourceLen : ULong) + return Int; + + function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile; + + function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile; + + function gzsetparams + (file : gzFile; + level : Int; + strategy : Int) + return Int; + + function gzread + (file : gzFile; + buf : Voidp; + len : UInt) + return Int; + + function gzwrite + (file : in gzFile; + buf : in Voidp; + len : in UInt) + return Int; + + function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int; + + function gzputs (file : in gzFile; s : in Chars_Ptr) return Int; + + function gzgets + (file : gzFile; + buf : Chars_Ptr; + len : Int) + return Chars_Ptr; + + function gzputc (file : gzFile; char : Int) return Int; + + function gzgetc (file : gzFile) return Int; + + function gzflush (file : gzFile; flush : Int) return Int; + + function gzseek + (file : gzFile; + offset : Int; + whence : Int) + return Int; + + function gzrewind (file : gzFile) return Int; + + function gztell (file : gzFile) return Int; + + function gzeof (file : gzFile) return Int; + + function gzclose (file : gzFile) return Int; + + function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr; + + function adler32 + (adler : ULong; + buf : Byte_Access; + len : UInt) + return ULong; + + function crc32 + (crc : ULong; + buf : Byte_Access; + len : UInt) + return ULong; + + function deflateInit + (strm : Z_Streamp; + level : Int; + version : Chars_Ptr; + stream_size : Int) + return Int; + + function deflateInit2 + (strm : Z_Streamp; + level : Int; + method : Int; + windowBits : Int; + memLevel : Int; + strategy : Int; + version : Chars_Ptr; + stream_size : Int) + return Int; + + function Deflate_Init + (strm : Z_Streamp; + level : Int; + method : Int; + windowBits : Int; + memLevel : Int; + strategy : Int) + return Int; + pragma Inline (Deflate_Init); + + function inflateInit + (strm : Z_Streamp; + version : Chars_Ptr; + stream_size : Int) + return Int; + + function inflateInit2 + (strm : in Z_Streamp; + windowBits : in Int; + version : in Chars_Ptr; + stream_size : in Int) + return Int; + + function inflateBackInit + (strm : in Z_Streamp; + windowBits : in Int; + window : in Byte_Access; + version : in Chars_Ptr; + stream_size : in Int) + return Int; + -- Size of window have to be 2**windowBits. + + function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int; + pragma Inline (Inflate_Init); + + function zError (err : Int) return Chars_Ptr; + + function inflateSyncPoint (z : Z_Streamp) return Int; + + function get_crc_table return ULong_Access; + + -- Interface to the available fields of the z_stream structure. + -- The application must update next_in and avail_in when avail_in has + -- dropped to zero. It must update next_out and avail_out when avail_out + -- has dropped to zero. The application must initialize zalloc, zfree and + -- opaque before calling the init function. + + procedure Set_In + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt); + pragma Inline (Set_In); + + procedure Set_Out + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt); + pragma Inline (Set_Out); + + procedure Set_Mem_Func + (Strm : in out Z_Stream; + Opaque : in Voidp; + Alloc : in alloc_func; + Free : in free_func); + pragma Inline (Set_Mem_Func); + + function Last_Error_Message (Strm : in Z_Stream) return String; + pragma Inline (Last_Error_Message); + + function Avail_Out (Strm : in Z_Stream) return UInt; + pragma Inline (Avail_Out); + + function Avail_In (Strm : in Z_Stream) return UInt; + pragma Inline (Avail_In); + + function Total_In (Strm : in Z_Stream) return ULong; + pragma Inline (Total_In); + + function Total_Out (Strm : in Z_Stream) return ULong; + pragma Inline (Total_Out); + + function inflateCopy + (dest : in Z_Streamp; + Source : in Z_Streamp) + return Int; + + function compressBound (Source_Len : in ULong) return ULong; + + function deflateBound + (Strm : in Z_Streamp; + Source_Len : in ULong) + return ULong; + + function gzungetc (C : in Int; File : in gzFile) return Int; + + function zlibCompileFlags return ULong; + +private + + type Z_Stream is record -- zlib.h:68 + Next_In : Voidp := Nul; -- next input byte + Avail_In : UInt := 0; -- number of bytes available at next_in + Total_In : ULong := 0; -- total nb of input bytes read so far + Next_Out : Voidp := Nul; -- next output byte should be put there + Avail_Out : UInt := 0; -- remaining free space at next_out + Total_Out : ULong := 0; -- total nb of bytes output so far + msg : Chars_Ptr; -- last error message, NULL if no error + state : Voidp; -- not visible by applications + zalloc : alloc_func := null; -- used to allocate the internal state + zfree : free_func := null; -- used to free the internal state + opaque : Voidp; -- private data object passed to + -- zalloc and zfree + data_type : Int; -- best guess about the data type: + -- ascii or binary + adler : ULong; -- adler32 value of the uncompressed + -- data + reserved : ULong; -- reserved for future use + end record; + + pragma Convention (C, Z_Stream); + + pragma Import (C, zlibVersion, "zlibVersion"); + pragma Import (C, Deflate, "deflate"); + pragma Import (C, DeflateEnd, "deflateEnd"); + pragma Import (C, Inflate, "inflate"); + pragma Import (C, InflateEnd, "inflateEnd"); + pragma Import (C, deflateSetDictionary, "deflateSetDictionary"); + pragma Import (C, deflateCopy, "deflateCopy"); + pragma Import (C, deflateReset, "deflateReset"); + pragma Import (C, deflateParams, "deflateParams"); + pragma Import (C, inflateSetDictionary, "inflateSetDictionary"); + pragma Import (C, inflateSync, "inflateSync"); + pragma Import (C, inflateReset, "inflateReset"); + pragma Import (C, compress, "compress"); + pragma Import (C, compress2, "compress2"); + pragma Import (C, uncompress, "uncompress"); + pragma Import (C, gzopen, "gzopen"); + pragma Import (C, gzdopen, "gzdopen"); + pragma Import (C, gzsetparams, "gzsetparams"); + pragma Import (C, gzread, "gzread"); + pragma Import (C, gzwrite, "gzwrite"); + pragma Import (C, gzprintf, "gzprintf"); + pragma Import (C, gzputs, "gzputs"); + pragma Import (C, gzgets, "gzgets"); + pragma Import (C, gzputc, "gzputc"); + pragma Import (C, gzgetc, "gzgetc"); + pragma Import (C, gzflush, "gzflush"); + pragma Import (C, gzseek, "gzseek"); + pragma Import (C, gzrewind, "gzrewind"); + pragma Import (C, gztell, "gztell"); + pragma Import (C, gzeof, "gzeof"); + pragma Import (C, gzclose, "gzclose"); + pragma Import (C, gzerror, "gzerror"); + pragma Import (C, adler32, "adler32"); + pragma Import (C, crc32, "crc32"); + pragma Import (C, deflateInit, "deflateInit_"); + pragma Import (C, inflateInit, "inflateInit_"); + pragma Import (C, deflateInit2, "deflateInit2_"); + pragma Import (C, inflateInit2, "inflateInit2_"); + pragma Import (C, zError, "zError"); + pragma Import (C, inflateSyncPoint, "inflateSyncPoint"); + pragma Import (C, get_crc_table, "get_crc_table"); + + -- since zlib 1.2.0: + + pragma Import (C, inflateCopy, "inflateCopy"); + pragma Import (C, compressBound, "compressBound"); + pragma Import (C, deflateBound, "deflateBound"); + pragma Import (C, gzungetc, "gzungetc"); + pragma Import (C, zlibCompileFlags, "zlibCompileFlags"); + + pragma Import (C, inflateBackInit, "inflateBackInit_"); + + -- I stopped binding the inflateBack routines, becouse realize that + -- it does not support zlib and gzip headers for now, and have no + -- symmetric deflateBack routines. + -- ZLib-Ada is symmetric regarding deflate/inflate data transformation + -- and has a similar generic callback interface for the + -- deflate/inflate transformation based on the regular Deflate/Inflate + -- routines. + + -- pragma Import (C, inflateBack, "inflateBack"); + -- pragma Import (C, inflateBackEnd, "inflateBackEnd"); + +end ZLib.Thin; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib.adb b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib.adb new file mode 100644 index 00000000..8b6fd686 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib.adb @@ -0,0 +1,701 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $ + +with Ada.Exceptions; +with Ada.Unchecked_Conversion; +with Ada.Unchecked_Deallocation; + +with Interfaces.C.Strings; + +with ZLib.Thin; + +package body ZLib is + + use type Thin.Int; + + type Z_Stream is new Thin.Z_Stream; + + type Return_Code_Enum is + (OK, + STREAM_END, + NEED_DICT, + ERRNO, + STREAM_ERROR, + DATA_ERROR, + MEM_ERROR, + BUF_ERROR, + VERSION_ERROR); + + type Flate_Step_Function is access + function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int; + pragma Convention (C, Flate_Step_Function); + + type Flate_End_Function is access + function (Ctrm : in Thin.Z_Streamp) return Thin.Int; + pragma Convention (C, Flate_End_Function); + + type Flate_Type is record + Step : Flate_Step_Function; + Done : Flate_End_Function; + end record; + + subtype Footer_Array is Stream_Element_Array (1 .. 8); + + Simple_GZip_Header : constant Stream_Element_Array (1 .. 10) + := (16#1f#, 16#8b#, -- Magic header + 16#08#, -- Z_DEFLATED + 16#00#, -- Flags + 16#00#, 16#00#, 16#00#, 16#00#, -- Time + 16#00#, -- XFlags + 16#03# -- OS code + ); + -- The simplest gzip header is not for informational, but just for + -- gzip format compatibility. + -- Note that some code below is using assumption + -- Simple_GZip_Header'Last > Footer_Array'Last, so do not make + -- Simple_GZip_Header'Last <= Footer_Array'Last. + + Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum + := (0 => OK, + 1 => STREAM_END, + 2 => NEED_DICT, + -1 => ERRNO, + -2 => STREAM_ERROR, + -3 => DATA_ERROR, + -4 => MEM_ERROR, + -5 => BUF_ERROR, + -6 => VERSION_ERROR); + + Flate : constant array (Boolean) of Flate_Type + := (True => (Step => Thin.Deflate'Access, + Done => Thin.DeflateEnd'Access), + False => (Step => Thin.Inflate'Access, + Done => Thin.InflateEnd'Access)); + + Flush_Finish : constant array (Boolean) of Flush_Mode + := (True => Finish, False => No_Flush); + + procedure Raise_Error (Stream : in Z_Stream); + pragma Inline (Raise_Error); + + procedure Raise_Error (Message : in String); + pragma Inline (Raise_Error); + + procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int); + + procedure Free is new Ada.Unchecked_Deallocation + (Z_Stream, Z_Stream_Access); + + function To_Thin_Access is new Ada.Unchecked_Conversion + (Z_Stream_Access, Thin.Z_Streamp); + + procedure Translate_GZip + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + -- Separate translate routine for make gzip header. + + procedure Translate_Auto + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + -- translate routine without additional headers. + + ----------------- + -- Check_Error -- + ----------------- + + procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is + use type Thin.Int; + begin + if Code /= Thin.Z_OK then + Raise_Error + (Return_Code_Enum'Image (Return_Code (Code)) + & ": " & Last_Error_Message (Stream)); + end if; + end Check_Error; + + ----------- + -- Close -- + ----------- + + procedure Close + (Filter : in out Filter_Type; + Ignore_Error : in Boolean := False) + is + Code : Thin.Int; + begin + if not Ignore_Error and then not Is_Open (Filter) then + raise Status_Error; + end if; + + Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm)); + + if Ignore_Error or else Code = Thin.Z_OK then + Free (Filter.Strm); + else + declare + Error_Message : constant String + := Last_Error_Message (Filter.Strm.all); + begin + Free (Filter.Strm); + Ada.Exceptions.Raise_Exception + (ZLib_Error'Identity, + Return_Code_Enum'Image (Return_Code (Code)) + & ": " & Error_Message); + end; + end if; + end Close; + + ----------- + -- CRC32 -- + ----------- + + function CRC32 + (CRC : in Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array) + return Unsigned_32 + is + use Thin; + begin + return Unsigned_32 (crc32 (ULong (CRC), + Data'Address, + Data'Length)); + end CRC32; + + procedure CRC32 + (CRC : in out Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array) is + begin + CRC := CRC32 (CRC, Data); + end CRC32; + + ------------------ + -- Deflate_Init -- + ------------------ + + procedure Deflate_Init + (Filter : in out Filter_Type; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Method : in Compression_Method := Deflated; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Memory_Level : in Memory_Level_Type := Default_Memory_Level; + Header : in Header_Type := Default) + is + use type Thin.Int; + Win_Bits : Thin.Int := Thin.Int (Window_Bits); + begin + if Is_Open (Filter) then + raise Status_Error; + end if; + + -- We allow ZLib to make header only in case of default header type. + -- Otherwise we would either do header by ourselfs, or do not do + -- header at all. + + if Header = None or else Header = GZip then + Win_Bits := -Win_Bits; + end if; + + -- For the GZip CRC calculation and make headers. + + if Header = GZip then + Filter.CRC := 0; + Filter.Offset := Simple_GZip_Header'First; + else + Filter.Offset := Simple_GZip_Header'Last + 1; + end if; + + Filter.Strm := new Z_Stream; + Filter.Compression := True; + Filter.Stream_End := False; + Filter.Header := Header; + + if Thin.Deflate_Init + (To_Thin_Access (Filter.Strm), + Level => Thin.Int (Level), + method => Thin.Int (Method), + windowBits => Win_Bits, + memLevel => Thin.Int (Memory_Level), + strategy => Thin.Int (Strategy)) /= Thin.Z_OK + then + Raise_Error (Filter.Strm.all); + end if; + end Deflate_Init; + + ----------- + -- Flush -- + ----------- + + procedure Flush + (Filter : in out Filter_Type; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) + is + No_Data : Stream_Element_Array := (1 .. 0 => 0); + Last : Stream_Element_Offset; + begin + Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush); + end Flush; + + ----------------------- + -- Generic_Translate -- + ----------------------- + + procedure Generic_Translate + (Filter : in out ZLib.Filter_Type; + In_Buffer_Size : in Integer := Default_Buffer_Size; + Out_Buffer_Size : in Integer := Default_Buffer_Size) + is + In_Buffer : Stream_Element_Array + (1 .. Stream_Element_Offset (In_Buffer_Size)); + Out_Buffer : Stream_Element_Array + (1 .. Stream_Element_Offset (Out_Buffer_Size)); + Last : Stream_Element_Offset; + In_Last : Stream_Element_Offset; + In_First : Stream_Element_Offset; + Out_Last : Stream_Element_Offset; + begin + Main : loop + Data_In (In_Buffer, Last); + + In_First := In_Buffer'First; + + loop + Translate + (Filter => Filter, + In_Data => In_Buffer (In_First .. Last), + In_Last => In_Last, + Out_Data => Out_Buffer, + Out_Last => Out_Last, + Flush => Flush_Finish (Last < In_Buffer'First)); + + if Out_Buffer'First <= Out_Last then + Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last)); + end if; + + exit Main when Stream_End (Filter); + + -- The end of in buffer. + + exit when In_Last = Last; + + In_First := In_Last + 1; + end loop; + end loop Main; + + end Generic_Translate; + + ------------------ + -- Inflate_Init -- + ------------------ + + procedure Inflate_Init + (Filter : in out Filter_Type; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Header : in Header_Type := Default) + is + use type Thin.Int; + Win_Bits : Thin.Int := Thin.Int (Window_Bits); + + procedure Check_Version; + -- Check the latest header types compatibility. + + procedure Check_Version is + begin + if Version <= "1.1.4" then + Raise_Error + ("Inflate header type " & Header_Type'Image (Header) + & " incompatible with ZLib version " & Version); + end if; + end Check_Version; + + begin + if Is_Open (Filter) then + raise Status_Error; + end if; + + case Header is + when None => + Check_Version; + + -- Inflate data without headers determined + -- by negative Win_Bits. + + Win_Bits := -Win_Bits; + when GZip => + Check_Version; + + -- Inflate gzip data defined by flag 16. + + Win_Bits := Win_Bits + 16; + when Auto => + Check_Version; + + -- Inflate with automatic detection + -- of gzip or native header defined by flag 32. + + Win_Bits := Win_Bits + 32; + when Default => null; + end case; + + Filter.Strm := new Z_Stream; + Filter.Compression := False; + Filter.Stream_End := False; + Filter.Header := Header; + + if Thin.Inflate_Init + (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK + then + Raise_Error (Filter.Strm.all); + end if; + end Inflate_Init; + + ------------- + -- Is_Open -- + ------------- + + function Is_Open (Filter : in Filter_Type) return Boolean is + begin + return Filter.Strm /= null; + end Is_Open; + + ----------------- + -- Raise_Error -- + ----------------- + + procedure Raise_Error (Message : in String) is + begin + Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message); + end Raise_Error; + + procedure Raise_Error (Stream : in Z_Stream) is + begin + Raise_Error (Last_Error_Message (Stream)); + end Raise_Error; + + ---------- + -- Read -- + ---------- + + procedure Read + (Filter : in out Filter_Type; + Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode := No_Flush) + is + In_Last : Stream_Element_Offset; + Item_First : Ada.Streams.Stream_Element_Offset := Item'First; + V_Flush : Flush_Mode := Flush; + + begin + pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1); + pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last); + + loop + if Rest_Last = Buffer'First - 1 then + V_Flush := Finish; + + elsif Rest_First > Rest_Last then + Read (Buffer, Rest_Last); + Rest_First := Buffer'First; + + if Rest_Last < Buffer'First then + V_Flush := Finish; + end if; + end if; + + Translate + (Filter => Filter, + In_Data => Buffer (Rest_First .. Rest_Last), + In_Last => In_Last, + Out_Data => Item (Item_First .. Item'Last), + Out_Last => Last, + Flush => V_Flush); + + Rest_First := In_Last + 1; + + exit when Stream_End (Filter) + or else Last = Item'Last + or else (Last >= Item'First and then Allow_Read_Some); + + Item_First := Last + 1; + end loop; + end Read; + + ---------------- + -- Stream_End -- + ---------------- + + function Stream_End (Filter : in Filter_Type) return Boolean is + begin + if Filter.Header = GZip and Filter.Compression then + return Filter.Stream_End + and then Filter.Offset = Footer_Array'Last + 1; + else + return Filter.Stream_End; + end if; + end Stream_End; + + -------------- + -- Total_In -- + -------------- + + function Total_In (Filter : in Filter_Type) return Count is + begin + return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all)); + end Total_In; + + --------------- + -- Total_Out -- + --------------- + + function Total_Out (Filter : in Filter_Type) return Count is + begin + return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all)); + end Total_Out; + + --------------- + -- Translate -- + --------------- + + procedure Translate + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) is + begin + if Filter.Header = GZip and then Filter.Compression then + Translate_GZip + (Filter => Filter, + In_Data => In_Data, + In_Last => In_Last, + Out_Data => Out_Data, + Out_Last => Out_Last, + Flush => Flush); + else + Translate_Auto + (Filter => Filter, + In_Data => In_Data, + In_Last => In_Last, + Out_Data => Out_Data, + Out_Last => Out_Last, + Flush => Flush); + end if; + end Translate; + + -------------------- + -- Translate_Auto -- + -------------------- + + procedure Translate_Auto + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) + is + use type Thin.Int; + Code : Thin.Int; + + begin + if not Is_Open (Filter) then + raise Status_Error; + end if; + + if Out_Data'Length = 0 and then In_Data'Length = 0 then + raise Constraint_Error; + end if; + + Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length); + Set_In (Filter.Strm.all, In_Data'Address, In_Data'Length); + + Code := Flate (Filter.Compression).Step + (To_Thin_Access (Filter.Strm), + Thin.Int (Flush)); + + if Code = Thin.Z_STREAM_END then + Filter.Stream_End := True; + else + Check_Error (Filter.Strm.all, Code); + end if; + + In_Last := In_Data'Last + - Stream_Element_Offset (Avail_In (Filter.Strm.all)); + Out_Last := Out_Data'Last + - Stream_Element_Offset (Avail_Out (Filter.Strm.all)); + end Translate_Auto; + + -------------------- + -- Translate_GZip -- + -------------------- + + procedure Translate_GZip + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) + is + Out_First : Stream_Element_Offset; + + procedure Add_Data (Data : in Stream_Element_Array); + -- Add data to stream from the Filter.Offset till necessary, + -- used for add gzip headr/footer. + + procedure Put_32 + (Item : in out Stream_Element_Array; + Data : in Unsigned_32); + pragma Inline (Put_32); + + -------------- + -- Add_Data -- + -------------- + + procedure Add_Data (Data : in Stream_Element_Array) is + Data_First : Stream_Element_Offset renames Filter.Offset; + Data_Last : Stream_Element_Offset; + Data_Len : Stream_Element_Offset; -- -1 + Out_Len : Stream_Element_Offset; -- -1 + begin + Out_First := Out_Last + 1; + + if Data_First > Data'Last then + return; + end if; + + Data_Len := Data'Last - Data_First; + Out_Len := Out_Data'Last - Out_First; + + if Data_Len <= Out_Len then + Out_Last := Out_First + Data_Len; + Data_Last := Data'Last; + else + Out_Last := Out_Data'Last; + Data_Last := Data_First + Out_Len; + end if; + + Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last); + + Data_First := Data_Last + 1; + Out_First := Out_Last + 1; + end Add_Data; + + ------------ + -- Put_32 -- + ------------ + + procedure Put_32 + (Item : in out Stream_Element_Array; + Data : in Unsigned_32) + is + D : Unsigned_32 := Data; + begin + for J in Item'First .. Item'First + 3 loop + Item (J) := Stream_Element (D and 16#FF#); + D := Shift_Right (D, 8); + end loop; + end Put_32; + + begin + Out_Last := Out_Data'First - 1; + + if not Filter.Stream_End then + Add_Data (Simple_GZip_Header); + + Translate_Auto + (Filter => Filter, + In_Data => In_Data, + In_Last => In_Last, + Out_Data => Out_Data (Out_First .. Out_Data'Last), + Out_Last => Out_Last, + Flush => Flush); + + CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last)); + end if; + + if Filter.Stream_End and then Out_Last <= Out_Data'Last then + -- This detection method would work only when + -- Simple_GZip_Header'Last > Footer_Array'Last + + if Filter.Offset = Simple_GZip_Header'Last + 1 then + Filter.Offset := Footer_Array'First; + end if; + + declare + Footer : Footer_Array; + begin + Put_32 (Footer, Filter.CRC); + Put_32 (Footer (Footer'First + 4 .. Footer'Last), + Unsigned_32 (Total_In (Filter))); + Add_Data (Footer); + end; + end if; + end Translate_GZip; + + ------------- + -- Version -- + ------------- + + function Version return String is + begin + return Interfaces.C.Strings.Value (Thin.zlibVersion); + end Version; + + ----------- + -- Write -- + ----------- + + procedure Write + (Filter : in out Filter_Type; + Item : in Ada.Streams.Stream_Element_Array; + Flush : in Flush_Mode := No_Flush) + is + Buffer : Stream_Element_Array (1 .. Buffer_Size); + In_Last : Stream_Element_Offset; + Out_Last : Stream_Element_Offset; + In_First : Stream_Element_Offset := Item'First; + begin + if Item'Length = 0 and Flush = No_Flush then + return; + end if; + + loop + Translate + (Filter => Filter, + In_Data => Item (In_First .. Item'Last), + In_Last => In_Last, + Out_Data => Buffer, + Out_Last => Out_Last, + Flush => Flush); + + if Out_Last >= Buffer'First then + Write (Buffer (1 .. Out_Last)); + end if; + + exit when In_Last = Item'Last or Stream_End (Filter); + + In_First := In_Last + 1; + end loop; + end Write; + +end ZLib; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib.ads b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib.ads new file mode 100644 index 00000000..79ffc409 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib.ads @@ -0,0 +1,328 @@ +------------------------------------------------------------------------------ +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- This library is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU General Public License as published by -- +-- the Free Software Foundation; either version 2 of the License, or (at -- +-- your option) any later version. -- +-- -- +-- This library is distributed in the hope that it will be useful, but -- +-- WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- +-- General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU General Public License -- +-- along with this library; if not, write to the Free Software Foundation, -- +-- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- +-- -- +-- As a special exception, if other files instantiate generics from this -- +-- unit, or you link this unit with other files to produce an executable, -- +-- this unit does not by itself cause the resulting executable to be -- +-- covered by the GNU General Public License. This exception does not -- +-- however invalidate any other reasons why the executable file might be -- +-- covered by the GNU Public License. -- +------------------------------------------------------------------------------ + +-- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $ + +with Ada.Streams; + +with Interfaces; + +package ZLib is + + ZLib_Error : exception; + Status_Error : exception; + + type Compression_Level is new Integer range -1 .. 9; + + type Flush_Mode is private; + + type Compression_Method is private; + + type Window_Bits_Type is new Integer range 8 .. 15; + + type Memory_Level_Type is new Integer range 1 .. 9; + + type Unsigned_32 is new Interfaces.Unsigned_32; + + type Strategy_Type is private; + + type Header_Type is (None, Auto, Default, GZip); + -- Header type usage have a some limitation for inflate. + -- See comment for Inflate_Init. + + subtype Count is Ada.Streams.Stream_Element_Count; + + Default_Memory_Level : constant Memory_Level_Type := 8; + Default_Window_Bits : constant Window_Bits_Type := 15; + + ---------------------------------- + -- Compression method constants -- + ---------------------------------- + + Deflated : constant Compression_Method; + -- Only one method allowed in this ZLib version + + --------------------------------- + -- Compression level constants -- + --------------------------------- + + No_Compression : constant Compression_Level := 0; + Best_Speed : constant Compression_Level := 1; + Best_Compression : constant Compression_Level := 9; + Default_Compression : constant Compression_Level := -1; + + -------------------------- + -- Flush mode constants -- + -------------------------- + + No_Flush : constant Flush_Mode; + -- Regular way for compression, no flush + + Partial_Flush : constant Flush_Mode; + -- Will be removed, use Z_SYNC_FLUSH instead + + Sync_Flush : constant Flush_Mode; + -- All pending output is flushed to the output buffer and the output + -- is aligned on a byte boundary, so that the decompressor can get all + -- input data available so far. (In particular avail_in is zero after the + -- call if enough output space has been provided before the call.) + -- Flushing may degrade compression for some compression algorithms and so + -- it should be used only when necessary. + + Block_Flush : constant Flush_Mode; + -- Z_BLOCK requests that inflate() stop + -- if and when it get to the next deflate block boundary. When decoding the + -- zlib or gzip format, this will cause inflate() to return immediately + -- after the header and before the first block. When doing a raw inflate, + -- inflate() will go ahead and process the first block, and will return + -- when it gets to the end of that block, or when it runs out of data. + + Full_Flush : constant Flush_Mode; + -- All output is flushed as with SYNC_FLUSH, and the compression state + -- is reset so that decompression can restart from this point if previous + -- compressed data has been damaged or if random access is desired. Using + -- Full_Flush too often can seriously degrade the compression. + + Finish : constant Flush_Mode; + -- Just for tell the compressor that input data is complete. + + ------------------------------------ + -- Compression strategy constants -- + ------------------------------------ + + -- RLE stategy could be used only in version 1.2.0 and later. + + Filtered : constant Strategy_Type; + Huffman_Only : constant Strategy_Type; + RLE : constant Strategy_Type; + Default_Strategy : constant Strategy_Type; + + Default_Buffer_Size : constant := 4096; + + type Filter_Type is tagged limited private; + -- The filter is for compression and for decompression. + -- The usage of the type is depend of its initialization. + + function Version return String; + pragma Inline (Version); + -- Return string representation of the ZLib version. + + procedure Deflate_Init + (Filter : in out Filter_Type; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Method : in Compression_Method := Deflated; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Memory_Level : in Memory_Level_Type := Default_Memory_Level; + Header : in Header_Type := Default); + -- Compressor initialization. + -- When Header parameter is Auto or Default, then default zlib header + -- would be provided for compressed data. + -- When Header is GZip, then gzip header would be set instead of + -- default header. + -- When Header is None, no header would be set for compressed data. + + procedure Inflate_Init + (Filter : in out Filter_Type; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Header : in Header_Type := Default); + -- Decompressor initialization. + -- Default header type mean that ZLib default header is expecting in the + -- input compressed stream. + -- Header type None mean that no header is expecting in the input stream. + -- GZip header type mean that GZip header is expecting in the + -- input compressed stream. + -- Auto header type mean that header type (GZip or Native) would be + -- detected automatically in the input stream. + -- Note that header types parameter values None, GZip and Auto are + -- supported for inflate routine only in ZLib versions 1.2.0.2 and later. + -- Deflate_Init is supporting all header types. + + function Is_Open (Filter : in Filter_Type) return Boolean; + pragma Inline (Is_Open); + -- Is the filter opened for compression or decompression. + + procedure Close + (Filter : in out Filter_Type; + Ignore_Error : in Boolean := False); + -- Closing the compression or decompressor. + -- If stream is closing before the complete and Ignore_Error is False, + -- The exception would be raised. + + generic + with procedure Data_In + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + with procedure Data_Out + (Item : in Ada.Streams.Stream_Element_Array); + procedure Generic_Translate + (Filter : in out Filter_Type; + In_Buffer_Size : in Integer := Default_Buffer_Size; + Out_Buffer_Size : in Integer := Default_Buffer_Size); + -- Compress/decompress data fetch from Data_In routine and pass the result + -- to the Data_Out routine. User should provide Data_In and Data_Out + -- for compression/decompression data flow. + -- Compression or decompression depend on Filter initialization. + + function Total_In (Filter : in Filter_Type) return Count; + pragma Inline (Total_In); + -- Returns total number of input bytes read so far + + function Total_Out (Filter : in Filter_Type) return Count; + pragma Inline (Total_Out); + -- Returns total number of bytes output so far + + function CRC32 + (CRC : in Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array) + return Unsigned_32; + pragma Inline (CRC32); + -- Compute CRC32, it could be necessary for make gzip format + + procedure CRC32 + (CRC : in out Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array); + pragma Inline (CRC32); + -- Compute CRC32, it could be necessary for make gzip format + + ------------------------------------------------- + -- Below is more complex low level routines. -- + ------------------------------------------------- + + procedure Translate + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + -- Compress/decompress the In_Data buffer and place the result into + -- Out_Data. In_Last is the index of last element from In_Data accepted by + -- the Filter. Out_Last is the last element of the received data from + -- Filter. To tell the filter that incoming data are complete put the + -- Flush parameter to Finish. + + function Stream_End (Filter : in Filter_Type) return Boolean; + pragma Inline (Stream_End); + -- Return the true when the stream is complete. + + procedure Flush + (Filter : in out Filter_Type; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + pragma Inline (Flush); + -- Flushing the data from the compressor. + + generic + with procedure Write + (Item : in Ada.Streams.Stream_Element_Array); + -- User should provide this routine for accept + -- compressed/decompressed data. + + Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size; + -- Buffer size for Write user routine. + + procedure Write + (Filter : in out Filter_Type; + Item : in Ada.Streams.Stream_Element_Array; + Flush : in Flush_Mode := No_Flush); + -- Compress/Decompress data from Item to the generic parameter procedure + -- Write. Output buffer size could be set in Buffer_Size generic parameter. + + generic + with procedure Read + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + -- User should provide data for compression/decompression + -- thru this routine. + + Buffer : in out Ada.Streams.Stream_Element_Array; + -- Buffer for keep remaining data from the previous + -- back read. + + Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset; + -- Rest_First have to be initialized to Buffer'Last + 1 + -- Rest_Last have to be initialized to Buffer'Last + -- before usage. + + Allow_Read_Some : in Boolean := False; + -- Is it allowed to return Last < Item'Last before end of data. + + procedure Read + (Filter : in out Filter_Type; + Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode := No_Flush); + -- Compress/Decompress data from generic parameter procedure Read to the + -- Item. User should provide Buffer and initialized Rest_First, Rest_Last + -- indicators. If Allow_Read_Some is True, Read routines could return + -- Last < Item'Last only at end of stream. + +private + + use Ada.Streams; + + pragma Assert (Ada.Streams.Stream_Element'Size = 8); + pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8); + + type Flush_Mode is new Integer range 0 .. 5; + + type Compression_Method is new Integer range 8 .. 8; + + type Strategy_Type is new Integer range 0 .. 3; + + No_Flush : constant Flush_Mode := 0; + Partial_Flush : constant Flush_Mode := 1; + Sync_Flush : constant Flush_Mode := 2; + Full_Flush : constant Flush_Mode := 3; + Finish : constant Flush_Mode := 4; + Block_Flush : constant Flush_Mode := 5; + + Filtered : constant Strategy_Type := 1; + Huffman_Only : constant Strategy_Type := 2; + RLE : constant Strategy_Type := 3; + Default_Strategy : constant Strategy_Type := 0; + + Deflated : constant Compression_Method := 8; + + type Z_Stream; + + type Z_Stream_Access is access all Z_Stream; + + type Filter_Type is tagged limited record + Strm : Z_Stream_Access; + Compression : Boolean; + Stream_End : Boolean; + Header : Header_Type; + CRC : Unsigned_32; + Offset : Stream_Element_Offset; + -- Offset for gzip header/footer output. + end record; + +end ZLib; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib.gpr b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib.gpr new file mode 100644 index 00000000..296b22aa --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/ada/zlib.gpr @@ -0,0 +1,20 @@ +project Zlib is + + for Languages use ("Ada"); + for Source_Dirs use ("."); + for Object_Dir use "."; + for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo"); + + package Compiler is + for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst"); + end Compiler; + + package Linker is + for Default_Switches ("ada") use ("-lz"); + end Linker; + + package Builder is + for Default_Switches ("ada") use ("-s", "-gnatQ"); + end Builder; + +end Zlib; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/amd64/amd64-match.S b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/amd64/amd64-match.S new file mode 100644 index 00000000..81d4a1c9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/amd64/amd64-match.S @@ -0,0 +1,452 @@ +/* + * match.S -- optimized version of longest_match() + * based on the similar work by Gilles Vollant, and Brian Raiter, written 1998 + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the BSD License. Use by owners of Che Guevarra + * parafernalia is prohibited, where possible, and highly discouraged + * elsewhere. + */ + +#ifndef NO_UNDERLINE +# define match_init _match_init +# define longest_match _longest_match +#endif + +#define scanend ebx +#define scanendw bx +#define chainlenwmask edx /* high word: current chain len low word: s->wmask */ +#define curmatch rsi +#define curmatchd esi +#define windowbestlen r8 +#define scanalign r9 +#define scanalignd r9d +#define window r10 +#define bestlen r11 +#define bestlend r11d +#define scanstart r12d +#define scanstartw r12w +#define scan r13 +#define nicematch r14d +#define limit r15 +#define limitd r15d +#define prev rcx + +/* + * The 258 is a "magic number, not a parameter -- changing it + * breaks the hell loose + */ +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ +#define LocalVarsSize (112) +#define _chainlenwmask ( 8-LocalVarsSize)(%rsp) +#define _windowbestlen (16-LocalVarsSize)(%rsp) +#define save_r14 (24-LocalVarsSize)(%rsp) +#define save_rsi (32-LocalVarsSize)(%rsp) +#define save_rbx (40-LocalVarsSize)(%rsp) +#define save_r12 (56-LocalVarsSize)(%rsp) +#define save_r13 (64-LocalVarsSize)(%rsp) +#define save_r15 (80-LocalVarsSize)(%rsp) + + +.globl match_init, longest_match + +/* + * On AMD64 the first argument of a function (in our case -- the pointer to + * deflate_state structure) is passed in %rdi, hence our offsets below are + * all off of that. + */ + +/* you can check the structure offset by running + +#include +#include +#include "deflate.h" + +void print_depl() +{ +deflate_state ds; +deflate_state *s=&ds; +printf("size pointer=%u\n",(int)sizeof(void*)); + +printf("#define dsWSize (%3u)(%%rdi)\n",(int)(((char*)&(s->w_size))-((char*)s))); +printf("#define dsWMask (%3u)(%%rdi)\n",(int)(((char*)&(s->w_mask))-((char*)s))); +printf("#define dsWindow (%3u)(%%rdi)\n",(int)(((char*)&(s->window))-((char*)s))); +printf("#define dsPrev (%3u)(%%rdi)\n",(int)(((char*)&(s->prev))-((char*)s))); +printf("#define dsMatchLen (%3u)(%%rdi)\n",(int)(((char*)&(s->match_length))-((char*)s))); +printf("#define dsPrevMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_match))-((char*)s))); +printf("#define dsStrStart (%3u)(%%rdi)\n",(int)(((char*)&(s->strstart))-((char*)s))); +printf("#define dsMatchStart (%3u)(%%rdi)\n",(int)(((char*)&(s->match_start))-((char*)s))); +printf("#define dsLookahead (%3u)(%%rdi)\n",(int)(((char*)&(s->lookahead))-((char*)s))); +printf("#define dsPrevLen (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_length))-((char*)s))); +printf("#define dsMaxChainLen (%3u)(%%rdi)\n",(int)(((char*)&(s->max_chain_length))-((char*)s))); +printf("#define dsGoodMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->good_match))-((char*)s))); +printf("#define dsNiceMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->nice_match))-((char*)s))); +} + +*/ + + +/* + to compile for XCode 3.2 on MacOSX x86_64 + - run "gcc -g -c -DXCODE_MAC_X64_STRUCTURE amd64-match.S" + */ + + +#ifndef CURRENT_LINX_XCODE_MAC_X64_STRUCTURE +#define dsWSize ( 68)(%rdi) +#define dsWMask ( 76)(%rdi) +#define dsWindow ( 80)(%rdi) +#define dsPrev ( 96)(%rdi) +#define dsMatchLen (144)(%rdi) +#define dsPrevMatch (148)(%rdi) +#define dsStrStart (156)(%rdi) +#define dsMatchStart (160)(%rdi) +#define dsLookahead (164)(%rdi) +#define dsPrevLen (168)(%rdi) +#define dsMaxChainLen (172)(%rdi) +#define dsGoodMatch (188)(%rdi) +#define dsNiceMatch (192)(%rdi) + +#else + +#ifndef STRUCT_OFFSET +# define STRUCT_OFFSET (0) +#endif + + +#define dsWSize ( 56 + STRUCT_OFFSET)(%rdi) +#define dsWMask ( 64 + STRUCT_OFFSET)(%rdi) +#define dsWindow ( 72 + STRUCT_OFFSET)(%rdi) +#define dsPrev ( 88 + STRUCT_OFFSET)(%rdi) +#define dsMatchLen (136 + STRUCT_OFFSET)(%rdi) +#define dsPrevMatch (140 + STRUCT_OFFSET)(%rdi) +#define dsStrStart (148 + STRUCT_OFFSET)(%rdi) +#define dsMatchStart (152 + STRUCT_OFFSET)(%rdi) +#define dsLookahead (156 + STRUCT_OFFSET)(%rdi) +#define dsPrevLen (160 + STRUCT_OFFSET)(%rdi) +#define dsMaxChainLen (164 + STRUCT_OFFSET)(%rdi) +#define dsGoodMatch (180 + STRUCT_OFFSET)(%rdi) +#define dsNiceMatch (184 + STRUCT_OFFSET)(%rdi) + +#endif + + + + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ + +longest_match: +/* + * Retrieve the function arguments. %curmatch will hold cur_match + * throughout the entire function (passed via rsi on amd64). + * rdi will hold the pointer to the deflate_state (first arg on amd64) + */ + mov %rsi, save_rsi + mov %rbx, save_rbx + mov %r12, save_r12 + mov %r13, save_r13 + mov %r14, save_r14 + mov %r15, save_r15 + +/* uInt wmask = s->w_mask; */ +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen, %eax + movl dsGoodMatch, %ebx + cmpl %ebx, %eax + movl dsWMask, %eax + movl dsMaxChainLen, %chainlenwmask + jl LastMatchGood + shrl $2, %chainlenwmask +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the wmask */ +/* value, which it will always accompany. */ + + decl %chainlenwmask + shll $16, %chainlenwmask + orl %eax, %chainlenwmask + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch, %eax + movl dsLookahead, %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, %nicematch + +/* register Bytef *scan = s->window + s->strstart; */ + + mov dsWindow, %window + movl dsStrStart, %limitd + lea (%limit, %window), %scan + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + mov %scan, %scanalign + negl %scanalignd + andl $3, %scanalignd + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize, %eax + subl $MIN_LOOKAHEAD, %eax + xorl %ecx, %ecx + subl %eax, %limitd + cmovng %ecx, %limitd + +/* int best_len = s->prev_length; */ + + movl dsPrevLen, %bestlend + +/* Store the sum of s->window + best_len in %windowbestlen locally, and in memory. */ + + lea (%window, %bestlen), %windowbestlen + mov %windowbestlen, _windowbestlen + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ +/* Posf *prev = s->prev; */ + + movzwl (%scan), %scanstart + movzwl -1(%scan, %bestlen), %scanend + mov dsPrev, %prev + +/* Jump into the main loop. */ + + movl %chainlenwmask, _chainlenwmask + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + */ +LookupLoop: + andl %chainlenwmask, %curmatchd + movzwl (%prev, %curmatch, 2), %curmatchd + cmpl %limitd, %curmatchd + jbe LeaveNow + subl $0x00010000, %chainlenwmask + js LeaveNow +LoopEntry: cmpw -1(%windowbestlen, %curmatch), %scanendw + jne LookupLoop + cmpw %scanstartw, (%window, %curmatch) + jne LookupLoop + +/* Store the current value of chainlen. */ + movl %chainlenwmask, _chainlenwmask + +/* %scan is the string under scrutiny, and %prev to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + mov $(-MAX_MATCH_8), %rdx + lea (%curmatch, %window), %windowbestlen + lea MAX_MATCH_8(%windowbestlen, %scanalign), %windowbestlen + lea MAX_MATCH_8(%scan, %scanalign), %prev + +/* the prefetching below makes very little difference... */ + prefetcht1 (%windowbestlen, %rdx) + prefetcht1 (%prev, %rdx) + +/* + * Test the strings for equality, 8 bytes at a time. At the end, + * adjust %rdx so that it is offset to the exact byte that mismatched. + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance -- unrolling it, for example, makes no difference. + */ + +#undef USE_SSE /* works, but is 6-7% slower, than non-SSE... */ + +LoopCmps: +#ifdef USE_SSE + /* Preload the SSE registers */ + movdqu (%windowbestlen, %rdx), %xmm1 + movdqu (%prev, %rdx), %xmm2 + pcmpeqb %xmm2, %xmm1 + movdqu 16(%windowbestlen, %rdx), %xmm3 + movdqu 16(%prev, %rdx), %xmm4 + pcmpeqb %xmm4, %xmm3 + movdqu 32(%windowbestlen, %rdx), %xmm5 + movdqu 32(%prev, %rdx), %xmm6 + pcmpeqb %xmm6, %xmm5 + movdqu 48(%windowbestlen, %rdx), %xmm7 + movdqu 48(%prev, %rdx), %xmm8 + pcmpeqb %xmm8, %xmm7 + + /* Check the comparisions' results */ + pmovmskb %xmm1, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + /* this is the only iteration of the loop with a possibility of having + incremented rdx by 0x108 (each loop iteration add 16*4 = 0x40 + and (0x40*4)+8=0x108 */ + add $8, %rdx + jz LenMaximum + add $8, %rdx + + + pmovmskb %xmm3, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + + add $16, %rdx + + + pmovmskb %xmm5, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + add $16, %rdx + + + pmovmskb %xmm7, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + add $16, %rdx + + jmp LoopCmps +LeaveLoopCmps: add %rax, %rdx +#else + mov (%windowbestlen, %rdx), %rax + xor (%prev, %rdx), %rax + jnz LeaveLoopCmps + + mov 8(%windowbestlen, %rdx), %rax + xor 8(%prev, %rdx), %rax + jnz LeaveLoopCmps8 + + mov 16(%windowbestlen, %rdx), %rax + xor 16(%prev, %rdx), %rax + jnz LeaveLoopCmps16 + + add $24, %rdx + jnz LoopCmps + jmp LenMaximum +# if 0 +/* + * This three-liner is tantalizingly simple, but bsf is a slow instruction, + * and the complicated alternative down below is quite a bit faster. Sad... + */ + +LeaveLoopCmps: bsf %rax, %rax /* find the first non-zero bit */ + shrl $3, %eax /* divide by 8 to get the byte */ + add %rax, %rdx +# else +LeaveLoopCmps16: + add $8, %rdx +LeaveLoopCmps8: + add $8, %rdx +LeaveLoopCmps: testl $0xFFFFFFFF, %eax /* Check the first 4 bytes */ + jnz Check16 + add $4, %rdx + shr $32, %rax +Check16: testw $0xFFFF, %ax + jnz LenLower + add $2, %rdx + shrl $16, %eax +LenLower: subb $1, %al + adc $0, %rdx +# endif +#endif + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%prev, %rdx), %rax + sub %scan, %rax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + cmpl %bestlend, %eax + jg LongerMatch + mov _windowbestlen, %windowbestlen + mov dsPrev, %prev + movl _chainlenwmask, %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: + movl %eax, %bestlend + movl %curmatchd, dsMatchStart + cmpl %nicematch, %eax + jge LeaveNow + + lea (%window, %bestlen), %windowbestlen + mov %windowbestlen, _windowbestlen + + movzwl -1(%scan, %rax), %scanend + mov dsPrev, %prev + movl _chainlenwmask, %chainlenwmask + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: + movl $MAX_MATCH, %bestlend + movl %curmatchd, dsMatchStart + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl dsLookahead, %eax + cmpl %eax, %bestlend + cmovngl %bestlend, %eax +LookaheadRet: + +/* Restore the registers and return from whence we came. */ + + mov save_rsi, %rsi + mov save_rbx, %rbx + mov save_r12, %r12 + mov save_r13, %r13 + mov save_r14, %r14 + mov save_r15, %r15 + + ret + +match_init: ret diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/bndsrc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/bndsrc new file mode 100644 index 00000000..d048dbb7 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/bndsrc @@ -0,0 +1,206 @@ +STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB') + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.1.3 entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +/********************************************************************/ +/* *MODULE ADLER32 ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("adler32") + +/********************************************************************/ +/* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("compress") + EXPORT SYMBOL("compress2") + +/********************************************************************/ +/* *MODULE CRC32 ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("crc32") + EXPORT SYMBOL("get_crc_table") + +/********************************************************************/ +/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("deflate") + EXPORT SYMBOL("deflateEnd") + EXPORT SYMBOL("deflateSetDictionary") + EXPORT SYMBOL("deflateCopy") + EXPORT SYMBOL("deflateReset") + EXPORT SYMBOL("deflateParams") + EXPORT SYMBOL("deflatePrime") + EXPORT SYMBOL("deflateInit_") + EXPORT SYMBOL("deflateInit2_") + +/********************************************************************/ +/* *MODULE GZIO ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("gzopen") + EXPORT SYMBOL("gzdopen") + EXPORT SYMBOL("gzsetparams") + EXPORT SYMBOL("gzread") + EXPORT SYMBOL("gzwrite") + EXPORT SYMBOL("gzprintf") + EXPORT SYMBOL("gzputs") + EXPORT SYMBOL("gzgets") + EXPORT SYMBOL("gzputc") + EXPORT SYMBOL("gzgetc") + EXPORT SYMBOL("gzflush") + EXPORT SYMBOL("gzseek") + EXPORT SYMBOL("gzrewind") + EXPORT SYMBOL("gztell") + EXPORT SYMBOL("gzeof") + EXPORT SYMBOL("gzclose") + EXPORT SYMBOL("gzerror") + +/********************************************************************/ +/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("inflate") + EXPORT SYMBOL("inflateEnd") + EXPORT SYMBOL("inflateSetDictionary") + EXPORT SYMBOL("inflateSync") + EXPORT SYMBOL("inflateReset") + EXPORT SYMBOL("inflateInit_") + EXPORT SYMBOL("inflateInit2_") + EXPORT SYMBOL("inflateSyncPoint") + +/********************************************************************/ +/* *MODULE UNCOMPR ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("uncompress") + +/********************************************************************/ +/* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("zlibVersion") + EXPORT SYMBOL("zError") + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.2.1 additional entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +/********************************************************************/ +/* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("compressBound") + +/********************************************************************/ +/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("deflateBound") + +/********************************************************************/ +/* *MODULE GZIO ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("gzungetc") + EXPORT SYMBOL("gzclearerr") + +/********************************************************************/ +/* *MODULE INFBACK ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("inflateBack") + EXPORT SYMBOL("inflateBackEnd") + EXPORT SYMBOL("inflateBackInit_") + +/********************************************************************/ +/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("inflateCopy") + +/********************************************************************/ +/* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("zlibCompileFlags") + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.2.5 additional entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +/********************************************************************/ +/* *MODULE ADLER32 ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("adler32_combine") + EXPORT SYMBOL("adler32_combine64") + +/********************************************************************/ +/* *MODULE CRC32 ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("crc32_combine") + EXPORT SYMBOL("crc32_combine64") + +/********************************************************************/ +/* *MODULE GZLIB ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("gzbuffer") + EXPORT SYMBOL("gzoffset") + EXPORT SYMBOL("gzoffset64") + EXPORT SYMBOL("gzopen64") + EXPORT SYMBOL("gzseek64") + EXPORT SYMBOL("gztell64") + +/********************************************************************/ +/* *MODULE GZREAD ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("gzclose_r") + +/********************************************************************/ +/* *MODULE GZWRITE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("gzclose_w") + +/********************************************************************/ +/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("inflateMark") + EXPORT SYMBOL("inflatePrime") + EXPORT SYMBOL("inflateReset2") + EXPORT SYMBOL("inflateUndermine") + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.2.6 additional entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +/********************************************************************/ +/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("deflateResetKeep") + EXPORT SYMBOL("deflatePending") + +/********************************************************************/ +/* *MODULE GZWRITE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("gzgetc_") + EXPORT SYMBOL("gzflags") + +/********************************************************************/ +/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("inflateResetKeep") + +ENDPGMEXP diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/compile.clp b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/compile.clp new file mode 100644 index 00000000..ed96ad49 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/compile.clp @@ -0,0 +1,110 @@ +/******************************************************************************/ +/* */ +/* ZLIB */ +/* */ +/* Compile sources into modules and link them into a service program. */ +/* */ +/******************************************************************************/ + + PGM + +/* Configuration adjustable parameters. */ + + DCL VAR(&SRCLIB) TYPE(*CHAR) LEN(10) + + VALUE('ZLIB') /* Source library. */ + DCL VAR(&SRCFILE) TYPE(*CHAR) LEN(10) + + VALUE('SOURCES') /* Source member file. */ + DCL VAR(&CTLFILE) TYPE(*CHAR) LEN(10) + + VALUE('TOOLS') /* Control member file. */ + + DCL VAR(&MODLIB) TYPE(*CHAR) LEN(10) + + VALUE('ZLIB') /* Module library. */ + + DCL VAR(&SRVLIB) TYPE(*CHAR) LEN(10) + + VALUE('LGPL') /* Service program library. */ + + DCL VAR(&CFLAGS) TYPE(*CHAR) + + VALUE('OPTIMIZE(40)') /* Compile options. */ + + DCL VAR(&TGTRLS) TYPE(*CHAR) + + VALUE('V5R3M0') /* Target release. */ + + +/* Working storage. */ + + DCL VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300) /* Command length. */ + DCL VAR(&CMD) TYPE(*CHAR) LEN(512) + DCL VAR(&FIXDCMD) TYPE(*CHAR) LEN(512) + + +/* Compile sources into modules. */ + + CHGVAR VAR(&FIXDCMD) VALUE('CRTCMOD' *BCAT &CFLAGS *BCAT + + 'SYSIFCOPT(*IFS64IO)' *BCAT + + 'DEFINE(''_LARGEFILE64_SOURCE''' *BCAT + + '''_LFS64_LARGEFILE=1'') TGTRLS(' *TCAT &TGTRLS *TCAT + + ') SRCFILE(' *TCAT &SRCLIB *TCAT '/' *TCAT + + &SRCFILE *TCAT ') MODULE(' *TCAT &MODLIB *TCAT '/') + + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ADLER32)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'COMPRESS)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'CRC32)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'DEFLATE)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZCLOSE)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZLIB)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZREAD)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZWRITE)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFBACK)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFFAST)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFLATE)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFTREES)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'TREES)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'UNCOMPR)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ZUTIL)') + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + +/* Link modules into a service program. */ + + CRTSRVPGM SRVPGM(&SRVLIB/ZLIB) + + MODULE(&MODLIB/ADLER32 &MODLIB/COMPRESS + + &MODLIB/CRC32 &MODLIB/DEFLATE + + &MODLIB/GZCLOSE &MODLIB/GZLIB + + &MODLIB/GZREAD &MODLIB/GZWRITE + + &MODLIB/INFBACK &MODLIB/INFFAST + + &MODLIB/INFLATE &MODLIB/INFTREES + + &MODLIB/TREES &MODLIB/UNCOMPR + + &MODLIB/ZUTIL) + + SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) + + TEXT('ZLIB 1.2.6') TGTRLS(&TGTRLS) + + ENDPGM diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/readme.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/readme.txt new file mode 100644 index 00000000..397fe997 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/readme.txt @@ -0,0 +1,115 @@ + ZLIB version 1.2.6 for AS400 installation instructions + +I) From an AS400 *SAVF file: + +1) Unpacking archive to an AS400 save file + +On the AS400: + +_ Create the ZLIB AS400 library: + + CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library') + +_ Create a work save file, for example: + + CRTSAVF FILE(ZLIB/ZLIBSAVF) + +On a PC connected to the target AS400: + +_ Unpack the save file image to a PC file "ZLIBSAVF" +_ Upload this file into the save file on the AS400, for example + using ftp in BINARY mode. + + +2) Populating the ZLIB AS400 source library + +On the AS400: + +_ Extract the saved objects into the ZLIB AS400 library using: + +RSTOBJ OBJ(*ALL) SAVLIB(ZLIB) DEV(*SAVF) SAVF(ZLIB/ZLIBSAVF) RSTLIB(ZLIB) + + +3) Customize installation: + +_ Edit CL member ZLIB/TOOLS(COMPILE) and change parameters if needed, + according to the comments. + +_ Compile this member with: + + CRTCLPGM PGM(ZLIB/COMPILE) SRCFILE(ZLIB/TOOLS) SRCMBR(COMPILE) + + +4) Compile and generate the service program: + +_ This can now be done by executing: + + CALL PGM(ZLIB/COMPILE) + + + +II) From the original source distribution: + +1) On the AS400, create the source library: + + CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library') + +2) Create the source files: + + CRTSRCPF FILE(ZLIB/SOURCES) RCDLEN(112) TEXT('ZLIB library modules') + CRTSRCPF FILE(ZLIB/H) RCDLEN(112) TEXT('ZLIB library includes') + CRTSRCPF FILE(ZLIB/TOOLS) RCDLEN(112) TEXT('ZLIB library control utilities') + +3) From the machine hosting the distribution files, upload them (with + FTP in text mode, for example) according to the following table: + + Original AS400 AS400 AS400 AS400 + file file member type description + SOURCES Original ZLIB C subprogram sources + adler32.c ADLER32 C ZLIB - Compute the Adler-32 checksum of a dta strm + compress.c COMPRESS C ZLIB - Compress a memory buffer + crc32.c CRC32 C ZLIB - Compute the CRC-32 of a data stream + deflate.c DEFLATE C ZLIB - Compress data using the deflation algorithm + gzclose.c GZCLOSE C ZLIB - Close .gz files + gzlib.c GZLIB C ZLIB - Miscellaneous .gz files IO support + gzread.c GZREAD C ZLIB - Read .gz files + gzwrite.c GZWRITE C ZLIB - Write .gz files + infback.c INFBACK C ZLIB - Inflate using a callback interface + inffast.c INFFAST C ZLIB - Fast proc. literals & length/distance pairs + inflate.c INFLATE C ZLIB - Interface to inflate modules + inftrees.c INFTREES C ZLIB - Generate Huffman trees for efficient decode + trees.c TREES C ZLIB - Output deflated data using Huffman coding + uncompr.c UNCOMPR C ZLIB - Decompress a memory buffer + zutil.c ZUTIL C ZLIB - Target dependent utility functions + H Original ZLIB C and ILE/RPG include files + crc32.h CRC32 C ZLIB - CRC32 tables + deflate.h DEFLATE C ZLIB - Internal compression state + gzguts.h GZGUTS C ZLIB - Definitions for the gzclose module + inffast.h INFFAST C ZLIB - Header to use inffast.c + inffixed.h INFFIXED C ZLIB - Table for decoding fixed codes + inflate.h INFLATE C ZLIB - Internal inflate state definitions + inftrees.h INFTREES C ZLIB - Header to use inftrees.c + trees.h TREES C ZLIB - Created automatically with -DGEN_TREES_H + zconf.h ZCONF C ZLIB - Compression library configuration + zlib.h ZLIB C ZLIB - Compression library C user interface + as400/zlib.inc ZLIB.INC RPGLE ZLIB - Compression library ILE RPG user interface + zutil.h ZUTIL C ZLIB - Internal interface and configuration + TOOLS Building source software & AS/400 README + as400/bndsrc BNDSRC Entry point exportation list + as400/compile.clp COMPILE CLP Compile sources & generate service program + as400/readme.txt README TXT Installation instructions + +4) Continue as in I)3). + + + + +Notes: For AS400 ILE RPG programmers, a /copy member defining the ZLIB + API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC). + Please read comments in this member for more information. + + Remember that most foreign textual data are ASCII coded: this + implementation does not handle conversion from/to ASCII, so + text data code conversions must be done explicitely. + + Mainly for the reason above, always open zipped files in binary mode. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/zlib.inc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/zlib.inc new file mode 100644 index 00000000..5ce905fd --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/as400/zlib.inc @@ -0,0 +1,447 @@ + * ZLIB.INC - Interface to the general purpose compression library + * + * ILE RPG400 version by Patrick Monnerat, DATASPHERE. + * Version 1.2.6 + * + * + * WARNING: + * Procedures inflateInit(), inflateInit2(), deflateInit(), + * deflateInit2() and inflateBackInit() need to be called with + * two additional arguments: + * the package version string and the stream control structure. + * size. This is needed because RPG lacks some macro feature. + * Call these procedures as: + * inflateInit(...: ZLIB_VERSION: %size(z_stream)) + * + /if not defined(ZLIB_H_) + /define ZLIB_H_ + * + ************************************************************************** + * Constants + ************************************************************************** + * + * Versioning information. + * + D ZLIB_VERSION C '1.2.6' + D ZLIB_VERNUM C X'1260' + D ZLIB_VER_MAJOR C 1 + D ZLIB_VER_MINOR C 2 + D ZLIB_VER_REVISION... + D C 6 + D ZLIB_VER_SUBREVISION... + D C 0 + * + * Other equates. + * + D Z_NO_FLUSH C 0 + D Z_PARTIAL_FLUSH... + D C 1 + D Z_SYNC_FLUSH C 2 + D Z_FULL_FLUSH C 3 + D Z_FINISH C 4 + D Z_BLOCK C 5 + D Z_TREES C 6 + * + D Z_OK C 0 + D Z_STREAM_END C 1 + D Z_NEED_DICT C 2 + D Z_ERRNO C -1 + D Z_STREAM_ERROR C -2 + D Z_DATA_ERROR C -3 + D Z_MEM_ERROR C -4 + D Z_BUF_ERROR C -5 + DZ_VERSION_ERROR C -6 + * + D Z_NO_COMPRESSION... + D C 0 + D Z_BEST_SPEED C 1 + D Z_BEST_COMPRESSION... + D C 9 + D Z_DEFAULT_COMPRESSION... + D C -1 + * + D Z_FILTERED C 1 + D Z_HUFFMAN_ONLY C 2 + D Z_RLE C 3 + D Z_DEFAULT_STRATEGY... + D C 0 + * + D Z_BINARY C 0 + D Z_ASCII C 1 + D Z_UNKNOWN C 2 + * + D Z_DEFLATED C 8 + * + D Z_NULL C 0 + * + ************************************************************************** + * Types + ************************************************************************** + * + D z_streamp S * Stream struct ptr + D gzFile S * File pointer + D z_off_t S 10i 0 Stream offsets + D z_off64_t S 20i 0 Stream offsets + * + ************************************************************************** + * Structures + ************************************************************************** + * + * The GZIP encode/decode stream support structure. + * + D z_stream DS align based(z_streamp) + D zs_next_in * Next input byte + D zs_avail_in 10U 0 Byte cnt at next_in + D zs_total_in 10U 0 Total bytes read + D zs_next_out * Output buffer ptr + D zs_avail_out 10U 0 Room left @ next_out + D zs_total_out 10U 0 Total bytes written + D zs_msg * Last errmsg or null + D zs_state * Internal state + D zs_zalloc * procptr Int. state allocator + D zs_free * procptr Int. state dealloc. + D zs_opaque * Private alloc. data + D zs_data_type 10i 0 ASC/BIN best guess + D zs_adler 10u 0 Uncompr. adler32 val + D 10U 0 Reserved + D 10U 0 Ptr. alignment + * + ************************************************************************** + * Utility function prototypes + ************************************************************************** + * + D compress PR 10I 0 extproc('compress') + D dest 65535 options(*varsize) Destination buffer + D destLen 10U 0 Destination length + D source 65535 const options(*varsize) Source buffer + D sourceLen 10u 0 value Source length + * + D compress2 PR 10I 0 extproc('compress2') + D dest 65535 options(*varsize) Destination buffer + D destLen 10U 0 Destination length + D source 65535 const options(*varsize) Source buffer + D sourceLen 10U 0 value Source length + D level 10I 0 value Compression level + * + D compressBound PR 10U 0 extproc('compressBound') + D sourceLen 10U 0 value + * + D uncompress PR 10I 0 extproc('uncompress') + D dest 65535 options(*varsize) Destination buffer + D destLen 10U 0 Destination length + D source 65535 const options(*varsize) Source buffer + D sourceLen 10U 0 value Source length + * + /if not defined(LARGE_FILES) + D gzopen PR extproc('gzopen') + D like(gzFile) + D path * value options(*string) File pathname + D mode * value options(*string) Open mode + /else + D gzopen PR extproc('gzopen64') + D like(gzFile) + D path * value options(*string) File pathname + D mode * value options(*string) Open mode + * + D gzopen64 PR extproc('gzopen64') + D like(gzFile) + D path * value options(*string) File pathname + D mode * value options(*string) Open mode + /endif + * + D gzdopen PR extproc('gzdopen') + D like(gzFile) + D fd 10I 0 value File descriptor + D mode * value options(*string) Open mode + * + D gzbuffer PR 10I 0 extproc('gzbuffer') + D file value like(gzFile) File pointer + D size 10U 0 value + * + D gzsetparams PR 10I 0 extproc('gzsetparams') + D file value like(gzFile) File pointer + D level 10I 0 value + D strategy 10I 0 value + * + D gzread PR 10I 0 extproc('gzread') + D file value like(gzFile) File pointer + D buf 65535 options(*varsize) Buffer + D len 10u 0 value Buffer length + * + D gzwrite PR 10I 0 extproc('gzwrite') + D file value like(gzFile) File pointer + D buf 65535 const options(*varsize) Buffer + D len 10u 0 value Buffer length + * + D gzputs PR 10I 0 extproc('gzputs') + D file value like(gzFile) File pointer + D s * value options(*string) String to output + * + D gzgets PR * extproc('gzgets') + D file value like(gzFile) File pointer + D buf 65535 options(*varsize) Read buffer + D len 10i 0 value Buffer length + * + D gzputc PR 10i 0 extproc('gzputc') + D file value like(gzFile) File pointer + D c 10I 0 value Character to write + * + D gzgetc PR 10i 0 extproc('gzgetc') + D file value like(gzFile) File pointer + * + D gzgetc_ PR 10i 0 extproc('gzgetc_') + D file value like(gzFile) File pointer + * + D gzungetc PR 10i 0 extproc('gzungetc') + D c 10I 0 value Character to push + D file value like(gzFile) File pointer + * + D gzflush PR 10i 0 extproc('gzflush') + D file value like(gzFile) File pointer + D flush 10I 0 value Type of flush + * + /if not defined(LARGE_FILES) + D gzseek PR extproc('gzseek') + D like(z_off_t) + D file value like(gzFile) File pointer + D offset value like(z_off_t) Offset + D whence 10i 0 value Origin + /else + D gzseek PR extproc('gzseek64') + D like(z_off_t) + D file value like(gzFile) File pointer + D offset value like(z_off_t) Offset + D whence 10i 0 value Origin + * + D gzseek64 PR extproc('gzseek64') + D like(z_off64_t) + D file value like(gzFile) File pointer + D offset value like(z_off64_t) Offset + D whence 10i 0 value Origin + /endif + * + D gzrewind PR 10i 0 extproc('gzrewind') + D file value like(gzFile) File pointer + * + /if not defined(LARGE_FILES) + D gztell PR extproc('gztell') + D like(z_off_t) + D file value like(gzFile) File pointer + /else + D gztell PR extproc('gztell64') + D like(z_off_t) + D file value like(gzFile) File pointer + * + D gztell64 PR extproc('gztell64') + D like(z_off64_t) + D file value like(gzFile) File pointer + /endif + * + /if not defined(LARGE_FILES) + D gzoffset PR extproc('gzoffset') + D like(z_off_t) + D file value like(gzFile) File pointer + /else + D gzoffset PR extproc('gzoffset64') + D like(z_off_t) + D file value like(gzFile) File pointer + * + D gzoffset64 PR extproc('gzoffset64') + D like(z_off64_t) + D file value like(gzFile) File pointer + /endif + * + D gzeof PR 10i 0 extproc('gzeof') + D file value like(gzFile) File pointer + * + D gzclose_r PR 10i 0 extproc('gzclose_r') + D file value like(gzFile) File pointer + * + D gzclose_w PR 10i 0 extproc('gzclose_w') + D file value like(gzFile) File pointer + * + D gzclose PR 10i 0 extproc('gzclose') + D file value like(gzFile) File pointer + * + D gzerror PR * extproc('gzerror') Error string + D file value like(gzFile) File pointer + D errnum 10I 0 Error code + * + D gzclearerr PR extproc('gzclearerr') + D file value like(gzFile) File pointer + * + ************************************************************************** + * Basic function prototypes + ************************************************************************** + * + D zlibVersion PR * extproc('zlibVersion') Version string + * + D deflateInit PR 10I 0 extproc('deflateInit_') Init. compression + D strm like(z_stream) Compression stream + D level 10I 0 value Compression level + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D deflate PR 10I 0 extproc('deflate') Compress data + D strm like(z_stream) Compression stream + D flush 10I 0 value Flush type required + * + D deflateEnd PR 10I 0 extproc('deflateEnd') Termin. compression + D strm like(z_stream) Compression stream + * + D inflateInit PR 10I 0 extproc('inflateInit_') Init. expansion + D strm like(z_stream) Expansion stream + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D inflate PR 10I 0 extproc('inflate') Expand data + D strm like(z_stream) Expansion stream + D flush 10I 0 value Flush type required + * + D inflateEnd PR 10I 0 extproc('inflateEnd') Termin. expansion + D strm like(z_stream) Expansion stream + * + ************************************************************************** + * Advanced function prototypes + ************************************************************************** + * + D deflateInit2 PR 10I 0 extproc('deflateInit2_') Init. compression + D strm like(z_stream) Compression stream + D level 10I 0 value Compression level + D method 10I 0 value Compression method + D windowBits 10I 0 value log2(window size) + D memLevel 10I 0 value Mem/cmpress tradeoff + D strategy 10I 0 value Compression stategy + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D deflateSetDictionary... + D PR 10I 0 extproc('deflateSetDictionary') Init. dictionary + D strm like(z_stream) Compression stream + D dictionary 65535 const options(*varsize) Dictionary bytes + D dictLength 10U 0 value Dictionary length + * + D deflateCopy PR 10I 0 extproc('deflateCopy') Compress strm 2 strm + D dest like(z_stream) Destination stream + D source like(z_stream) Source stream + * + D deflateReset PR 10I 0 extproc('deflateReset') End and init. stream + D strm like(z_stream) Compression stream + * + D deflateParams PR 10I 0 extproc('deflateParams') Change level & strat + D strm like(z_stream) Compression stream + D level 10I 0 value Compression level + D strategy 10I 0 value Compression stategy + * + D deflateBound PR 10U 0 extproc('deflateBound') Change level & strat + D strm like(z_stream) Compression stream + D sourcelen 10U 0 value Compression level + * + D deflatePending PR 10I 0 extproc('deflatePending') Change level & strat + D strm like(z_stream) Compression stream + D pending 10U 0 Pending bytes + D bits 10I 0 Pending bits + * + D deflatePrime PR 10I 0 extproc('deflatePrime') Change level & strat + D strm like(z_stream) Compression stream + D bits 10I 0 value # of bits to insert + D value 10I 0 value Bits to insert + * + D inflateInit2 PR 10I 0 extproc('inflateInit2_') Init. expansion + D strm like(z_stream) Expansion stream + D windowBits 10I 0 value log2(window size) + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D inflateSetDictionary... + D PR 10I 0 extproc('inflateSetDictionary') Init. dictionary + D strm like(z_stream) Expansion stream + D dictionary 65535 const options(*varsize) Dictionary bytes + D dictLength 10U 0 value Dictionary length + * + D inflateSync PR 10I 0 extproc('inflateSync') Sync. expansion + D strm like(z_stream) Expansion stream + * + D inflateCopy PR 10I 0 extproc('inflateCopy') + D dest like(z_stream) Destination stream + D source like(z_stream) Source stream + * + D inflateReset PR 10I 0 extproc('inflateReset') End and init. stream + D strm like(z_stream) Expansion stream + * + D inflateReset2 PR 10I 0 extproc('inflateReset2') End and init. stream + D strm like(z_stream) Expansion stream + D windowBits 10I 0 value Log2(buffer size) + * + D inflatePrime PR 10I 0 extproc('inflatePrime') Insert bits + D strm like(z_stream) Expansion stream + D bits 10I 0 value Bit count + D value 10I 0 value Bits to insert + * + D inflateMark PR 10I 0 extproc('inflateMark') Get inflate info + D strm like(z_stream) Expansion stream + * + D inflateBackInit... + D PR 10I 0 extproc('inflateBackInit_') + D strm like(z_stream) Expansion stream + D windowBits 10I 0 value Log2(buffer size) + D window 65535 options(*varsize) Buffer + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D inflateBack PR 10I 0 extproc('inflateBack') + D strm like(z_stream) Expansion stream + D in * value procptr Input function + D in_desc * value Input descriptor + D out * value procptr Output function + D out_desc * value Output descriptor + * + D inflateBackEnd PR 10I 0 extproc('inflateBackEnd') + D strm like(z_stream) Expansion stream + * + D zlibCompileFlags... + D PR 10U 0 extproc('zlibCompileFlags') + * + ************************************************************************** + * Checksum function prototypes + ************************************************************************** + * + D adler32 PR 10U 0 extproc('adler32') New checksum + D adler 10U 0 value Old checksum + D buf 65535 const options(*varsize) Bytes to accumulate + D len 10U 0 value Buffer length + * + D crc32 PR 10U 0 extproc('crc32') New checksum + D crc 10U 0 value Old checksum + D buf 65535 const options(*varsize) Bytes to accumulate + D len 10U 0 value Buffer length + * + ************************************************************************** + * Miscellaneous function prototypes + ************************************************************************** + * + D zError PR * extproc('zError') Error string + D err 10I 0 value Error code + * + D inflateSyncPoint... + D PR 10I 0 extproc('inflateSyncPoint') + D strm like(z_stream) Expansion stream + * + D get_crc_table PR * extproc('get_crc_table') Ptr to ulongs + * + D inflateUndermine... + D PR 10I 0 extproc('inflateUndermine') + D strm like(z_stream) Expansion stream + D arg 10I 0 value Error code + * + D inflateResetKeep... + D PR 10I 0 extproc('inflateResetKeep') End and init. stream + D strm like(z_stream) Expansion stream + * + D deflateResetKeep... + D PR 10I 0 extproc('deflateResetKeep') End and init. stream + D strm like(z_stream) Expansion stream + * + D gzflags PR 10U 0 extproc('gzflags') + * + /endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/asm686/README.686 b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/asm686/README.686 new file mode 100644 index 00000000..a0bf3bea --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/asm686/README.686 @@ -0,0 +1,51 @@ +This is a patched version of zlib, modified to use +Pentium-Pro-optimized assembly code in the deflation algorithm. The +files changed/added by this patch are: + +README.686 +match.S + +The speedup that this patch provides varies, depending on whether the +compiler used to build the original version of zlib falls afoul of the +PPro's speed traps. My own tests show a speedup of around 10-20% at +the default compression level, and 20-30% using -9, against a version +compiled using gcc 2.7.2.3. Your mileage may vary. + +Note that this code has been tailored for the PPro/PII in particular, +and will not perform particuarly well on a Pentium. + +If you are using an assembler other than GNU as, you will have to +translate match.S to use your assembler's syntax. (Have fun.) + +Brian Raiter +breadbox@muppetlabs.com +April, 1998 + + +Added for zlib 1.1.3: + +The patches come from +http://www.muppetlabs.com/~breadbox/software/assembly.html + +To compile zlib with this asm file, copy match.S to the zlib directory +then do: + +CFLAGS="-O3 -DASMV" ./configure +make OBJA=match.o + + +Update: + +I've been ignoring these assembly routines for years, believing that +gcc's generated code had caught up with it sometime around gcc 2.95 +and the major rearchitecting of the Pentium 4. However, I recently +learned that, despite what I believed, this code still has some life +in it. On the Pentium 4 and AMD64 chips, it continues to run about 8% +faster than the code produced by gcc 4.1. + +In acknowledgement of its continuing usefulness, I've altered the +license to match that of the rest of zlib. Share and Enjoy! + +Brian Raiter +breadbox@muppetlabs.com +April, 2007 diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/asm686/match.S b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/asm686/match.S new file mode 100644 index 00000000..fa421092 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/asm686/match.S @@ -0,0 +1,357 @@ +/* match.S -- x86 assembly version of the zlib longest_match() function. + * Optimized for the Intel 686 chips (PPro and later). + * + * Copyright (C) 1998, 2007 Brian Raiter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the author be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef NO_UNDERLINE +#define match_init _match_init +#define longest_match _longest_match +#endif + +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ + +#define chainlenwmask 0 /* high word: current chain len */ + /* low word: s->wmask */ +#define window 4 /* local copy of s->window */ +#define windowbestlen 8 /* s->window + bestlen */ +#define scanstart 16 /* first two bytes of string */ +#define scanend 12 /* last two bytes of string */ +#define scanalign 20 /* dword-misalignment of string */ +#define nicematch 24 /* a good enough match size */ +#define bestlen 28 /* size of best match so far */ +#define scan 32 /* ptr to string wanting match */ + +#define LocalVarsSize (36) +/* saved ebx 36 */ +/* saved edi 40 */ +/* saved esi 44 */ +/* saved ebp 48 */ +/* return address 52 */ +#define deflatestate 56 /* the function arguments */ +#define curmatch 60 + +/* All the +zlib1222add offsets are due to the addition of fields + * in zlib in the deflate_state structure since the asm code was first written + * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). + * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). + * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + */ + +#define zlib1222add (8) + +#define dsWSize (36+zlib1222add) +#define dsWMask (44+zlib1222add) +#define dsWindow (48+zlib1222add) +#define dsPrev (56+zlib1222add) +#define dsMatchLen (88+zlib1222add) +#define dsPrevMatch (92+zlib1222add) +#define dsStrStart (100+zlib1222add) +#define dsMatchStart (104+zlib1222add) +#define dsLookahead (108+zlib1222add) +#define dsPrevLen (112+zlib1222add) +#define dsMaxChainLen (116+zlib1222add) +#define dsGoodMatch (132+zlib1222add) +#define dsNiceMatch (136+zlib1222add) + + +.file "match.S" + +.globl match_init, longest_match + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ +.cfi_sections .debug_frame + +longest_match: + +.cfi_startproc +/* Save registers that the compiler may be using, and adjust %esp to */ +/* make room for our stack frame. */ + + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset ebp, -8 + pushl %edi + .cfi_def_cfa_offset 12 + pushl %esi + .cfi_def_cfa_offset 16 + pushl %ebx + .cfi_def_cfa_offset 20 + subl $LocalVarsSize, %esp + .cfi_def_cfa_offset LocalVarsSize+20 + +/* Retrieve the function arguments. %ecx will hold cur_match */ +/* throughout the entire function. %edx will hold the pointer to the */ +/* deflate_state structure during the function's setup (before */ +/* entering the main loop). */ + + movl deflatestate(%esp), %edx + movl curmatch(%esp), %ecx + +/* uInt wmask = s->w_mask; */ +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen(%edx), %eax + movl dsGoodMatch(%edx), %ebx + cmpl %ebx, %eax + movl dsWMask(%edx), %eax + movl dsMaxChainLen(%edx), %ebx + jl LastMatchGood + shrl $2, %ebx +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the wmask */ +/* value, which it will always accompany. */ + + decl %ebx + shll $16, %ebx + orl %eax, %ebx + movl %ebx, chainlenwmask(%esp) + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch(%edx), %eax + movl dsLookahead(%edx), %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, nicematch(%esp) + +/* register Bytef *scan = s->window + s->strstart; */ + + movl dsWindow(%edx), %esi + movl %esi, window(%esp) + movl dsStrStart(%edx), %ebp + lea (%esi,%ebp), %edi + movl %edi, scan(%esp) + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + movl %edi, %eax + negl %eax + andl $3, %eax + movl %eax, scanalign(%esp) + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize(%edx), %eax + subl $MIN_LOOKAHEAD, %eax + subl %eax, %ebp + jg LimitPositive + xorl %ebp, %ebp +LimitPositive: + +/* int best_len = s->prev_length; */ + + movl dsPrevLen(%edx), %eax + movl %eax, bestlen(%esp) + +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ + + addl %eax, %esi + movl %esi, windowbestlen(%esp) + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ +/* Posf *prev = s->prev; */ + + movzwl (%edi), %ebx + movl %ebx, scanstart(%esp) + movzwl -1(%edi,%eax), %ebx + movl %ebx, scanend(%esp) + movl dsPrev(%edx), %edi + +/* Jump into the main loop. */ + + movl chainlenwmask(%esp), %edx + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + * + * Within this loop: + * %ebx = scanend + * %ecx = curmatch + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) + * %esi = windowbestlen - i.e., (window + bestlen) + * %edi = prev + * %ebp = limit + */ +LookupLoop: + andl %edx, %ecx + movzwl (%edi,%ecx,2), %ecx + cmpl %ebp, %ecx + jbe LeaveNow + subl $0x00010000, %edx + js LeaveNow +LoopEntry: movzwl -1(%esi,%ecx), %eax + cmpl %ebx, %eax + jnz LookupLoop + movl window(%esp), %eax + movzwl (%eax,%ecx), %eax + cmpl scanstart(%esp), %eax + jnz LookupLoop + +/* Store the current value of chainlen. */ + + movl %edx, chainlenwmask(%esp) + +/* Point %edi to the string under scrutiny, and %esi to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + movl window(%esp), %esi + movl scan(%esp), %edi + addl %ecx, %esi + movl scanalign(%esp), %eax + movl $(-MAX_MATCH_8), %edx + lea MAX_MATCH_8(%edi,%eax), %edi + lea MAX_MATCH_8(%esi,%eax), %esi + +/* Test the strings for equality, 8 bytes at a time. At the end, + * adjust %edx so that it is offset to the exact byte that mismatched. + * + * We already know at this point that the first three bytes of the + * strings match each other, and they can be safely passed over before + * starting the compare loop. So what this code does is skip over 0-3 + * bytes, as much as necessary in order to dword-align the %edi + * pointer. (%esi will still be misaligned three times out of four.) + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance. + */ +LoopCmps: + movl (%esi,%edx), %eax + xorl (%edi,%edx), %eax + jnz LeaveLoopCmps + movl 4(%esi,%edx), %eax + xorl 4(%edi,%edx), %eax + jnz LeaveLoopCmps4 + addl $8, %edx + jnz LoopCmps + jmp LenMaximum +LeaveLoopCmps4: addl $4, %edx +LeaveLoopCmps: testl $0x0000FFFF, %eax + jnz LenLower + addl $2, %edx + shrl $16, %eax +LenLower: subb $1, %al + adcl $0, %edx + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%edi,%edx), %eax + movl scan(%esp), %edi + subl %edi, %eax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + cmpl %ebx, %eax + jg LongerMatch + movl windowbestlen(%esp), %esi + movl dsPrev(%edx), %edi + movl scanend(%esp), %ebx + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: movl nicematch(%esp), %ebx + movl %eax, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + cmpl %ebx, %eax + jge LeaveNow + movl window(%esp), %esi + addl %eax, %esi + movl %esi, windowbestlen(%esp) + movzwl -1(%edi,%eax), %ebx + movl dsPrev(%edx), %edi + movl %ebx, scanend(%esp) + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: movl deflatestate(%esp), %edx + movl $MAX_MATCH, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + movl dsLookahead(%edx), %eax + cmpl %eax, %ebx + jg LookaheadRet + movl %ebx, %eax +LookaheadRet: + +/* Restore the stack and return from whence we came. */ + + addl $LocalVarsSize, %esp + .cfi_def_cfa_offset 20 + popl %ebx + .cfi_def_cfa_offset 16 + popl %esi + .cfi_def_cfa_offset 12 + popl %edi + .cfi_def_cfa_offset 8 + popl %ebp + .cfi_def_cfa_offset 4 +.cfi_endproc +match_init: ret diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/Makefile b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/Makefile new file mode 100644 index 00000000..9be80baf --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/Makefile @@ -0,0 +1,8 @@ +blast: blast.c blast.h + cc -DTEST -o blast blast.c + +test: blast + blast < test.pk | cmp - test.txt + +clean: + rm -f blast blast.o diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/README b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/README new file mode 100644 index 00000000..e3a60b3f --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/README @@ -0,0 +1,4 @@ +Read blast.h for purpose and usage. + +Mark Adler +madler@alumni.caltech.edu diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/blast.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/blast.c new file mode 100644 index 00000000..4ce697a4 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/blast.c @@ -0,0 +1,444 @@ +/* blast.c + * Copyright (C) 2003 Mark Adler + * For conditions of distribution and use, see copyright notice in blast.h + * version 1.1, 16 Feb 2003 + * + * blast.c decompresses data compressed by the PKWare Compression Library. + * This function provides functionality similar to the explode() function of + * the PKWare library, hence the name "blast". + * + * This decompressor is based on the excellent format description provided by + * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the + * example Ben provided in the post is incorrect. The distance 110001 should + * instead be 111000. When corrected, the example byte stream becomes: + * + * 00 04 82 24 25 8f 80 7f + * + * which decompresses to "AIAIAIAIAIAIA" (without the quotes). + */ + +/* + * Change history: + * + * 1.0 12 Feb 2003 - First version + * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data + */ + +#include /* for setjmp(), longjmp(), and jmp_buf */ +#include "blast.h" /* prototype for blast() */ + +#define local static /* for local function definitions */ +#define MAXBITS 13 /* maximum code length */ +#define MAXWIN 4096 /* maximum window size */ + +/* input and output state */ +struct state { + /* input state */ + blast_in infun; /* input function provided by user */ + void *inhow; /* opaque information passed to infun() */ + unsigned char *in; /* next input location */ + unsigned left; /* available input at in */ + int bitbuf; /* bit buffer */ + int bitcnt; /* number of bits in bit buffer */ + + /* input limit error return state for bits() and decode() */ + jmp_buf env; + + /* output state */ + blast_out outfun; /* output function provided by user */ + void *outhow; /* opaque information passed to outfun() */ + unsigned next; /* index of next write location in out[] */ + int first; /* true to check distances (for first 4K) */ + unsigned char out[MAXWIN]; /* output buffer and sliding window */ +}; + +/* + * Return need bits from the input stream. This always leaves less than + * eight bits in the buffer. bits() works properly for need == 0. + * + * Format notes: + * + * - Bits are stored in bytes from the least significant bit to the most + * significant bit. Therefore bits are dropped from the bottom of the bit + * buffer, using shift right, and new bytes are appended to the top of the + * bit buffer, using shift left. + */ +local int bits(struct state *s, int need) +{ + int val; /* bit accumulator */ + + /* load at least need bits into val */ + val = s->bitbuf; + while (s->bitcnt < need) { + if (s->left == 0) { + s->left = s->infun(s->inhow, &(s->in)); + if (s->left == 0) longjmp(s->env, 1); /* out of input */ + } + val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */ + s->left--; + s->bitcnt += 8; + } + + /* drop need bits and update buffer, always zero to seven bits left */ + s->bitbuf = val >> need; + s->bitcnt -= need; + + /* return need bits, zeroing the bits above that */ + return val & ((1 << need) - 1); +} + +/* + * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of + * each length, which for a canonical code are stepped through in order. + * symbol[] are the symbol values in canonical order, where the number of + * entries is the sum of the counts in count[]. The decoding process can be + * seen in the function decode() below. + */ +struct huffman { + short *count; /* number of symbols of each length */ + short *symbol; /* canonically ordered symbols */ +}; + +/* + * Decode a code from the stream s using huffman table h. Return the symbol or + * a negative value if there is an error. If all of the lengths are zero, i.e. + * an empty code, or if the code is incomplete and an invalid code is received, + * then -9 is returned after reading MAXBITS bits. + * + * Format notes: + * + * - The codes as stored in the compressed data are bit-reversed relative to + * a simple integer ordering of codes of the same lengths. Hence below the + * bits are pulled from the compressed data one at a time and used to + * build the code value reversed from what is in the stream in order to + * permit simple integer comparisons for decoding. + * + * - The first code for the shortest length is all ones. Subsequent codes of + * the same length are simply integer decrements of the previous code. When + * moving up a length, a one bit is appended to the code. For a complete + * code, the last code of the longest length will be all zeros. To support + * this ordering, the bits pulled during decoding are inverted to apply the + * more "natural" ordering starting with all zeros and incrementing. + */ +local int decode(struct state *s, struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + int bitbuf; /* bits from stream */ + int left; /* bits left in next or left to process */ + short *next; /* next number of codes */ + + bitbuf = s->bitbuf; + left = s->bitcnt; + code = first = index = 0; + len = 1; + next = h->count + 1; + while (1) { + while (left--) { + code |= (bitbuf & 1) ^ 1; /* invert code */ + bitbuf >>= 1; + count = *next++; + if (code < first + count) { /* if length len, return symbol */ + s->bitbuf = bitbuf; + s->bitcnt = (s->bitcnt - len) & 7; + return h->symbol[index + (code - first)]; + } + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + len++; + } + left = (MAXBITS+1) - len; + if (left == 0) break; + if (s->left == 0) { + s->left = s->infun(s->inhow, &(s->in)); + if (s->left == 0) longjmp(s->env, 1); /* out of input */ + } + bitbuf = *(s->in)++; + s->left--; + if (left > 8) left = 8; + } + return -9; /* ran out of codes */ +} + +/* + * Given a list of repeated code lengths rep[0..n-1], where each byte is a + * count (high four bits + 1) and a code length (low four bits), generate the + * list of code lengths. This compaction reduces the size of the object code. + * Then given the list of code lengths length[0..n-1] representing a canonical + * Huffman code for n symbols, construct the tables required to decode those + * codes. Those tables are the number of codes of each length, and the symbols + * sorted by length, retaining their original order within each length. The + * return value is zero for a complete code set, negative for an over- + * subscribed code set, and positive for an incomplete code set. The tables + * can be used if the return value is zero or positive, but they cannot be used + * if the return value is negative. If the return value is zero, it is not + * possible for decode() using that table to return an error--any stream of + * enough bits will resolve to a symbol. If the return value is positive, then + * it is possible for decode() using that table to return an error for received + * codes past the end of the incomplete lengths. + */ +local int construct(struct huffman *h, const unsigned char *rep, int n) +{ + int symbol; /* current symbol when stepping through length[] */ + int len; /* current length when stepping through h->count[] */ + int left; /* number of possible codes left of current length */ + short offs[MAXBITS+1]; /* offsets in symbol table for each length */ + short length[256]; /* code lengths */ + + /* convert compact repeat counts into symbol bit length list */ + symbol = 0; + do { + len = *rep++; + left = (len >> 4) + 1; + len &= 15; + do { + length[symbol++] = len; + } while (--left); + } while (--n); + n = symbol; + + /* count number of codes of each length */ + for (len = 0; len <= MAXBITS; len++) + h->count[len] = 0; + for (symbol = 0; symbol < n; symbol++) + (h->count[length[symbol]])++; /* assumes lengths are within bounds */ + if (h->count[0] == n) /* no codes! */ + return 0; /* complete, but decode() will fail */ + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; /* one possible code of zero length */ + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; /* one more bit, double codes left */ + left -= h->count[len]; /* deduct count from possible codes */ + if (left < 0) return left; /* over-subscribed--return negative */ + } /* left > 0 means incomplete */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + h->count[len]; + + /* + * put symbols in table sorted by length, by symbol order within each + * length + */ + for (symbol = 0; symbol < n; symbol++) + if (length[symbol] != 0) + h->symbol[offs[length[symbol]]++] = symbol; + + /* return zero for complete set, positive for incomplete set */ + return left; +} + +/* + * Decode PKWare Compression Library stream. + * + * Format notes: + * + * - First byte is 0 if literals are uncoded or 1 if they are coded. Second + * byte is 4, 5, or 6 for the number of extra bits in the distance code. + * This is the base-2 logarithm of the dictionary size minus six. + * + * - Compressed data is a combination of literals and length/distance pairs + * terminated by an end code. Literals are either Huffman coded or + * uncoded bytes. A length/distance pair is a coded length followed by a + * coded distance to represent a string that occurs earlier in the + * uncompressed data that occurs again at the current location. + * + * - A bit preceding a literal or length/distance pair indicates which comes + * next, 0 for literals, 1 for length/distance. + * + * - If literals are uncoded, then the next eight bits are the literal, in the + * normal bit order in th stream, i.e. no bit-reversal is needed. Similarly, + * no bit reversal is needed for either the length extra bits or the distance + * extra bits. + * + * - Literal bytes are simply written to the output. A length/distance pair is + * an instruction to copy previously uncompressed bytes to the output. The + * copy is from distance bytes back in the output stream, copying for length + * bytes. + * + * - Distances pointing before the beginning of the output data are not + * permitted. + * + * - Overlapped copies, where the length is greater than the distance, are + * allowed and common. For example, a distance of one and a length of 518 + * simply copies the last byte 518 times. A distance of four and a length of + * twelve copies the last four bytes three times. A simple forward copy + * ignoring whether the length is greater than the distance or not implements + * this correctly. + */ +local int decomp(struct state *s) +{ + int lit; /* true if literals are coded */ + int dict; /* log2(dictionary size) - 6 */ + int symbol; /* decoded symbol, extra bits for distance */ + int len; /* length for copy */ + int dist; /* distance for copy */ + int copy; /* copy counter */ + unsigned char *from, *to; /* copy pointers */ + static int virgin = 1; /* build tables once */ + static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */ + static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */ + static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */ + static struct huffman litcode = {litcnt, litsym}; /* length code */ + static struct huffman lencode = {lencnt, lensym}; /* length code */ + static struct huffman distcode = {distcnt, distsym};/* distance code */ + /* bit lengths of literal codes */ + static const unsigned char litlen[] = { + 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8, + 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5, + 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12, + 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27, + 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45, + 44, 173}; + /* bit lengths of length codes 0..15 */ + static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23}; + /* bit lengths of distance codes 0..63 */ + static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248}; + static const short base[16] = { /* base for length codes */ + 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264}; + static const char extra[16] = { /* extra bits for length codes */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8}; + + /* set up decoding tables (once--might not be thread-safe) */ + if (virgin) { + construct(&litcode, litlen, sizeof(litlen)); + construct(&lencode, lenlen, sizeof(lenlen)); + construct(&distcode, distlen, sizeof(distlen)); + virgin = 0; + } + + /* read header */ + lit = bits(s, 8); + if (lit > 1) return -1; + dict = bits(s, 8); + if (dict < 4 || dict > 6) return -2; + + /* decode literals and length/distance pairs */ + do { + if (bits(s, 1)) { + /* get length */ + symbol = decode(s, &lencode); + len = base[symbol] + bits(s, extra[symbol]); + if (len == 519) break; /* end code */ + + /* get distance */ + symbol = len == 2 ? 2 : dict; + dist = decode(s, &distcode) << symbol; + dist += bits(s, symbol); + dist++; + if (s->first && dist > s->next) + return -3; /* distance too far back */ + + /* copy length bytes from distance bytes back */ + do { + to = s->out + s->next; + from = to - dist; + copy = MAXWIN; + if (s->next < dist) { + from += copy; + copy = dist; + } + copy -= s->next; + if (copy > len) copy = len; + len -= copy; + s->next += copy; + do { + *to++ = *from++; + } while (--copy); + if (s->next == MAXWIN) { + if (s->outfun(s->outhow, s->out, s->next)) return 1; + s->next = 0; + s->first = 0; + } + } while (len != 0); + } + else { + /* get literal and write it */ + symbol = lit ? decode(s, &litcode) : bits(s, 8); + s->out[s->next++] = symbol; + if (s->next == MAXWIN) { + if (s->outfun(s->outhow, s->out, s->next)) return 1; + s->next = 0; + s->first = 0; + } + } + } while (1); + return 0; +} + +/* See comments in blast.h */ +int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow) +{ + struct state s; /* input/output state */ + int err; /* return value */ + + /* initialize input state */ + s.infun = infun; + s.inhow = inhow; + s.left = 0; + s.bitbuf = 0; + s.bitcnt = 0; + + /* initialize output state */ + s.outfun = outfun; + s.outhow = outhow; + s.next = 0; + s.first = 1; + + /* return if bits() or decode() tries to read past available input */ + if (setjmp(s.env) != 0) /* if came back here via longjmp(), */ + err = 2; /* then skip decomp(), return error */ + else + err = decomp(&s); /* decompress */ + + /* write any leftover output and update the error code if needed */ + if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0) + err = 1; + return err; +} + +#ifdef TEST +/* Example of how to use blast() */ +#include +#include + +#define CHUNK 16384 + +local unsigned inf(void *how, unsigned char **buf) +{ + static unsigned char hold[CHUNK]; + + *buf = hold; + return fread(hold, 1, CHUNK, (FILE *)how); +} + +local int outf(void *how, unsigned char *buf, unsigned len) +{ + return fwrite(buf, 1, len, (FILE *)how) != len; +} + +/* Decompress a PKWare Compression Library stream from stdin to stdout */ +int main(void) +{ + int ret, n; + + /* decompress to stdout */ + ret = blast(inf, stdin, outf, stdout); + if (ret != 0) fprintf(stderr, "blast error: %d\n", ret); + + /* see if there are any leftover bytes */ + n = 0; + while (getchar() != EOF) n++; + if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n); + + /* return blast() error code */ + return ret; +} +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/blast.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/blast.h new file mode 100644 index 00000000..ce9e5410 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/blast.h @@ -0,0 +1,71 @@ +/* blast.h -- interface for blast.c + Copyright (C) 2003 Mark Adler + version 1.1, 16 Feb 2003 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + + +/* + * blast() decompresses the PKWare Data Compression Library (DCL) compressed + * format. It provides the same functionality as the explode() function in + * that library. (Note: PKWare overused the "implode" verb, and the format + * used by their library implode() function is completely different and + * incompatible with the implode compression method supported by PKZIP.) + */ + + +typedef unsigned (*blast_in)(void *how, unsigned char **buf); +typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len); +/* Definitions for input/output functions passed to blast(). See below for + * what the provided functions need to do. + */ + + +int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow); +/* Decompress input to output using the provided infun() and outfun() calls. + * On success, the return value of blast() is zero. If there is an error in + * the source data, i.e. it is not in the proper format, then a negative value + * is returned. If there is not enough input available or there is not enough + * output space, then a positive error is returned. + * + * The input function is invoked: len = infun(how, &buf), where buf is set by + * infun() to point to the input buffer, and infun() returns the number of + * available bytes there. If infun() returns zero, then blast() returns with + * an input error. (blast() only asks for input if it needs it.) inhow is for + * use by the application to pass an input descriptor to infun(), if desired. + * + * The output function is invoked: err = outfun(how, buf, len), where the bytes + * to be written are buf[0..len-1]. If err is not zero, then blast() returns + * with an output error. outfun() is always called with len <= 4096. outhow + * is for use by the application to pass an output descriptor to outfun(), if + * desired. + * + * The return codes are: + * + * 2: ran out of input before completing decompression + * 1: output error before completing decompression + * 0: successful decompression + * -1: literal flag not zero or one + * -2: dictionary size not in 4..6 + * -3: distance is too far back + * + * At the bottom of blast.c is an example program that uses blast() that can be + * compiled to produce a command-line decompression filter by defining TEST. + */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/test.pk b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/test.pk new file mode 100644 index 00000000..be10b2bb Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/test.pk differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/test.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/test.txt new file mode 100644 index 00000000..bfdf1c5d --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/blast/test.txt @@ -0,0 +1 @@ +AIAIAIAIAIAIA \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/ZLib.pas b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/ZLib.pas new file mode 100644 index 00000000..6daf8bba --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/ZLib.pas @@ -0,0 +1,557 @@ +{*******************************************************} +{ } +{ Borland Delphi Supplemental Components } +{ ZLIB Data Compression Interface Unit } +{ } +{ Copyright (c) 1997,99 Borland Corporation } +{ } +{*******************************************************} + +{ Updated for zlib 1.2.x by Cosmin Truta } + +unit ZLib; + +interface + +uses SysUtils, Classes; + +type + TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl; + TFree = procedure (AppData, Block: Pointer); cdecl; + + // Internal structure. Ignore. + TZStreamRec = packed record + next_in: PChar; // next input byte + avail_in: Integer; // number of bytes available at next_in + total_in: Longint; // total nb of input bytes read so far + + next_out: PChar; // next output byte should be put here + avail_out: Integer; // remaining free space at next_out + total_out: Longint; // total nb of bytes output so far + + msg: PChar; // last error message, NULL if no error + internal: Pointer; // not visible by applications + + zalloc: TAlloc; // used to allocate the internal state + zfree: TFree; // used to free the internal state + AppData: Pointer; // private data object passed to zalloc and zfree + + data_type: Integer; // best guess about the data type: ascii or binary + adler: Longint; // adler32 value of the uncompressed data + reserved: Longint; // reserved for future use + end; + + // Abstract ancestor class + TCustomZlibStream = class(TStream) + private + FStrm: TStream; + FStrmPos: Integer; + FOnProgress: TNotifyEvent; + FZRec: TZStreamRec; + FBuffer: array [Word] of Char; + protected + procedure Progress(Sender: TObject); dynamic; + property OnProgress: TNotifyEvent read FOnProgress write FOnProgress; + constructor Create(Strm: TStream); + end; + +{ TCompressionStream compresses data on the fly as data is written to it, and + stores the compressed data to another stream. + + TCompressionStream is write-only and strictly sequential. Reading from the + stream will raise an exception. Using Seek to move the stream pointer + will raise an exception. + + Output data is cached internally, written to the output stream only when + the internal output buffer is full. All pending output data is flushed + when the stream is destroyed. + + The Position property returns the number of uncompressed bytes of + data that have been written to the stream so far. + + CompressionRate returns the on-the-fly percentage by which the original + data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100 + If raw data size = 100 and compressed data size = 25, the CompressionRate + is 75% + + The OnProgress event is called each time the output buffer is filled and + written to the output stream. This is useful for updating a progress + indicator when you are writing a large chunk of data to the compression + stream in a single call.} + + + TCompressionLevel = (clNone, clFastest, clDefault, clMax); + + TCompressionStream = class(TCustomZlibStream) + private + function GetCompressionRate: Single; + public + constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream); + destructor Destroy; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + function Seek(Offset: Longint; Origin: Word): Longint; override; + property CompressionRate: Single read GetCompressionRate; + property OnProgress; + end; + +{ TDecompressionStream decompresses data on the fly as data is read from it. + + Compressed data comes from a separate source stream. TDecompressionStream + is read-only and unidirectional; you can seek forward in the stream, but not + backwards. The special case of setting the stream position to zero is + allowed. Seeking forward decompresses data until the requested position in + the uncompressed data has been reached. Seeking backwards, seeking relative + to the end of the stream, requesting the size of the stream, and writing to + the stream will raise an exception. + + The Position property returns the number of bytes of uncompressed data that + have been read from the stream so far. + + The OnProgress event is called each time the internal input buffer of + compressed data is exhausted and the next block is read from the input stream. + This is useful for updating a progress indicator when you are reading a + large chunk of data from the decompression stream in a single call.} + + TDecompressionStream = class(TCustomZlibStream) + public + constructor Create(Source: TStream); + destructor Destroy; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + function Seek(Offset: Longint; Origin: Word): Longint; override; + property OnProgress; + end; + + + +{ CompressBuf compresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + Out: OutBuf = ptr to newly allocated buffer containing decompressed data + OutBytes = number of bytes in OutBuf } +procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; + out OutBuf: Pointer; out OutBytes: Integer); + + +{ DecompressBuf decompresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + OutEstimate = zero, or est. size of the decompressed data + Out: OutBuf = ptr to newly allocated buffer containing decompressed data + OutBytes = number of bytes in OutBuf } +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); + +{ DecompressToUserBuf decompresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + Out: OutBuf = ptr to user-allocated buffer to contain decompressed data + BufSize = number of bytes in OutBuf } +procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; + const OutBuf: Pointer; BufSize: Integer); + +const + zlib_version = '1.2.6'; + +type + EZlibError = class(Exception); + ECompressionError = class(EZlibError); + EDecompressionError = class(EZlibError); + +implementation + +uses ZLibConst; + +const + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = (-1); + Z_STREAM_ERROR = (-2); + Z_DATA_ERROR = (-3); + Z_MEM_ERROR = (-4); + Z_BUF_ERROR = (-5); + Z_VERSION_ERROR = (-6); + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = (-1); + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_RLE = 3; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_ASCII = 1; + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + + +{$L adler32.obj} +{$L compress.obj} +{$L crc32.obj} +{$L deflate.obj} +{$L infback.obj} +{$L inffast.obj} +{$L inflate.obj} +{$L inftrees.obj} +{$L trees.obj} +{$L uncompr.obj} +{$L zutil.obj} + +procedure adler32; external; +procedure compressBound; external; +procedure crc32; external; +procedure deflateInit2_; external; +procedure deflateParams; external; + +function _malloc(Size: Integer): Pointer; cdecl; +begin + Result := AllocMem(Size); +end; + +procedure _free(Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; +begin + FillChar(P^, count, B); +end; + +procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; +begin + Move(source^, dest^, count); +end; + + + +// deflate compresses data +function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar; + recsize: Integer): Integer; external; +function deflate(var strm: TZStreamRec; flush: Integer): Integer; external; +function deflateEnd(var strm: TZStreamRec): Integer; external; + +// inflate decompresses data +function inflateInit_(var strm: TZStreamRec; version: PChar; + recsize: Integer): Integer; external; +function inflate(var strm: TZStreamRec; flush: Integer): Integer; external; +function inflateEnd(var strm: TZStreamRec): Integer; external; +function inflateReset(var strm: TZStreamRec): Integer; external; + + +function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl; +begin +// GetMem(Result, Items*Size); + Result := AllocMem(Items * Size); +end; + +procedure zlibFreeMem(AppData, Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +{function zlibCheck(code: Integer): Integer; +begin + Result := code; + if code < 0 then + raise EZlibError.Create('error'); //!! +end;} + +function CCheck(code: Integer): Integer; +begin + Result := code; + if code < 0 then + raise ECompressionError.Create('error'); //!! +end; + +function DCheck(code: Integer): Integer; +begin + Result := code; + if code < 0 then + raise EDecompressionError.Create('error'); //!! +end; + +procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; + out OutBuf: Pointer; out OutBytes: Integer); +var + strm: TZStreamRec; + P: Pointer; +begin + FillChar(strm, sizeof(strm), 0); + strm.zalloc := zlibAllocMem; + strm.zfree := zlibFreeMem; + OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm))); + try + while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, 256); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := 256; + end; + finally + CCheck(deflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + + +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); +var + strm: TZStreamRec; + P: Pointer; + BufInc: Integer; +begin + FillChar(strm, sizeof(strm), 0); + strm.zalloc := zlibAllocMem; + strm.zfree := zlibFreeMem; + BufInc := (InBytes + 255) and not 255; + if OutEstimate = 0 then + OutBytes := BufInc + else + OutBytes := OutEstimate; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); + try + while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, BufInc); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := BufInc; + end; + finally + DCheck(inflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + +procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; + const OutBuf: Pointer; BufSize: Integer); +var + strm: TZStreamRec; +begin + FillChar(strm, sizeof(strm), 0); + strm.zalloc := zlibAllocMem; + strm.zfree := zlibFreeMem; + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := BufSize; + DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); + try + if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then + raise EZlibError.CreateRes(@sTargetBufferTooSmall); + finally + DCheck(inflateEnd(strm)); + end; +end; + +// TCustomZlibStream + +constructor TCustomZLibStream.Create(Strm: TStream); +begin + inherited Create; + FStrm := Strm; + FStrmPos := Strm.Position; + FZRec.zalloc := zlibAllocMem; + FZRec.zfree := zlibFreeMem; +end; + +procedure TCustomZLibStream.Progress(Sender: TObject); +begin + if Assigned(FOnProgress) then FOnProgress(Sender); +end; + + +// TCompressionStream + +constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel; + Dest: TStream); +const + Levels: array [TCompressionLevel] of ShortInt = + (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION); +begin + inherited Create(Dest); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec))); +end; + +destructor TCompressionStream.Destroy; +begin + FZRec.next_in := nil; + FZRec.avail_in := 0; + try + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END) + and (FZRec.avail_out = 0) do + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + end; + if FZRec.avail_out < sizeof(FBuffer) then + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out); + finally + deflateEnd(FZRec); + end; + inherited Destroy; +end; + +function TCompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + raise ECompressionError.CreateRes(@sInvalidStreamOp); +end; + +function TCompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + FZRec.next_in := @Buffer; + FZRec.avail_in := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_in > 0) do + begin + CCheck(deflate(FZRec, 0)); + if FZRec.avail_out = 0 then + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + FStrmPos := FStrm.Position; + Progress(Self); + end; + end; + Result := Count; +end; + +function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +begin + if (Offset = 0) and (Origin = soFromCurrent) then + Result := FZRec.total_in + else + raise ECompressionError.CreateRes(@sInvalidStreamOp); +end; + +function TCompressionStream.GetCompressionRate: Single; +begin + if FZRec.total_in = 0 then + Result := 0 + else + Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0; +end; + + +// TDecompressionStream + +constructor TDecompressionStream.Create(Source: TStream); +begin + inherited Create(Source); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec))); +end; + +destructor TDecompressionStream.Destroy; +begin + FStrm.Seek(-FZRec.avail_in, 1); + inflateEnd(FZRec); + inherited Destroy; +end; + +function TDecompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + FZRec.next_out := @Buffer; + FZRec.avail_out := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_out > 0) do + begin + if FZRec.avail_in = 0 then + begin + FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer)); + if FZRec.avail_in = 0 then + begin + Result := Count - FZRec.avail_out; + Exit; + end; + FZRec.next_in := FBuffer; + FStrmPos := FStrm.Position; + Progress(Self); + end; + CCheck(inflate(FZRec, 0)); + end; + Result := Count; +end; + +function TDecompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + raise EDecompressionError.CreateRes(@sInvalidStreamOp); +end; + +function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +var + I: Integer; + Buf: array [0..4095] of Char; +begin + if (Offset = 0) and (Origin = soFromBeginning) then + begin + DCheck(inflateReset(FZRec)); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + FStrm.Position := 0; + FStrmPos := 0; + end + else if ( (Offset >= 0) and (Origin = soFromCurrent)) or + ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then + begin + if Origin = soFromBeginning then Dec(Offset, FZRec.total_out); + if Offset > 0 then + begin + for I := 1 to Offset div sizeof(Buf) do + ReadBuffer(Buf, sizeof(Buf)); + ReadBuffer(Buf, Offset mod sizeof(Buf)); + end; + end + else + raise EDecompressionError.CreateRes(@sInvalidStreamOp); + Result := FZRec.total_out; +end; + + +end. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/ZLibConst.pas b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/ZLibConst.pas new file mode 100644 index 00000000..cdfe1367 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/ZLibConst.pas @@ -0,0 +1,11 @@ +unit ZLibConst; + +interface + +resourcestring + sTargetBufferTooSmall = 'ZLib error: target buffer may be too small'; + sInvalidStreamOp = 'Invalid stream operation'; + +implementation + +end. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/readme.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/readme.txt new file mode 100644 index 00000000..2dc9a8bb --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/readme.txt @@ -0,0 +1,76 @@ + +Overview +======== + +This directory contains an update to the ZLib interface unit, +distributed by Borland as a Delphi supplemental component. + +The original ZLib unit is Copyright (c) 1997,99 Borland Corp., +and is based on zlib version 1.0.4. There are a series of bugs +and security problems associated with that old zlib version, and +we recommend the users to update their ZLib unit. + + +Summary of modifications +======================== + +- Improved makefile, adapted to zlib version 1.2.1. + +- Some field types from TZStreamRec are changed from Integer to + Longint, for consistency with the zlib.h header, and for 64-bit + readiness. + +- The zlib_version constant is updated. + +- The new Z_RLE strategy has its corresponding symbolic constant. + +- The allocation and deallocation functions and function types + (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl, + and _malloc and _free are added as C RTL stubs. As a result, + the original C sources of zlib can be compiled out of the box, + and linked to the ZLib unit. + + +Suggestions for improvements +============================ + +Currently, the ZLib unit provides only a limited wrapper around +the zlib library, and much of the original zlib functionality is +missing. Handling compressed file formats like ZIP/GZIP or PNG +cannot be implemented without having this functionality. +Applications that handle these formats are either using their own, +duplicated code, or not using the ZLib unit at all. + +Here are a few suggestions: + +- Checksum class wrappers around adler32() and crc32(), similar + to the Java classes that implement the java.util.zip.Checksum + interface. + +- The ability to read and write raw deflate streams, without the + zlib stream header and trailer. Raw deflate streams are used + in the ZIP file format. + +- The ability to read and write gzip streams, used in the GZIP + file format, and normally produced by the gzip program. + +- The ability to select a different compression strategy, useful + to PNG and MNG image compression, and to multimedia compression + in general. Besides the compression level + + TCompressionLevel = (clNone, clFastest, clDefault, clMax); + + which, in fact, could have used the 'z' prefix and avoided + TColor-like symbols + + TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax); + + there could be a compression strategy + + TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle); + +- ZIP and GZIP stream handling via TStreams. + + +-- +Cosmin Truta diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/zlibd32.mak b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/zlibd32.mak new file mode 100644 index 00000000..9bb00b7c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/delphi/zlibd32.mak @@ -0,0 +1,99 @@ +# Makefile for zlib +# For use with Delphi and C++ Builder under Win32 +# Updated for zlib 1.2.x by Cosmin Truta + +# ------------ Borland C++ ------------ + +# This project uses the Delphi (fastcall/register) calling convention: +LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl + +CC = bcc32 +LD = bcc32 +AR = tlib +# do not use "-pr" in CFLAGS +CFLAGS = -a -d -k- -O2 $(LOC) +LDFLAGS = + + +# variables +ZLIB_LIB = zlib.lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# For the sake of the old Borland make, +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + + +# cleanup +clean: + -del *.obj + -del *.exe + -del *.lib + -del *.tds + -del zlib.bak + -del foo.gz + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib.build b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib.build new file mode 100644 index 00000000..7f90d6bc --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib.build @@ -0,0 +1,33 @@ + + + A .Net wrapper library around ZLib1.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib.chm b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib.chm new file mode 100644 index 00000000..f214a444 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib.chm differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib.sln b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib.sln new file mode 100644 index 00000000..ac45ca04 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/AssemblyInfo.cs b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/AssemblyInfo.cs new file mode 100644 index 00000000..0491bfc2 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("DotZLib")] +[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Henrik Ravn")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/ChecksumImpl.cs b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/ChecksumImpl.cs new file mode 100644 index 00000000..788b2fce --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/ChecksumImpl.cs @@ -0,0 +1,202 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Runtime.InteropServices; +using System.Text; + + +namespace DotZLib +{ + #region ChecksumGeneratorBase + /// + /// Implements the common functionality needed for all s + /// + /// + public abstract class ChecksumGeneratorBase : ChecksumGenerator + { + /// + /// The value of the current checksum + /// + protected uint _current; + + /// + /// Initializes a new instance of the checksum generator base - the current checksum is + /// set to zero + /// + public ChecksumGeneratorBase() + { + _current = 0; + } + + /// + /// Initializes a new instance of the checksum generator basewith a specified value + /// + /// The value to set the current checksum to + public ChecksumGeneratorBase(uint initialValue) + { + _current = initialValue; + } + + /// + /// Resets the current checksum to zero + /// + public void Reset() { _current = 0; } + + /// + /// Gets the current checksum value + /// + public uint Value { get { return _current; } } + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + /// All the other Update methods are implmeneted in terms of this one. + /// This is therefore the only method a derived class has to implement + public abstract void Update(byte[] data, int offset, int count); + + /// + /// Updates the current checksum with an array of bytes. + /// + /// The data to update the checksum with + public void Update(byte[] data) + { + Update(data, 0, data.Length); + } + + /// + /// Updates the current checksum with the data from a string + /// + /// The string to update the checksum with + /// The characters in the string are converted by the UTF-8 encoding + public void Update(string data) + { + Update(Encoding.UTF8.GetBytes(data)); + } + + /// + /// Updates the current checksum with the data from a string, using a specific encoding + /// + /// The string to update the checksum with + /// The encoding to use + public void Update(string data, Encoding encoding) + { + Update(encoding.GetBytes(data)); + } + + } + #endregion + + #region CRC32 + /// + /// Implements a CRC32 checksum generator + /// + public sealed class CRC32Checksum : ChecksumGeneratorBase + { + #region DLL imports + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint crc32(uint crc, int data, uint length); + + #endregion + + /// + /// Initializes a new instance of the CRC32 checksum generator + /// + public CRC32Checksum() : base() {} + + /// + /// Initializes a new instance of the CRC32 checksum generator with a specified value + /// + /// The value to set the current checksum to + public CRC32Checksum(uint initialValue) : base(initialValue) {} + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + public override void Update(byte[] data, int offset, int count) + { + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); + } + finally + { + hData.Free(); + } + } + + } + #endregion + + #region Adler + /// + /// Implements a checksum generator that computes the Adler checksum on data + /// + public sealed class AdlerChecksum : ChecksumGeneratorBase + { + #region DLL imports + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint adler32(uint adler, int data, uint length); + + #endregion + + /// + /// Initializes a new instance of the Adler checksum generator + /// + public AdlerChecksum() : base() {} + + /// + /// Initializes a new instance of the Adler checksum generator with a specified value + /// + /// The value to set the current checksum to + public AdlerChecksum(uint initialValue) : base(initialValue) {} + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + public override void Update(byte[] data, int offset, int count) + { + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); + } + finally + { + hData.Free(); + } + } + + } + #endregion + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/CircularBuffer.cs b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/CircularBuffer.cs new file mode 100644 index 00000000..c1cab3a0 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/CircularBuffer.cs @@ -0,0 +1,83 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; + +namespace DotZLib +{ + + /// + /// This class implements a circular buffer + /// + internal class CircularBuffer + { + #region Private data + private int _capacity; + private int _head; + private int _tail; + private int _size; + private byte[] _buffer; + #endregion + + public CircularBuffer(int capacity) + { + Debug.Assert( capacity > 0 ); + _buffer = new byte[capacity]; + _capacity = capacity; + _head = 0; + _tail = 0; + _size = 0; + } + + public int Size { get { return _size; } } + + public int Put(byte[] source, int offset, int count) + { + Debug.Assert( count > 0 ); + int trueCount = Math.Min(count, _capacity - Size); + for (int i = 0; i < trueCount; ++i) + _buffer[(_tail+i) % _capacity] = source[offset+i]; + _tail += trueCount; + _tail %= _capacity; + _size += trueCount; + return trueCount; + } + + public bool Put(byte b) + { + if (Size == _capacity) // no room + return false; + _buffer[_tail++] = b; + _tail %= _capacity; + ++_size; + return true; + } + + public int Get(byte[] destination, int offset, int count) + { + int trueCount = Math.Min(count,Size); + for (int i = 0; i < trueCount; ++i) + destination[offset + i] = _buffer[(_head+i) % _capacity]; + _head += trueCount; + _head %= _capacity; + _size -= trueCount; + return trueCount; + } + + public int Get() + { + if (Size == 0) + return -1; + + int result = (int)_buffer[_head++ % _capacity]; + --_size; + return result; + } + + } +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/CodecBase.cs b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/CodecBase.cs new file mode 100644 index 00000000..42e6da3a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/CodecBase.cs @@ -0,0 +1,198 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + /// + /// Implements the common functionality needed for all s + /// + public abstract class CodecBase : Codec, IDisposable + { + + #region Data members + + /// + /// Instance of the internal zlib buffer structure that is + /// passed to all functions in the zlib dll + /// + internal ZStream _ztream = new ZStream(); + + /// + /// True if the object instance has been disposed, false otherwise + /// + protected bool _isDisposed = false; + + /// + /// The size of the internal buffers + /// + protected const int kBufferSize = 16384; + + private byte[] _outBuffer = new byte[kBufferSize]; + private byte[] _inBuffer = new byte[kBufferSize]; + + private GCHandle _hInput; + private GCHandle _hOutput; + + private uint _checksum = 0; + + #endregion + + /// + /// Initializes a new instance of the CodeBase class. + /// + public CodecBase() + { + try + { + _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned); + _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned); + } + catch (Exception) + { + CleanUp(false); + throw; + } + } + + + #region Codec Members + + /// + /// Occurs when more processed data are available. + /// + public event DataAvailableHandler DataAvailable; + + /// + /// Fires the event + /// + protected void OnDataAvailable() + { + if (_ztream.total_out > 0) + { + if (DataAvailable != null) + DataAvailable( _outBuffer, 0, (int)_ztream.total_out); + resetOutput(); + } + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// Adding data may, or may not, raise the DataAvailable event + public void Add(byte[] data) + { + Add(data,0,data.Length); + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + /// This must be implemented by a derived class + public abstract void Add(byte[] data, int offset, int count); + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + /// This must be implemented by a derived class + public abstract void Finish(); + + /// + /// Gets the checksum of the data that has been added so far + /// + public uint Checksum { get { return _checksum; } } + + #endregion + + #region Destructor & IDisposable stuff + + /// + /// Destroys this instance + /// + ~CodecBase() + { + CleanUp(false); + } + + /// + /// Releases any unmanaged resources and calls the method of the derived class + /// + public void Dispose() + { + CleanUp(true); + } + + /// + /// Performs any codec specific cleanup + /// + /// This must be implemented by a derived class + protected abstract void CleanUp(); + + // performs the release of the handles and calls the dereived CleanUp() + private void CleanUp(bool isDisposing) + { + if (!_isDisposed) + { + CleanUp(); + if (_hInput.IsAllocated) + _hInput.Free(); + if (_hOutput.IsAllocated) + _hOutput.Free(); + + _isDisposed = true; + } + } + + + #endregion + + #region Helper methods + + /// + /// Copies a number of bytes to the internal codec buffer - ready for proccesing + /// + /// The byte array that contains the data to copy + /// The index of the first byte to copy + /// The number of bytes to copy from data + protected void copyInput(byte[] data, int startIndex, int count) + { + Array.Copy(data, startIndex, _inBuffer,0, count); + _ztream.next_in = _hInput.AddrOfPinnedObject(); + _ztream.total_in = 0; + _ztream.avail_in = (uint)count; + + } + + /// + /// Resets the internal output buffers to a known state - ready for processing + /// + protected void resetOutput() + { + _ztream.total_out = 0; + _ztream.avail_out = kBufferSize; + _ztream.next_out = _hOutput.AddrOfPinnedObject(); + } + + /// + /// Updates the running checksum property + /// + /// The new checksum value + protected void setChecksum(uint newSum) + { + _checksum = newSum; + } + #endregion + + } +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/Deflater.cs b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/Deflater.cs new file mode 100644 index 00000000..c2477925 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/Deflater.cs @@ -0,0 +1,106 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + + /// + /// Implements a data compressor, using the deflate algorithm in the ZLib dll + /// + public sealed class Deflater : CodecBase + { + #region Dll imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflate(ref ZStream sz, int flush); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflateReset(ref ZStream sz); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflateEnd(ref ZStream sz); + #endregion + + /// + /// Constructs an new instance of the Deflater + /// + /// The compression level to use for this Deflater + public Deflater(CompressLevel level) : base() + { + int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream)); + if (retval != 0) + throw new ZLibException(retval, "Could not initialize deflater"); + + resetOutput(); + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + public override void Add(byte[] data, int offset, int count) + { + if (data == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + + int total = count; + int inputIndex = offset; + int err = 0; + + while (err >= 0 && inputIndex < total) + { + copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); + while (err >= 0 && _ztream.avail_in > 0) + { + err = deflate(ref _ztream, (int)FlushTypes.None); + if (err == 0) + while (_ztream.avail_out == 0) + { + OnDataAvailable(); + err = deflate(ref _ztream, (int)FlushTypes.None); + } + inputIndex += (int)_ztream.total_in; + } + } + setChecksum( _ztream.adler ); + } + + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + public override void Finish() + { + int err; + do + { + err = deflate(ref _ztream, (int)FlushTypes.Finish); + OnDataAvailable(); + } + while (err == 0); + setChecksum( _ztream.adler ); + deflateReset(ref _ztream); + resetOutput(); + } + + /// + /// Closes the internal zlib deflate stream + /// + protected override void CleanUp() { deflateEnd(ref _ztream); } + + } +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/DotZLib.cs b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/DotZLib.cs new file mode 100644 index 00000000..be184b4c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/DotZLib.cs @@ -0,0 +1,288 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; + + +namespace DotZLib +{ + + #region Internal types + + /// + /// Defines constants for the various flush types used with zlib + /// + internal enum FlushTypes + { + None, Partial, Sync, Full, Finish, Block + } + + #region ZStream structure + // internal mapping of the zlib zstream structure for marshalling + [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)] + internal struct ZStream + { + public IntPtr next_in; + public uint avail_in; + public uint total_in; + + public IntPtr next_out; + public uint avail_out; + public uint total_out; + + [MarshalAs(UnmanagedType.LPStr)] + string msg; + uint state; + + uint zalloc; + uint zfree; + uint opaque; + + int data_type; + public uint adler; + uint reserved; + } + + #endregion + + #endregion + + #region Public enums + /// + /// Defines constants for the available compression levels in zlib + /// + public enum CompressLevel : int + { + /// + /// The default compression level with a reasonable compromise between compression and speed + /// + Default = -1, + /// + /// No compression at all. The data are passed straight through. + /// + None = 0, + /// + /// The maximum compression rate available. + /// + Best = 9, + /// + /// The fastest available compression level. + /// + Fastest = 1 + } + #endregion + + #region Exception classes + /// + /// The exception that is thrown when an error occurs on the zlib dll + /// + public class ZLibException : ApplicationException + { + /// + /// Initializes a new instance of the class with a specified + /// error message and error code + /// + /// The zlib error code that caused the exception + /// A message that (hopefully) describes the error + public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg)) + { + } + + /// + /// Initializes a new instance of the class with a specified + /// error code + /// + /// The zlib error code that caused the exception + public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode)) + { + } + } + #endregion + + #region Interfaces + + /// + /// Declares methods and properties that enables a running checksum to be calculated + /// + public interface ChecksumGenerator + { + /// + /// Gets the current value of the checksum + /// + uint Value { get; } + + /// + /// Clears the current checksum to 0 + /// + void Reset(); + + /// + /// Updates the current checksum with an array of bytes + /// + /// The data to update the checksum with + void Update(byte[] data); + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + void Update(byte[] data, int offset, int count); + + /// + /// Updates the current checksum with the data from a string + /// + /// The string to update the checksum with + /// The characters in the string are converted by the UTF-8 encoding + void Update(string data); + + /// + /// Updates the current checksum with the data from a string, using a specific encoding + /// + /// The string to update the checksum with + /// The encoding to use + void Update(string data, Encoding encoding); + } + + + /// + /// Represents the method that will be called from a codec when new data + /// are available. + /// + /// The byte array containing the processed data + /// The index of the first processed byte in data + /// The number of processed bytes available + /// On return from this method, the data may be overwritten, so grab it while you can. + /// You cannot assume that startIndex will be zero. + /// + public delegate void DataAvailableHandler(byte[] data, int startIndex, int count); + + /// + /// Declares methods and events for implementing compressors/decompressors + /// + public interface Codec + { + /// + /// Occurs when more processed data are available. + /// + event DataAvailableHandler DataAvailable; + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// Adding data may, or may not, raise the DataAvailable event + void Add(byte[] data); + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + void Add(byte[] data, int offset, int count); + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + void Finish(); + + /// + /// Gets the checksum of the data that has been added so far + /// + uint Checksum { get; } + + + } + + #endregion + + #region Classes + /// + /// Encapsulates general information about the ZLib library + /// + public class Info + { + #region DLL imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint zlibCompileFlags(); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern string zlibVersion(); + #endregion + + #region Private stuff + private uint _flags; + + // helper function that unpacks a bitsize mask + private static int bitSize(uint bits) + { + switch (bits) + { + case 0: return 16; + case 1: return 32; + case 2: return 64; + } + return -1; + } + #endregion + + /// + /// Constructs an instance of the Info class. + /// + public Info() + { + _flags = zlibCompileFlags(); + } + + /// + /// True if the library is compiled with debug info + /// + public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } } + + /// + /// True if the library is compiled with assembly optimizations + /// + public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } } + + /// + /// Gets the size of the unsigned int that was compiled into Zlib + /// + public int SizeOfUInt { get { return bitSize(_flags & 3); } } + + /// + /// Gets the size of the unsigned long that was compiled into Zlib + /// + public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } } + + /// + /// Gets the size of the pointers that were compiled into Zlib + /// + public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } } + + /// + /// Gets the size of the z_off_t type that was compiled into Zlib + /// + public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } } + + /// + /// Gets the version of ZLib as a string, e.g. "1.2.1" + /// + public static string Version { get { return zlibVersion(); } } + } + + #endregion + +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/DotZLib.csproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/DotZLib.csproj new file mode 100644 index 00000000..71eeb859 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/DotZLib.csproj @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/GZipStream.cs b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/GZipStream.cs new file mode 100644 index 00000000..b161300b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/GZipStream.cs @@ -0,0 +1,301 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + /// + /// Implements a compressed , in GZip (.gz) format. + /// + public class GZipStream : Stream, IDisposable + { + #region Dll Imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern IntPtr gzopen(string name, string mode); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzclose(IntPtr gzFile); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzwrite(IntPtr gzFile, int data, int length); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzread(IntPtr gzFile, int data, int length); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzgetc(IntPtr gzFile); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzputc(IntPtr gzFile, int c); + + #endregion + + #region Private data + private IntPtr _gzFile; + private bool _isDisposed = false; + private bool _isWriting; + #endregion + + #region Constructors + /// + /// Creates a new file as a writeable GZipStream + /// + /// The name of the compressed file to create + /// The compression level to use when adding data + /// If an error occurred in the internal zlib function + public GZipStream(string fileName, CompressLevel level) + { + _isWriting = true; + _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level)); + if (_gzFile == IntPtr.Zero) + throw new ZLibException(-1, "Could not open " + fileName); + } + + /// + /// Opens an existing file as a readable GZipStream + /// + /// The name of the file to open + /// If an error occurred in the internal zlib function + public GZipStream(string fileName) + { + _isWriting = false; + _gzFile = gzopen(fileName, "rb"); + if (_gzFile == IntPtr.Zero) + throw new ZLibException(-1, "Could not open " + fileName); + + } + #endregion + + #region Access properties + /// + /// Returns true of this stream can be read from, false otherwise + /// + public override bool CanRead + { + get + { + return !_isWriting; + } + } + + + /// + /// Returns false. + /// + public override bool CanSeek + { + get + { + return false; + } + } + + /// + /// Returns true if this tsream is writeable, false otherwise + /// + public override bool CanWrite + { + get + { + return _isWriting; + } + } + #endregion + + #region Destructor & IDispose stuff + + /// + /// Destroys this instance + /// + ~GZipStream() + { + cleanUp(false); + } + + /// + /// Closes the external file handle + /// + public void Dispose() + { + cleanUp(true); + } + + // Does the actual closing of the file handle. + private void cleanUp(bool isDisposing) + { + if (!_isDisposed) + { + gzclose(_gzFile); + _isDisposed = true; + } + } + #endregion + + #region Basic reading and writing + /// + /// Attempts to read a number of bytes from the stream. + /// + /// The destination data buffer + /// The index of the first destination byte in buffer + /// The number of bytes requested + /// The number of bytes read + /// If buffer is null + /// If count or offset are negative + /// If offset + count is > buffer.Length + /// If this stream is not readable. + /// If this stream has been disposed. + public override int Read(byte[] buffer, int offset, int count) + { + if (!CanRead) throw new NotSupportedException(); + if (buffer == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > buffer.Length) throw new ArgumentException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); + int result; + try + { + result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); + if (result < 0) + throw new IOException(); + } + finally + { + h.Free(); + } + return result; + } + + /// + /// Attempts to read a single byte from the stream. + /// + /// The byte that was read, or -1 in case of error or End-Of-File + public override int ReadByte() + { + if (!CanRead) throw new NotSupportedException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + return gzgetc(_gzFile); + } + + /// + /// Writes a number of bytes to the stream + /// + /// + /// + /// + /// If buffer is null + /// If count or offset are negative + /// If offset + count is > buffer.Length + /// If this stream is not writeable. + /// If this stream has been disposed. + public override void Write(byte[] buffer, int offset, int count) + { + if (!CanWrite) throw new NotSupportedException(); + if (buffer == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > buffer.Length) throw new ArgumentException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); + try + { + int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); + if (result < 0) + throw new IOException(); + } + finally + { + h.Free(); + } + } + + /// + /// Writes a single byte to the stream + /// + /// The byte to add to the stream. + /// If this stream is not writeable. + /// If this stream has been disposed. + public override void WriteByte(byte value) + { + if (!CanWrite) throw new NotSupportedException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + int result = gzputc(_gzFile, (int)value); + if (result < 0) + throw new IOException(); + } + #endregion + + #region Position & length stuff + /// + /// Not supported. + /// + /// + /// Always thrown + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + /// + /// Not suppported. + /// + /// + /// + /// + /// Always thrown + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + /// + /// Flushes the GZipStream. + /// + /// In this implementation, this method does nothing. This is because excessive + /// flushing may degrade the achievable compression rates. + public override void Flush() + { + // left empty on purpose + } + + /// + /// Gets/sets the current position in the GZipStream. Not suppported. + /// + /// In this implementation this property is not supported + /// Always thrown + public override long Position + { + get + { + throw new NotSupportedException(); + } + set + { + throw new NotSupportedException(); + } + } + + /// + /// Gets the size of the stream. Not suppported. + /// + /// In this implementation this property is not supported + /// Always thrown + public override long Length + { + get + { + throw new NotSupportedException(); + } + } + #endregion + } +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/Inflater.cs b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/Inflater.cs new file mode 100644 index 00000000..8ed5451d --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/Inflater.cs @@ -0,0 +1,105 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + + /// + /// Implements a data decompressor, using the inflate algorithm in the ZLib dll + /// + public class Inflater : CodecBase + { + #region Dll imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern int inflateInit_(ref ZStream sz, string vs, int size); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflate(ref ZStream sz, int flush); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflateReset(ref ZStream sz); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflateEnd(ref ZStream sz); + #endregion + + /// + /// Constructs an new instance of the Inflater + /// + public Inflater() : base() + { + int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream)); + if (retval != 0) + throw new ZLibException(retval, "Could not initialize inflater"); + + resetOutput(); + } + + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + public override void Add(byte[] data, int offset, int count) + { + if (data == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + + int total = count; + int inputIndex = offset; + int err = 0; + + while (err >= 0 && inputIndex < total) + { + copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); + err = inflate(ref _ztream, (int)FlushTypes.None); + if (err == 0) + while (_ztream.avail_out == 0) + { + OnDataAvailable(); + err = inflate(ref _ztream, (int)FlushTypes.None); + } + + inputIndex += (int)_ztream.total_in; + } + setChecksum( _ztream.adler ); + } + + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + public override void Finish() + { + int err; + do + { + err = inflate(ref _ztream, (int)FlushTypes.Finish); + OnDataAvailable(); + } + while (err == 0); + setChecksum( _ztream.adler ); + inflateReset(ref _ztream); + resetOutput(); + } + + /// + /// Closes the internal zlib inflate stream + /// + protected override void CleanUp() { inflateEnd(ref _ztream); } + + + } +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/UnitTests.cs b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/UnitTests.cs new file mode 100644 index 00000000..b33d9d9b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/DotZLib/UnitTests.cs @@ -0,0 +1,274 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Collections; +using System.IO; + +// uncomment the define below to include unit tests +//#define nunit +#if nunit +using NUnit.Framework; + +// Unit tests for the DotZLib class library +// ---------------------------------------- +// +// Use this with NUnit 2 from http://www.nunit.org +// + +namespace DotZLibTests +{ + using DotZLib; + + // helper methods + internal class Utils + { + public static bool byteArrEqual( byte[] lhs, byte[] rhs ) + { + if (lhs.Length != rhs.Length) + return false; + for (int i = lhs.Length-1; i >= 0; --i) + if (lhs[i] != rhs[i]) + return false; + return true; + } + + } + + + [TestFixture] + public class CircBufferTests + { + #region Circular buffer tests + [Test] + public void SinglePutGet() + { + CircularBuffer buf = new CircularBuffer(10); + Assert.AreEqual( 0, buf.Size ); + Assert.AreEqual( -1, buf.Get() ); + + Assert.IsTrue(buf.Put( 1 )); + Assert.AreEqual( 1, buf.Size ); + Assert.AreEqual( 1, buf.Get() ); + Assert.AreEqual( 0, buf.Size ); + Assert.AreEqual( -1, buf.Get() ); + } + + [Test] + public void BlockPutGet() + { + CircularBuffer buf = new CircularBuffer(10); + byte[] arr = {1,2,3,4,5,6,7,8,9,10}; + Assert.AreEqual( 10, buf.Put(arr,0,10) ); + Assert.AreEqual( 10, buf.Size ); + Assert.IsFalse( buf.Put(11) ); + Assert.AreEqual( 1, buf.Get() ); + Assert.IsTrue( buf.Put(11) ); + + byte[] arr2 = (byte[])arr.Clone(); + Assert.AreEqual( 9, buf.Get(arr2,1,9) ); + Assert.IsTrue( Utils.byteArrEqual(arr,arr2) ); + } + + #endregion + } + + [TestFixture] + public class ChecksumTests + { + #region CRC32 Tests + [Test] + public void CRC32_Null() + { + CRC32Checksum crc32 = new CRC32Checksum(); + Assert.AreEqual( 0, crc32.Value ); + + crc32 = new CRC32Checksum(1); + Assert.AreEqual( 1, crc32.Value ); + + crc32 = new CRC32Checksum(556); + Assert.AreEqual( 556, crc32.Value ); + } + + [Test] + public void CRC32_Data() + { + CRC32Checksum crc32 = new CRC32Checksum(); + byte[] data = { 1,2,3,4,5,6,7 }; + crc32.Update(data); + Assert.AreEqual( 0x70e46888, crc32.Value ); + + crc32 = new CRC32Checksum(); + crc32.Update("penguin"); + Assert.AreEqual( 0x0e5c1a120, crc32.Value ); + + crc32 = new CRC32Checksum(1); + crc32.Update("penguin"); + Assert.AreEqual(0x43b6aa94, crc32.Value); + + } + #endregion + + #region Adler tests + + [Test] + public void Adler_Null() + { + AdlerChecksum adler = new AdlerChecksum(); + Assert.AreEqual(0, adler.Value); + + adler = new AdlerChecksum(1); + Assert.AreEqual( 1, adler.Value ); + + adler = new AdlerChecksum(556); + Assert.AreEqual( 556, adler.Value ); + } + + [Test] + public void Adler_Data() + { + AdlerChecksum adler = new AdlerChecksum(1); + byte[] data = { 1,2,3,4,5,6,7 }; + adler.Update(data); + Assert.AreEqual( 0x5b001d, adler.Value ); + + adler = new AdlerChecksum(); + adler.Update("penguin"); + Assert.AreEqual(0x0bcf02f6, adler.Value ); + + adler = new AdlerChecksum(1); + adler.Update("penguin"); + Assert.AreEqual(0x0bd602f7, adler.Value); + + } + #endregion + } + + [TestFixture] + public class InfoTests + { + #region Info tests + [Test] + public void Info_Version() + { + Info info = new Info(); + Assert.AreEqual("1.2.6", Info.Version); + Assert.AreEqual(32, info.SizeOfUInt); + Assert.AreEqual(32, info.SizeOfULong); + Assert.AreEqual(32, info.SizeOfPointer); + Assert.AreEqual(32, info.SizeOfOffset); + } + #endregion + } + + [TestFixture] + public class DeflateInflateTests + { + #region Deflate tests + [Test] + public void Deflate_Init() + { + using (Deflater def = new Deflater(CompressLevel.Default)) + { + } + } + + private ArrayList compressedData = new ArrayList(); + private uint adler1; + + private ArrayList uncompressedData = new ArrayList(); + private uint adler2; + + public void CDataAvail(byte[] data, int startIndex, int count) + { + for (int i = 0; i < count; ++i) + compressedData.Add(data[i+startIndex]); + } + + [Test] + public void Deflate_Compress() + { + compressedData.Clear(); + + byte[] testData = new byte[35000]; + for (int i = 0; i < testData.Length; ++i) + testData[i] = 5; + + using (Deflater def = new Deflater((CompressLevel)5)) + { + def.DataAvailable += new DataAvailableHandler(CDataAvail); + def.Add(testData); + def.Finish(); + adler1 = def.Checksum; + } + } + #endregion + + #region Inflate tests + [Test] + public void Inflate_Init() + { + using (Inflater inf = new Inflater()) + { + } + } + + private void DDataAvail(byte[] data, int startIndex, int count) + { + for (int i = 0; i < count; ++i) + uncompressedData.Add(data[i+startIndex]); + } + + [Test] + public void Inflate_Expand() + { + uncompressedData.Clear(); + + using (Inflater inf = new Inflater()) + { + inf.DataAvailable += new DataAvailableHandler(DDataAvail); + inf.Add((byte[])compressedData.ToArray(typeof(byte))); + inf.Finish(); + adler2 = inf.Checksum; + } + Assert.AreEqual( adler1, adler2 ); + } + #endregion + } + + [TestFixture] + public class GZipStreamTests + { + #region GZipStream test + [Test] + public void GZipStream_WriteRead() + { + using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best)) + { + BinaryWriter writer = new BinaryWriter(gzOut); + writer.Write("hi there"); + writer.Write(Math.PI); + writer.Write(42); + } + + using (GZipStream gzIn = new GZipStream("gzstream.gz")) + { + BinaryReader reader = new BinaryReader(gzIn); + string s = reader.ReadString(); + Assert.AreEqual("hi there",s); + double d = reader.ReadDouble(); + Assert.AreEqual(Math.PI, d); + int i = reader.ReadInt32(); + Assert.AreEqual(42,i); + } + + } + #endregion + } +} + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/LICENSE_1_0.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/LICENSE_1_0.txt new file mode 100644 index 00000000..30aac2cf --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/readme.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/readme.txt new file mode 100644 index 00000000..b2395720 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/dotzlib/readme.txt @@ -0,0 +1,58 @@ +This directory contains a .Net wrapper class library for the ZLib1.dll + +The wrapper includes support for inflating/deflating memory buffers, +.Net streaming wrappers for the gz streams part of zlib, and wrappers +for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples. + +Directory structure: +-------------------- + +LICENSE_1_0.txt - License file. +readme.txt - This file. +DotZLib.chm - Class library documentation +DotZLib.build - NAnt build file +DotZLib.sln - Microsoft Visual Studio 2003 solution file + +DotZLib\*.cs - Source files for the class library + +Unit tests: +----------- +The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher. +To include unit tests in the build, define nunit before building. + + +Build instructions: +------------------- + +1. Using Visual Studio.Net 2003: + Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll) + will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on + you are building the release or debug version of the library. Check + DotZLib/UnitTests.cs for instructions on how to include unit tests in the + build. + +2. Using NAnt: + Open a command prompt with access to the build environment and run nant + in the same directory as the DotZLib.build file. + You can define 2 properties on the nant command-line to control the build: + debug={true|false} to toggle between release/debug builds (default=true). + nunit={true|false} to include or esclude unit tests (default=true). + Also the target clean will remove binaries. + Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release + or ./DotZLib/bin/debug, depending on whether you are building the release + or debug version of the library. + + Examples: + nant -D:debug=false -D:nunit=false + will build a release mode version of the library without unit tests. + nant + will build a debug version of the library with unit tests + nant clean + will remove all previously built files. + + +--------------------------------- +Copyright (c) Henrik Ravn 2004 + +Use, modification and distribution are subject to the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/gcc_gvmat64/gvmat64.S b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/gcc_gvmat64/gvmat64.S new file mode 100644 index 00000000..dd858ddb --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/gcc_gvmat64/gvmat64.S @@ -0,0 +1,574 @@ +/* +;uInt longest_match_x64( +; deflate_state *s, +; IPos cur_match); // current match + +; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64 +; (AMD64 on Athlon 64, Opteron, Phenom +; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7) +; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode) +; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; +; File written by Gilles Vollant, by converting to assembly the longest_match +; from Jean-loup Gailly in deflate.c of zLib and infoZip zip. +; and by taking inspiration on asm686 with masm, optimised assembly code +; from Brian Raiter, written 1998 +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software +; 3. This notice may not be removed or altered from any source distribution. +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; to compile this file for zLib, I use option: +; gcc -c -arch x86_64 gvmat64.S + + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; // current match / +; +; with XCode for Mac, I had strange error with some jump on intel syntax +; this is why BEFORE_JMP and AFTER_JMP are used + */ + + +#define BEFORE_JMP .att_syntax +#define AFTER_JMP .intel_syntax noprefix + +#ifndef NO_UNDERLINE +# define match_init _match_init +# define longest_match _longest_match +#endif + +.intel_syntax noprefix + +.globl match_init, longest_match +.text +longest_match: + + + +#define LocalVarsSize 96 +/* +; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12 +; free register : r14,r15 +; register can be saved : rsp +*/ + +#define chainlenwmask (rsp + 8 - LocalVarsSize) +#define nicematch (rsp + 16 - LocalVarsSize) + +#define save_rdi (rsp + 24 - LocalVarsSize) +#define save_rsi (rsp + 32 - LocalVarsSize) +#define save_rbx (rsp + 40 - LocalVarsSize) +#define save_rbp (rsp + 48 - LocalVarsSize) +#define save_r12 (rsp + 56 - LocalVarsSize) +#define save_r13 (rsp + 64 - LocalVarsSize) +#define save_r14 (rsp + 72 - LocalVarsSize) +#define save_r15 (rsp + 80 - LocalVarsSize) + + +/* +; all the +4 offsets are due to the addition of pending_buf_size (in zlib +; in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, remove the +4). +; Note : these value are good with a 8 bytes boundary pack structure +*/ + +#define MAX_MATCH 258 +#define MIN_MATCH 3 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) + +/* +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). +*/ + + + +/* you can check the structure offset by running + +#include +#include +#include "deflate.h" + +void print_depl() +{ +deflate_state ds; +deflate_state *s=&ds; +printf("size pointer=%u\n",(int)sizeof(void*)); + +printf("#define dsWSize %u\n",(int)(((char*)&(s->w_size))-((char*)s))); +printf("#define dsWMask %u\n",(int)(((char*)&(s->w_mask))-((char*)s))); +printf("#define dsWindow %u\n",(int)(((char*)&(s->window))-((char*)s))); +printf("#define dsPrev %u\n",(int)(((char*)&(s->prev))-((char*)s))); +printf("#define dsMatchLen %u\n",(int)(((char*)&(s->match_length))-((char*)s))); +printf("#define dsPrevMatch %u\n",(int)(((char*)&(s->prev_match))-((char*)s))); +printf("#define dsStrStart %u\n",(int)(((char*)&(s->strstart))-((char*)s))); +printf("#define dsMatchStart %u\n",(int)(((char*)&(s->match_start))-((char*)s))); +printf("#define dsLookahead %u\n",(int)(((char*)&(s->lookahead))-((char*)s))); +printf("#define dsPrevLen %u\n",(int)(((char*)&(s->prev_length))-((char*)s))); +printf("#define dsMaxChainLen %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s))); +printf("#define dsGoodMatch %u\n",(int)(((char*)&(s->good_match))-((char*)s))); +printf("#define dsNiceMatch %u\n",(int)(((char*)&(s->nice_match))-((char*)s))); +} +*/ + +#define dsWSize 68 +#define dsWMask 76 +#define dsWindow 80 +#define dsPrev 96 +#define dsMatchLen 144 +#define dsPrevMatch 148 +#define dsStrStart 156 +#define dsMatchStart 160 +#define dsLookahead 164 +#define dsPrevLen 168 +#define dsMaxChainLen 172 +#define dsGoodMatch 188 +#define dsNiceMatch 192 + +#define window_size [ rcx + dsWSize] +#define WMask [ rcx + dsWMask] +#define window_ad [ rcx + dsWindow] +#define prev_ad [ rcx + dsPrev] +#define strstart [ rcx + dsStrStart] +#define match_start [ rcx + dsMatchStart] +#define Lookahead [ rcx + dsLookahead] //; 0ffffffffh on infozip +#define prev_length [ rcx + dsPrevLen] +#define max_chain_length [ rcx + dsMaxChainLen] +#define good_match [ rcx + dsGoodMatch] +#define nice_match [ rcx + dsNiceMatch] + +/* +; windows: +; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match) + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch. + +; +; gcc on macosx-linux: +; see http://www.x86-64.org/documentation/abi-0.99.pdf +; param 1 in rdi, param 2 in rsi +; rbx, rsp, rbp, r12 to r15 must be preserved + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + +;;; Retrieve the function arguments. r8d will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + +; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match) +; mac: param 1 in rdi, param 2 rsi +; this clear high 32 bits of r8, which can be garbage in both r8 and rdx +*/ + mov [save_rbx],rbx + mov [save_rbp],rbp + + + mov rcx,rdi + + mov r8d,esi + + + mov [save_r12],r12 + mov [save_r13],r13 + mov [save_r14],r14 + mov [save_r15],r15 + + +//;;; uInt wmask = s->w_mask; +//;;; unsigned chain_length = s->max_chain_length; +//;;; if (s->prev_length >= s->good_match) { +//;;; chain_length >>= 2; +//;;; } + + + mov edi, prev_length + mov esi, good_match + mov eax, WMask + mov ebx, max_chain_length + cmp edi, esi + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +//;;; chainlen is decremented once beforehand so that the function can +//;;; use the sign flag instead of the zero flag for the exit test. +//;;; It is then shifted into the high word, to make room for the wmask +//;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + +//;;; on zlib only +//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + + + mov eax, nice_match + mov [chainlenwmask], ebx + mov r10d, Lookahead + cmp r10d, eax + cmovnl r10d, eax + mov [nicematch],r10d + + + +//;;; register Bytef *scan = s->window + s->strstart; + mov r10, window_ad + mov ebp, strstart + lea r13, [r10 + rbp] + +//;;; Determine how many bytes the scan ptr is off from being +//;;; dword-aligned. + + mov r9,r13 + neg r13 + and r13,3 + +//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +//;;; s->strstart - (IPos)MAX_DIST(s) : NIL; + + + mov eax, window_size + sub eax, MIN_LOOKAHEAD + + + xor edi,edi + sub ebp, eax + + mov r11d, prev_length + + cmovng ebp,edi + +//;;; int best_len = s->prev_length; + + +//;;; Store the sum of s->window + best_len in esi locally, and in esi. + + lea rsi,[r10+r11] + +//;;; register ush scan_start = *(ushf*)scan; +//;;; register ush scan_end = *(ushf*)(scan+best_len-1); +//;;; Posf *prev = s->prev; + + movzx r12d,word ptr [r9] + movzx ebx, word ptr [r9 + r11 - 1] + + mov rdi, prev_ad + +//;;; Jump into the main loop. + + mov edx, [chainlenwmask] + + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + + + +LookupLoop1: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + + + + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry1: + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jz LookupLoopIsZero + AFTER_JMP + +LookupLoop2: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + BEFORE_JMP + jbe LeaveNow + AFTER_JMP + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry2: + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jz LookupLoopIsZero + AFTER_JMP + +LookupLoop4: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + BEFORE_JMP + jbe LeaveNow + AFTER_JMP + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry4: + + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jnz LookupLoop1 + jmp LookupLoopIsZero + AFTER_JMP +/* +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; r8d = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit +*/ +.balign 16 +LookupLoop: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + BEFORE_JMP + jbe LeaveNow + AFTER_JMP + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry: + + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jnz LookupLoop1 + AFTER_JMP +LookupLoopIsZero: + cmp r12w, word ptr [r10 + r8] + BEFORE_JMP + jnz LookupLoop1 + AFTER_JMP + + +//;;; Store the current value of chainlen. + mov [chainlenwmask], edx +/* +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). +*/ + lea rsi,[r8+r10] + mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8) + lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8] + lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8] + + prefetcht1 [rsi+rdx] + prefetcht1 [rdi+rdx] + +/* +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust rdx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (rsi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. +*/ + +LoopCmps: + mov rax, [rsi + rdx] + xor rax, [rdi + rdx] + jnz LeaveLoopCmps + + mov rax, [rsi + rdx + 8] + xor rax, [rdi + rdx + 8] + jnz LeaveLoopCmps8 + + + mov rax, [rsi + rdx + 8+8] + xor rax, [rdi + rdx + 8+8] + jnz LeaveLoopCmps16 + + add rdx,8+8+8 + + BEFORE_JMP + jnz LoopCmps + jmp LenMaximum + AFTER_JMP + +LeaveLoopCmps16: add rdx,8 +LeaveLoopCmps8: add rdx,8 +LeaveLoopCmps: + + test eax, 0x0000FFFF + jnz LenLower + + test eax,0xffffffff + + jnz LenLower32 + + add rdx,4 + shr rax,32 + or ax,ax + BEFORE_JMP + jnz LenLower + AFTER_JMP + +LenLower32: + shr eax,16 + add rdx,2 + +LenLower: + sub al, 1 + adc rdx, 0 +//;;; Calculate the length of the match. If it is longer than MAX_MATCH, +//;;; then automatically accept it as the best possible match and leave. + + lea rax, [rdi + rdx] + sub rax, r9 + cmp eax, MAX_MATCH + BEFORE_JMP + jge LenMaximum + AFTER_JMP +/* +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. +;/////////////////////////////////// +*/ + cmp eax, r11d + jg LongerMatch + + lea rsi,[r10+r11] + + mov rdi, prev_ad + mov edx, [chainlenwmask] + BEFORE_JMP + jmp LookupLoop + AFTER_JMP +/* +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); +*/ +LongerMatch: + mov r11d, eax + mov match_start, r8d + cmp eax, [nicematch] + BEFORE_JMP + jge LeaveNow + AFTER_JMP + + lea rsi,[r10+rax] + + movzx ebx, word ptr [r9 + rax - 1] + mov rdi, prev_ad + mov edx, [chainlenwmask] + BEFORE_JMP + jmp LookupLoop + AFTER_JMP + +//;;; Accept the current string, with the maximum possible length. + +LenMaximum: + mov r11d,MAX_MATCH + mov match_start, r8d + +//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +//;;; return s->lookahead; + +LeaveNow: + mov eax, Lookahead + cmp r11d, eax + cmovng eax, r11d + + + +//;;; Restore the stack and return from whence we came. + + +// mov rsi,[save_rsi] +// mov rdi,[save_rdi] + mov rbx,[save_rbx] + mov rbp,[save_rbp] + mov r12,[save_r12] + mov r13,[save_r13] + mov r14,[save_r14] + mov r15,[save_r15] + + + ret 0 +//; please don't remove this string ! +//; Your can freely use gvmat64 in any free or commercial app +//; but it is far better don't remove the string in the binary! + // db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0 + + +match_init: + ret 0 + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/README b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/README new file mode 100644 index 00000000..e75ed132 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/README @@ -0,0 +1 @@ +See infback9.h for what this is and how to use it. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/infback9.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/infback9.c new file mode 100644 index 00000000..7bbe90ce --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/infback9.c @@ -0,0 +1,617 @@ +/* infback9.c -- inflate deflate64 data using a call-back interface + * Copyright (C) 1995-2008 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infback9.h" +#include "inftree9.h" +#include "inflate9.h" + +#define WSIZE 65536UL + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + window is a user-supplied window and output buffer that is 64K bytes. + */ +int ZEXPORT inflateBack9Init_(strm, window, version, stream_size) +z_stream FAR *strm; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (voidpf)state; + state->window = window; + return Z_OK; +} + +/* + Build and output length and distance decoding tables for fixed code + decoding. + */ +#ifdef MAKEFIXED +#include + +void makefixed9(void) +{ + unsigned sym, bits, low, size; + code *next, *lenfix, *distfix; + struct inflate_state state; + code fixed[544]; + + /* literal/length table */ + sym = 0; + while (sym < 144) state.lens[sym++] = 8; + while (sym < 256) state.lens[sym++] = 9; + while (sym < 280) state.lens[sym++] = 7; + while (sym < 288) state.lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work); + + /* distance table */ + sym = 0; + while (sym < 32) state.lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work); + + /* write tables */ + puts(" /* inffix9.h -- table for decoding deflate64 fixed codes"); + puts(" * Generated automatically by makefixed9()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits, + lenfix[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 5) == 0) printf("\n "); + printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits, + distfix[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* Macros for inflateBack(): */ + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n <= 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = window; \ + left = WSIZE; \ + wrap = 1; \ + if (out(out_desc, put, (unsigned)left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc) +z_stream FAR *strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have; /* available input */ + unsigned long left; /* available output */ + inflate_mode mode; /* current inflate mode */ + int lastblock; /* true if processing last block */ + int wrap; /* true if the window has wrapped */ + unsigned long write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned extra; /* extra bits needed */ + unsigned long length; /* literal or length of data to copy */ + unsigned long offset; /* distance back to copy string from */ + unsigned long copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +#include "inffix9.h" + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + mode = TYPE; + lastblock = 0; + write = 0; + wrap = 0; + window = state->window; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = window; + left = WSIZE; + lencode = Z_NULL; + distcode = Z_NULL; + + /* Inflate until end of block marked as last */ + for (;;) + switch (mode) { + case TYPE: + /* determine and dispatch block type */ + if (lastblock) { + BYTEBITS(); + mode = DONE; + break; + } + NEEDBITS(3); + lastblock = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + lastblock ? " (last)" : "")); + mode = STORED; + break; + case 1: /* fixed block */ + lencode = lenfix; + lenbits = 9; + distcode = distfix; + distbits = 5; + Tracev((stderr, "inflate: fixed codes block%s\n", + lastblock ? " (last)" : "")); + mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + lastblock ? " (last)" : "")); + mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + mode = BAD; + break; + } + length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %lu\n", + length)); + INITBITS(); + + /* copy stored block from input to output */ + while (length != 0) { + copy = length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); + if (state->nlen > 286) { + strm->msg = (char *)"too many length symbols"; + mode = BAD; + break; + } + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + lencode = (code const FAR *)(state->next); + lenbits = 7; + ret = inflate_table9(CODES, state->lens, 19, &(state->next), + &(lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = lencode[BITS(lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftree9.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + lencode = (code const FAR *)(state->next); + lenbits = 9; + ret = inflate_table9(LENS, state->lens, state->nlen, + &(state->next), &(lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + mode = BAD; + break; + } + distcode = (code const FAR *)(state->next); + distbits = 6; + ret = inflate_table9(DISTS, state->lens + state->nlen, + state->ndist, &(state->next), &(distbits), + state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + mode = LEN; + + case LEN: + /* get a literal, length, or end-of-block code */ + for (;;) { + here = lencode[BITS(lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(length); + left--; + mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + extra = (unsigned)(here.op) & 31; + if (extra != 0) { + NEEDBITS(extra); + length += BITS(extra); + DROPBITS(extra); + } + Tracevv((stderr, "inflate: length %lu\n", length)); + + /* get distance code */ + for (;;) { + here = distcode[BITS(distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + mode = BAD; + break; + } + offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + extra = (unsigned)(here.op) & 15; + if (extra != 0) { + NEEDBITS(extra); + offset += BITS(extra); + DROPBITS(extra); + } + if (offset > WSIZE - (wrap ? 0: left)) { + strm->msg = (char *)"invalid distance too far back"; + mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %lu\n", offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = WSIZE - offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - offset; + copy = left; + } + if (copy > length) copy = length; + length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < WSIZE) { + if (out(out_desc, window, (unsigned)(WSIZE - left))) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBack9End(strm) +z_stream FAR *strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/infback9.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/infback9.h new file mode 100644 index 00000000..1073c0a3 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/infback9.h @@ -0,0 +1,37 @@ +/* infback9.h -- header for using inflateBack9 functions + * Copyright (C) 2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * This header file and associated patches provide a decoder for PKWare's + * undocumented deflate64 compression method (method 9). Use with infback9.c, + * inftree9.h, inftree9.c, and inffix9.h. These patches are not supported. + * This should be compiled with zlib, since it uses zutil.h and zutil.o. + * This code has not yet been tested on 16-bit architectures. See the + * comments in zlib.h for inflateBack() usage. These functions are used + * identically, except that there is no windowBits parameter, and a 64K + * window must be provided. Also if int's are 16 bits, then a zero for + * the third parameter of the "out" function actually means 65536UL. + * zlib.h must be included before this header file. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +ZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm)); +ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define inflateBack9Init(strm, window) \ + inflateBack9Init_((strm), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +#ifdef __cplusplus +} +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inffix9.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inffix9.h new file mode 100644 index 00000000..ee5671d2 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inffix9.h @@ -0,0 +1,107 @@ + /* inffix9.h -- table for decoding deflate64 fixed codes + * Generated automatically by makefixed9(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112}, + {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160}, + {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88}, + {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208}, + {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136}, + {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227}, + {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232}, + {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124}, + {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184}, + {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82}, + {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196}, + {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130}, + {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148}, + {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106}, + {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244}, + {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118}, + {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172}, + {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94}, + {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220}, + {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131}, + {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97}, + {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226}, + {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121}, + {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178}, + {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85}, + {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202}, + {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133}, + {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154}, + {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109}, + {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250}, + {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115}, + {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166}, + {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91}, + {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214}, + {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139}, + {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0}, + {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103}, + {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238}, + {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127}, + {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80}, + {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193}, + {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128}, + {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145}, + {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104}, + {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241}, + {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116}, + {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169}, + {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92}, + {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217}, + {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140}, + {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163}, + {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98}, + {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122}, + {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181}, + {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86}, + {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205}, + {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134}, + {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157}, + {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253}, + {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113}, + {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163}, + {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89}, + {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211}, + {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137}, + {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3}, + {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101}, + {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235}, + {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125}, + {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187}, + {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83}, + {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199}, + {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151}, + {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107}, + {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247}, + {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119}, + {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175}, + {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95}, + {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223}, + {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143}, + {0,8,79},{0,9,255} + }; + + static const code distfix[32] = { + {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5}, + {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513}, + {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129}, + {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145}, + {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4}, + {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073}, + {134,5,193},{142,5,49153} + }; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inflate9.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inflate9.h new file mode 100644 index 00000000..ee9a7939 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inflate9.h @@ -0,0 +1,47 @@ +/* inflate9.h -- internal inflate state definition + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Possible inflate modes between inflate() calls */ +typedef enum { + TYPE, /* i: waiting for type bits, including last-flag bit */ + STORED, /* i: waiting for stored size (length and complement) */ + TABLE, /* i: waiting for dynamic block table lengths */ + LEN, /* i: waiting for length/lit code */ + DONE, /* finished check, done -- remain here until reset */ + BAD /* got a data error -- remain here until reset */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD mode -- not shown for clarity) + + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or DONE + STORED -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LEN or TYPE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + /* sliding window */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inftree9.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inftree9.c new file mode 100644 index 00000000..4ce2a1f1 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inftree9.c @@ -0,0 +1,324 @@ +/* inftree9.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftree9.h" + +#define MAXBITS 15 + +const char inflate9_copyright[] = + " inflate9 1.2.6 Copyright 1995-2012 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table9(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, + 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, + 131, 163, 195, 227, 3, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, + 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, + 133, 133, 133, 133, 144, 203, 69}; + static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, + 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, + 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153}; + static const unsigned short dext[32] = { /* Distance codes 0..31 extra */ + 128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, + 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138, + 139, 139, 140, 140, 141, 141, 142, 142}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) return -1; /* no codes! */ + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftree9.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += 1U << curr; + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + curr = root; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inftree9.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inftree9.h new file mode 100644 index 00000000..5ab21f0c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/infback9/inftree9.h @@ -0,0 +1,61 @@ +/* inftree9.h -- header to use inftree9.c + * Copyright (C) 1995-2008 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 100eeeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1446, which is the sum of 852 for literal/length codes and 594 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 32 6 15" for distance codes returns 594. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in infback9.c. If the root table size is changed, + then these maximum sizes would be need to be recalculated and updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 594 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table9() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table9 OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/inflate86/inffas86.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/inflate86/inffas86.c new file mode 100644 index 00000000..7292f67b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/inflate86/inffas86.c @@ -0,0 +1,1157 @@ +/* inffas86.c is a hand tuned assembler version of + * + * inffast.c -- fast decoding + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also + * slightly quicker on x86 systems because, instead of using rep movsb to copy + * data, it uses rep movsw, which moves data in 2-byte chunks instead of single + * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates + * from http://fedora.linux.duke.edu/fc1_x86_64 + * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with + * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version, + * when decompressing mozilla-source-1.3.tar.gz. + * + * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from + * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at + * the moment. I have successfully compiled and tested this code with gcc2.96, + * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S + * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX + * enabled. I will attempt to merge the MMX code into this version. Newer + * versions of this and inffast.S can be found at + * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* Mark Adler's comments from inffast.c: */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + struct inffast_ar { +/* 64 32 x86 x86_64 */ +/* ar offset register */ +/* 0 0 */ void *esp; /* esp save */ +/* 8 4 */ void *ebp; /* ebp save */ +/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */ +/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */ +/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */ +/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */ +/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */ +/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */ +/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */ +/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */ +/* 80 40 */ unsigned long hold; /* edx rdx local strm->hold */ +/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */ +/* 92 48 */ unsigned wsize; /* window size */ +/* 96 52 */ unsigned write; /* window write index */ +/*100 56 */ unsigned lmask; /* r12 mask for lcode */ +/*104 60 */ unsigned dmask; /* r13 mask for dcode */ +/*108 64 */ unsigned len; /* r14 match length */ +/*112 68 */ unsigned dist; /* r15 match distance */ +/*116 72 */ unsigned status; /* set when state chng*/ + } ar; + +#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 ) +#define PAD_AVAIL_IN 6 +#define PAD_AVAIL_OUT 258 +#else +#define PAD_AVAIL_IN 5 +#define PAD_AVAIL_OUT 257 +#endif + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + ar.in = strm->next_in; + ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN); + ar.out = strm->next_out; + ar.beg = ar.out - (start - strm->avail_out); + ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT); + ar.wsize = state->wsize; + ar.write = state->wnext; + ar.window = state->window; + ar.hold = state->hold; + ar.bits = state->bits; + ar.lcode = state->lencode; + ar.dcode = state->distcode; + ar.lmask = (1U << state->lenbits) - 1; + ar.dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + /* align in on 1/2 hold size boundary */ + while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) { + ar.hold += (unsigned long)*ar.in++ << ar.bits; + ar.bits += 8; + } + +#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 ) + __asm__ __volatile__ ( +" leaq %0, %%rax\n" +" movq %%rbp, 8(%%rax)\n" /* save regs rbp and rsp */ +" movq %%rsp, (%%rax)\n" +" movq %%rax, %%rsp\n" /* make rsp point to &ar */ +" movq 16(%%rsp), %%rsi\n" /* rsi = in */ +" movq 32(%%rsp), %%rdi\n" /* rdi = out */ +" movq 24(%%rsp), %%r9\n" /* r9 = last */ +" movq 48(%%rsp), %%r10\n" /* r10 = end */ +" movq 64(%%rsp), %%rbp\n" /* rbp = lcode */ +" movq 72(%%rsp), %%r11\n" /* r11 = dcode */ +" movq 80(%%rsp), %%rdx\n" /* rdx = hold */ +" movl 88(%%rsp), %%ebx\n" /* ebx = bits */ +" movl 100(%%rsp), %%r12d\n" /* r12d = lmask */ +" movl 104(%%rsp), %%r13d\n" /* r13d = dmask */ + /* r14d = len */ + /* r15d = dist */ +" cld\n" +" cmpq %%rdi, %%r10\n" +" je .L_one_time\n" /* if only one decode left */ +" cmpq %%rsi, %%r9\n" +" je .L_one_time\n" +" jmp .L_do_loop\n" + +".L_one_time:\n" +" movq %%r12, %%r8\n" /* r8 = lmask */ +" cmpb $32, %%bl\n" +" ja .L_get_length_code_one_time\n" + +" lodsl\n" /* eax = *(uint *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $32, %%bl\n" /* bits += 32 */ +" shlq %%cl, %%rax\n" +" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */ +" jmp .L_get_length_code_one_time\n" + +".align 32,0x90\n" +".L_while_test:\n" +" cmpq %%rdi, %%r10\n" +" jbe .L_break_loop\n" +" cmpq %%rsi, %%r9\n" +" jbe .L_break_loop\n" + +".L_do_loop:\n" +" movq %%r12, %%r8\n" /* r8 = lmask */ +" cmpb $32, %%bl\n" +" ja .L_get_length_code\n" /* if (32 < bits) */ + +" lodsl\n" /* eax = *(uint *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $32, %%bl\n" /* bits += 32 */ +" shlq %%cl, %%rax\n" +" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */ + +".L_get_length_code:\n" +" andq %%rdx, %%r8\n" /* r8 &= hold */ +" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */ + +" movb %%ah, %%cl\n" /* cl = this.bits */ +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrq %%cl, %%rdx\n" /* hold >>= this.bits */ + +" testb %%al, %%al\n" +" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */ + +" movq %%r12, %%r8\n" /* r8 = lmask */ +" shrl $16, %%eax\n" /* output this.val char */ +" stosb\n" + +".L_get_length_code_one_time:\n" +" andq %%rdx, %%r8\n" /* r8 &= hold */ +" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */ + +".L_dolen:\n" +" movb %%ah, %%cl\n" /* cl = this.bits */ +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrq %%cl, %%rdx\n" /* hold >>= this.bits */ + +" testb %%al, %%al\n" +" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */ + +" shrl $16, %%eax\n" /* output this.val char */ +" stosb\n" +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_length_base:\n" +" movl %%eax, %%r14d\n" /* len = this */ +" shrl $16, %%r14d\n" /* len = this.val */ +" movb %%al, %%cl\n" + +" testb $16, %%al\n" +" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */ +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_decode_distance\n" /* if (!op) */ + +".L_add_bits_to_len:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrq %%cl, %%rdx\n" +" addl %%eax, %%r14d\n" /* len += hold & mask[op] */ + +".L_decode_distance:\n" +" movq %%r13, %%r8\n" /* r8 = dmask */ +" cmpb $32, %%bl\n" +" ja .L_get_distance_code\n" /* if (32 < bits) */ + +" lodsl\n" /* eax = *(uint *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $32, %%bl\n" /* bits += 32 */ +" shlq %%cl, %%rax\n" +" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */ + +".L_get_distance_code:\n" +" andq %%rdx, %%r8\n" /* r8 &= hold */ +" movl (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */ + +".L_dodist:\n" +" movl %%eax, %%r15d\n" /* dist = this */ +" shrl $16, %%r15d\n" /* dist = this.val */ +" movb %%ah, %%cl\n" +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrq %%cl, %%rdx\n" /* hold >>= this.bits */ +" movb %%al, %%cl\n" /* cl = this.op */ + +" testb $16, %%al\n" /* if ((op & 16) == 0) */ +" jz .L_test_for_second_level_dist\n" +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_check_dist_one\n" + +".L_add_bits_to_dist:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" /* (1 << op) - 1 */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrq %%cl, %%rdx\n" +" addl %%eax, %%r15d\n" /* dist += hold & ((1 << op) - 1) */ + +".L_check_window:\n" +" movq %%rsi, %%r8\n" /* save in so from can use it's reg */ +" movq %%rdi, %%rax\n" +" subq 40(%%rsp), %%rax\n" /* nbytes = out - beg */ + +" cmpl %%r15d, %%eax\n" +" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */ + +" movl %%r14d, %%ecx\n" /* ecx = len */ +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = out - dist */ + +" sarl %%ecx\n" +" jnc .L_copy_two\n" /* if len % 2 == 0 */ + +" rep movsw\n" +" movb (%%rsi), %%al\n" +" movb %%al, (%%rdi)\n" +" incq %%rdi\n" + +" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */ +" jmp .L_while_test\n" + +".L_copy_two:\n" +" rep movsw\n" +" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */ +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_check_dist_one:\n" +" cmpl $1, %%r15d\n" /* if dist 1, is a memset */ +" jne .L_check_window\n" +" cmpq %%rdi, 40(%%rsp)\n" /* if out == beg, outside window */ +" je .L_check_window\n" + +" movl %%r14d, %%ecx\n" /* ecx = len */ +" movb -1(%%rdi), %%al\n" +" movb %%al, %%ah\n" + +" sarl %%ecx\n" +" jnc .L_set_two\n" +" movb %%al, (%%rdi)\n" +" incq %%rdi\n" + +".L_set_two:\n" +" rep stosw\n" +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_second_level_length:\n" +" testb $64, %%al\n" +" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl %%r14d, %%eax\n" /* eax += len */ +" movl (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/ +" jmp .L_dolen\n" + +".align 32,0x90\n" +".L_test_for_second_level_dist:\n" +" testb $64, %%al\n" +" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl %%r15d, %%eax\n" /* eax += dist */ +" movl (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/ +" jmp .L_dodist\n" + +".align 32,0x90\n" +".L_clip_window:\n" +" movl %%eax, %%ecx\n" /* ecx = nbytes */ +" movl 92(%%rsp), %%eax\n" /* eax = wsize, prepare for dist cmp */ +" negl %%ecx\n" /* nbytes = -nbytes */ + +" cmpl %%r15d, %%eax\n" +" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */ + +" addl %%r15d, %%ecx\n" /* nbytes = dist - nbytes */ +" cmpl $0, 96(%%rsp)\n" +" jne .L_wrap_around_window\n" /* if (write != 0) */ + +" movq 56(%%rsp), %%rsi\n" /* from = window */ +" subl %%ecx, %%eax\n" /* eax -= nbytes */ +" addq %%rax, %%rsi\n" /* from += wsize - nbytes */ + +" movl %%r14d, %%eax\n" /* eax = len */ +" cmpl %%ecx, %%r14d\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* eax -= nbytes */ +" rep movsb\n" +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = &out[ -dist ] */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_wrap_around_window:\n" +" movl 96(%%rsp), %%eax\n" /* eax = write */ +" cmpl %%eax, %%ecx\n" +" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */ + +" movl 92(%%rsp), %%esi\n" /* from = wsize */ +" addq 56(%%rsp), %%rsi\n" /* from += window */ +" addq %%rax, %%rsi\n" /* from += write */ +" subq %%rcx, %%rsi\n" /* from -= nbytes */ +" subl %%eax, %%ecx\n" /* nbytes -= write */ + +" movl %%r14d, %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movq 56(%%rsp), %%rsi\n" /* from = window */ +" movl 96(%%rsp), %%ecx\n" /* nbytes = write */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = out - dist */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_contiguous_in_window:\n" +" movq 56(%%rsp), %%rsi\n" /* rsi = window */ +" addq %%rax, %%rsi\n" +" subq %%rcx, %%rsi\n" /* from += write - nbytes */ + +" movl %%r14d, %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = out - dist */ +" jmp .L_do_copy\n" /* if (nbytes >= len) */ + +".align 32,0x90\n" +".L_do_copy:\n" +" movl %%eax, %%ecx\n" /* ecx = len */ +" rep movsb\n" + +" movq %%r8, %%rsi\n" /* move in back to %esi, toss from */ +" jmp .L_while_test\n" + +".L_test_for_end_of_block:\n" +" testb $32, %%al\n" +" jz .L_invalid_literal_length_code\n" +" movl $1, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_literal_length_code:\n" +" movl $2, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_code:\n" +" movl $3, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_too_far:\n" +" movl $4, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_break_loop:\n" +" movl $0, 116(%%rsp)\n" + +".L_break_loop_with_status:\n" +/* put in, out, bits, and hold back into ar and pop esp */ +" movq %%rsi, 16(%%rsp)\n" /* in */ +" movq %%rdi, 32(%%rsp)\n" /* out */ +" movl %%ebx, 88(%%rsp)\n" /* bits */ +" movq %%rdx, 80(%%rsp)\n" /* hold */ +" movq (%%rsp), %%rax\n" /* restore rbp and rsp */ +" movq 8(%%rsp), %%rbp\n" +" movq %%rax, %%rsp\n" + : + : "m" (ar) + : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" + ); +#elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 ) + __asm__ __volatile__ ( +" leal %0, %%eax\n" +" movl %%esp, (%%eax)\n" /* save esp, ebp */ +" movl %%ebp, 4(%%eax)\n" +" movl %%eax, %%esp\n" +" movl 8(%%esp), %%esi\n" /* esi = in */ +" movl 16(%%esp), %%edi\n" /* edi = out */ +" movl 40(%%esp), %%edx\n" /* edx = hold */ +" movl 44(%%esp), %%ebx\n" /* ebx = bits */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ + +" cld\n" +" jmp .L_do_loop\n" + +".align 32,0x90\n" +".L_while_test:\n" +" cmpl %%edi, 24(%%esp)\n" /* out < end */ +" jbe .L_break_loop\n" +" cmpl %%esi, 12(%%esp)\n" /* in < last */ +" jbe .L_break_loop\n" + +".L_do_loop:\n" +" cmpb $15, %%bl\n" +" ja .L_get_length_code\n" /* if (15 < bits) */ + +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ + +".L_get_length_code:\n" +" movl 56(%%esp), %%eax\n" /* eax = lmask */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */ + +".L_dolen:\n" +" movb %%ah, %%cl\n" /* cl = this.bits */ +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrl %%cl, %%edx\n" /* hold >>= this.bits */ + +" testb %%al, %%al\n" +" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */ + +" shrl $16, %%eax\n" /* output this.val char */ +" stosb\n" +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_length_base:\n" +" movl %%eax, %%ecx\n" /* len = this */ +" shrl $16, %%ecx\n" /* len = this.val */ +" movl %%ecx, 64(%%esp)\n" /* save len */ +" movb %%al, %%cl\n" + +" testb $16, %%al\n" +" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */ +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_decode_distance\n" /* if (!op) */ +" cmpb %%cl, %%bl\n" +" jae .L_add_bits_to_len\n" /* if (op <= bits) */ + +" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */ +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ +" movb %%ch, %%cl\n" /* move op back to ecx */ + +".L_add_bits_to_len:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrl %%cl, %%edx\n" +" addl %%eax, 64(%%esp)\n" /* len += hold & mask[op] */ + +".L_decode_distance:\n" +" cmpb $15, %%bl\n" +" ja .L_get_distance_code\n" /* if (15 < bits) */ + +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ + +".L_get_distance_code:\n" +" movl 60(%%esp), %%eax\n" /* eax = dmask */ +" movl 36(%%esp), %%ecx\n" /* ecx = dcode */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */ + +".L_dodist:\n" +" movl %%eax, %%ebp\n" /* dist = this */ +" shrl $16, %%ebp\n" /* dist = this.val */ +" movb %%ah, %%cl\n" +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrl %%cl, %%edx\n" /* hold >>= this.bits */ +" movb %%al, %%cl\n" /* cl = this.op */ + +" testb $16, %%al\n" /* if ((op & 16) == 0) */ +" jz .L_test_for_second_level_dist\n" +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_check_dist_one\n" +" cmpb %%cl, %%bl\n" +" jae .L_add_bits_to_dist\n" /* if (op <= bits) 97.6% */ + +" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */ +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ +" movb %%ch, %%cl\n" /* move op back to ecx */ + +".L_add_bits_to_dist:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" /* (1 << op) - 1 */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrl %%cl, %%edx\n" +" addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */ + +".L_check_window:\n" +" movl %%esi, 8(%%esp)\n" /* save in so from can use it's reg */ +" movl %%edi, %%eax\n" +" subl 20(%%esp), %%eax\n" /* nbytes = out - beg */ + +" cmpl %%ebp, %%eax\n" +" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */ + +" movl 64(%%esp), %%ecx\n" /* ecx = len */ +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ + +" sarl %%ecx\n" +" jnc .L_copy_two\n" /* if len % 2 == 0 */ + +" rep movsw\n" +" movb (%%esi), %%al\n" +" movb %%al, (%%edi)\n" +" incl %%edi\n" + +" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".L_copy_two:\n" +" rep movsw\n" +" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_check_dist_one:\n" +" cmpl $1, %%ebp\n" /* if dist 1, is a memset */ +" jne .L_check_window\n" +" cmpl %%edi, 20(%%esp)\n" +" je .L_check_window\n" /* out == beg, if outside window */ + +" movl 64(%%esp), %%ecx\n" /* ecx = len */ +" movb -1(%%edi), %%al\n" +" movb %%al, %%ah\n" + +" sarl %%ecx\n" +" jnc .L_set_two\n" +" movb %%al, (%%edi)\n" +" incl %%edi\n" + +".L_set_two:\n" +" rep stosw\n" +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_second_level_length:\n" +" testb $64, %%al\n" +" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl 64(%%esp), %%eax\n" /* eax += len */ +" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/ +" jmp .L_dolen\n" + +".align 32,0x90\n" +".L_test_for_second_level_dist:\n" +" testb $64, %%al\n" +" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl %%ebp, %%eax\n" /* eax += dist */ +" movl 36(%%esp), %%ecx\n" /* ecx = dcode */ +" movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/ +" jmp .L_dodist\n" + +".align 32,0x90\n" +".L_clip_window:\n" +" movl %%eax, %%ecx\n" +" movl 48(%%esp), %%eax\n" /* eax = wsize */ +" negl %%ecx\n" /* nbytes = -nbytes */ +" movl 28(%%esp), %%esi\n" /* from = window */ + +" cmpl %%ebp, %%eax\n" +" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */ + +" addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */ +" cmpl $0, 52(%%esp)\n" +" jne .L_wrap_around_window\n" /* if (write != 0) */ + +" subl %%ecx, %%eax\n" +" addl %%eax, %%esi\n" /* from += wsize - nbytes */ + +" movl 64(%%esp), %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_wrap_around_window:\n" +" movl 52(%%esp), %%eax\n" /* eax = write */ +" cmpl %%eax, %%ecx\n" +" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */ + +" addl 48(%%esp), %%esi\n" /* from += wsize */ +" addl %%eax, %%esi\n" /* from += write */ +" subl %%ecx, %%esi\n" /* from -= nbytes */ +" subl %%eax, %%ecx\n" /* nbytes -= write */ + +" movl 64(%%esp), %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl 28(%%esp), %%esi\n" /* from = window */ +" movl 52(%%esp), %%ecx\n" /* nbytes = write */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_contiguous_in_window:\n" +" addl %%eax, %%esi\n" +" subl %%ecx, %%esi\n" /* from += write - nbytes */ + +" movl 64(%%esp), %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ +" jmp .L_do_copy\n" /* if (nbytes >= len) */ + +".align 32,0x90\n" +".L_do_copy:\n" +" movl %%eax, %%ecx\n" +" rep movsb\n" + +" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".L_test_for_end_of_block:\n" +" testb $32, %%al\n" +" jz .L_invalid_literal_length_code\n" +" movl $1, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_literal_length_code:\n" +" movl $2, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_code:\n" +" movl $3, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_too_far:\n" +" movl 8(%%esp), %%esi\n" +" movl $4, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_break_loop:\n" +" movl $0, 72(%%esp)\n" + +".L_break_loop_with_status:\n" +/* put in, out, bits, and hold back into ar and pop esp */ +" movl %%esi, 8(%%esp)\n" /* save in */ +" movl %%edi, 16(%%esp)\n" /* save out */ +" movl %%ebx, 44(%%esp)\n" /* save bits */ +" movl %%edx, 40(%%esp)\n" /* save hold */ +" movl 4(%%esp), %%ebp\n" /* restore esp, ebp */ +" movl (%%esp), %%esp\n" + : + : "m" (ar) + : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" + ); +#elif defined( _MSC_VER ) && ! defined( _M_AMD64 ) + __asm { + lea eax, ar + mov [eax], esp /* save esp, ebp */ + mov [eax+4], ebp + mov esp, eax + mov esi, [esp+8] /* esi = in */ + mov edi, [esp+16] /* edi = out */ + mov edx, [esp+40] /* edx = hold */ + mov ebx, [esp+44] /* ebx = bits */ + mov ebp, [esp+32] /* ebp = lcode */ + + cld + jmp L_do_loop + +ALIGN 4 +L_while_test: + cmp [esp+24], edi + jbe L_break_loop + cmp [esp+12], esi + jbe L_break_loop + +L_do_loop: + cmp bl, 15 + ja L_get_length_code /* if (15 < bits) */ + + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + +L_get_length_code: + mov eax, [esp+56] /* eax = lmask */ + and eax, edx /* eax &= hold */ + mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */ + +L_dolen: + mov cl, ah /* cl = this.bits */ + sub bl, ah /* bits -= this.bits */ + shr edx, cl /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base /* if (op != 0) 45.7% */ + + shr eax, 16 /* output this.val char */ + stosb + jmp L_while_test + +ALIGN 4 +L_test_for_length_base: + mov ecx, eax /* len = this */ + shr ecx, 16 /* len = this.val */ + mov [esp+64], ecx /* save len */ + mov cl, al + + test al, 16 + jz L_test_for_second_level_length /* if ((op & 16) == 0) 8% */ + and cl, 15 /* op &= 15 */ + jz L_decode_distance /* if (!op) */ + cmp bl, cl + jae L_add_bits_to_len /* if (op <= bits) */ + + mov ch, cl /* stash op in ch, freeing cl */ + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + mov cl, ch /* move op back to ecx */ + +L_add_bits_to_len: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx /* eax &= hold */ + shr edx, cl + add [esp+64], eax /* len += hold & mask[op] */ + +L_decode_distance: + cmp bl, 15 + ja L_get_distance_code /* if (15 < bits) */ + + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + +L_get_distance_code: + mov eax, [esp+60] /* eax = dmask */ + mov ecx, [esp+36] /* ecx = dcode */ + and eax, edx /* eax &= hold */ + mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */ + +L_dodist: + mov ebp, eax /* dist = this */ + shr ebp, 16 /* dist = this.val */ + mov cl, ah + sub bl, ah /* bits -= this.bits */ + shr edx, cl /* hold >>= this.bits */ + mov cl, al /* cl = this.op */ + + test al, 16 /* if ((op & 16) == 0) */ + jz L_test_for_second_level_dist + and cl, 15 /* op &= 15 */ + jz L_check_dist_one + cmp bl, cl + jae L_add_bits_to_dist /* if (op <= bits) 97.6% */ + + mov ch, cl /* stash op in ch, freeing cl */ + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + mov cl, ch /* move op back to ecx */ + +L_add_bits_to_dist: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax /* (1 << op) - 1 */ + and eax, edx /* eax &= hold */ + shr edx, cl + add ebp, eax /* dist += hold & ((1 << op) - 1) */ + +L_check_window: + mov [esp+8], esi /* save in so from can use it's reg */ + mov eax, edi + sub eax, [esp+20] /* nbytes = out - beg */ + + cmp eax, ebp + jb L_clip_window /* if (dist > nbytes) 4.2% */ + + mov ecx, [esp+64] /* ecx = len */ + mov esi, edi + sub esi, ebp /* from = out - dist */ + + sar ecx, 1 + jnc L_copy_two + + rep movsw + mov al, [esi] + mov [edi], al + inc edi + + mov esi, [esp+8] /* move in back to %esi, toss from */ + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +L_copy_two: + rep movsw + mov esi, [esp+8] /* move in back to %esi, toss from */ + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp ebp, 1 /* if dist 1, is a memset */ + jne L_check_window + cmp [esp+20], edi + je L_check_window /* out == beg, if outside window */ + + mov ecx, [esp+64] /* ecx = len */ + mov al, [edi-1] + mov ah, al + + sar ecx, 1 + jnc L_set_two + mov [edi], al /* memset out with from[-1] */ + inc edi + +L_set_two: + rep stosw + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + test al, 64 + jnz L_test_for_end_of_block /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx /* eax &= hold */ + add eax, [esp+64] /* eax += len */ + mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/ + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + test al, 64 + jnz L_invalid_distance_code /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx /* eax &= hold */ + add eax, ebp /* eax += dist */ + mov ecx, [esp+36] /* ecx = dcode */ + mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/ + jmp L_dodist + +ALIGN 4 +L_clip_window: + mov ecx, eax + mov eax, [esp+48] /* eax = wsize */ + neg ecx /* nbytes = -nbytes */ + mov esi, [esp+28] /* from = window */ + + cmp eax, ebp + jb L_invalid_distance_too_far /* if (dist > wsize) */ + + add ecx, ebp /* nbytes = dist - nbytes */ + cmp dword ptr [esp+52], 0 + jne L_wrap_around_window /* if (write != 0) */ + + sub eax, ecx + add esi, eax /* from += wsize - nbytes */ + + mov eax, [esp+64] /* eax = len */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, edi + sub esi, ebp /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_wrap_around_window: + mov eax, [esp+52] /* eax = write */ + cmp ecx, eax + jbe L_contiguous_in_window /* if (write >= nbytes) */ + + add esi, [esp+48] /* from += wsize */ + add esi, eax /* from += write */ + sub esi, ecx /* from -= nbytes */ + sub ecx, eax /* nbytes -= write */ + + mov eax, [esp+64] /* eax = len */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, [esp+28] /* from = window */ + mov ecx, [esp+52] /* nbytes = write */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, edi + sub esi, ebp /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_contiguous_in_window: + add esi, eax + sub esi, ecx /* from += write - nbytes */ + + mov eax, [esp+64] /* eax = len */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, edi + sub esi, ebp /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_do_copy: + mov ecx, eax + rep movsb + + mov esi, [esp+8] /* move in back to %esi, toss from */ + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +L_test_for_end_of_block: + test al, 32 + jz L_invalid_literal_length_code + mov dword ptr [esp+72], 1 + jmp L_break_loop_with_status + +L_invalid_literal_length_code: + mov dword ptr [esp+72], 2 + jmp L_break_loop_with_status + +L_invalid_distance_code: + mov dword ptr [esp+72], 3 + jmp L_break_loop_with_status + +L_invalid_distance_too_far: + mov esi, [esp+4] + mov dword ptr [esp+72], 4 + jmp L_break_loop_with_status + +L_break_loop: + mov dword ptr [esp+72], 0 + +L_break_loop_with_status: +/* put in, out, bits, and hold back into ar and pop esp */ + mov [esp+8], esi /* save in */ + mov [esp+16], edi /* save out */ + mov [esp+44], ebx /* save bits */ + mov [esp+40], edx /* save hold */ + mov ebp, [esp+4] /* restore esp, ebp */ + mov esp, [esp] + } +#else +#error "x86 architecture not defined" +#endif + + if (ar.status > 1) { + if (ar.status == 2) + strm->msg = "invalid literal/length code"; + else if (ar.status == 3) + strm->msg = "invalid distance code"; + else + strm->msg = "invalid distance too far back"; + state->mode = BAD; + } + else if ( ar.status == 1 ) { + state->mode = TYPE; + } + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + ar.len = ar.bits >> 3; + ar.in -= ar.len; + ar.bits -= ar.len << 3; + ar.hold &= (1U << ar.bits) - 1; + + /* update state and return */ + strm->next_in = ar.in; + strm->next_out = ar.out; + strm->avail_in = (unsigned)(ar.in < ar.last ? + PAD_AVAIL_IN + (ar.last - ar.in) : + PAD_AVAIL_IN - (ar.in - ar.last)); + strm->avail_out = (unsigned)(ar.out < ar.end ? + PAD_AVAIL_OUT + (ar.end - ar.out) : + PAD_AVAIL_OUT - (ar.out - ar.end)); + state->hold = ar.hold; + state->bits = ar.bits; + return; +} + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/inflate86/inffast.S b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/inflate86/inffast.S new file mode 100644 index 00000000..2245a290 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/inflate86/inffast.S @@ -0,0 +1,1368 @@ +/* + * inffast.S is a hand tuned assembler version of: + * + * inffast.c -- fast decoding + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * This version (Jan-23-2003) of inflate_fast was coded and tested under + * GNU/Linux on a pentium 3, using the gcc-3.2 compiler distribution. On that + * machine, I found that gzip style archives decompressed about 20% faster than + * the gcc-3.2 -O3 -fomit-frame-pointer compiled version. Your results will + * depend on how large of a buffer is used for z_stream.next_in & next_out + * (8K-32K worked best for my 256K cpu cache) and how much overhead there is in + * stream processing I/O and crc32/addler32. In my case, this routine used + * 70% of the cpu time and crc32 used 20%. + * + * I am confident that this version will work in the general case, but I have + * not tested a wide variety of datasets or a wide variety of platforms. + * + * Jan-24-2003 -- Added -DUSE_MMX define for slightly faster inflating. + * It should be a runtime flag instead of compile time flag... + * + * Jan-26-2003 -- Added runtime check for MMX support with cpuid instruction. + * With -DUSE_MMX, only MMX code is compiled. With -DNO_MMX, only non-MMX code + * is compiled. Without either option, runtime detection is enabled. Runtime + * detection should work on all modern cpus and the recomended algorithm (flip + * ID bit on eflags and then use the cpuid instruction) is used in many + * multimedia applications. Tested under win2k with gcc-2.95 and gas-2.12 + * distributed with cygwin3. Compiling with gcc-2.95 -c inffast.S -o + * inffast.obj generates a COFF object which can then be linked with MSVC++ + * compiled code. Tested under FreeBSD 4.7 with gcc-2.95. + * + * Jan-28-2003 -- Tested Athlon XP... MMX mode is slower than no MMX (and + * slower than compiler generated code). Adjusted cpuid check to use the MMX + * code only for Pentiums < P4 until I have more data on the P4. Speed + * improvment is only about 15% on the Athlon when compared with code generated + * with MSVC++. Not sure yet, but I think the P4 will also be slower using the + * MMX mode because many of it's x86 ALU instructions execute in .5 cycles and + * have less latency than MMX ops. Added code to buffer the last 11 bytes of + * the input stream since the MMX code grabs bits in chunks of 32, which + * differs from the inffast.c algorithm. I don't think there would have been + * read overruns where a page boundary was crossed (a segfault), but there + * could have been overruns when next_in ends on unaligned memory (unintialized + * memory read). + * + * Mar-13-2003 -- P4 MMX is slightly slower than P4 NO_MMX. I created a C + * version of the non-MMX code so that it doesn't depend on zstrm and zstate + * structure offsets which are hard coded in this file. This was last tested + * with zlib-1.2.0 which is currently in beta testing, newer versions of this + * and inffas86.c can be found at http://www.eetbeetee.com/zlib/ and + * http://www.charm.net/~christop/zlib/ + */ + + +/* + * if you have underscore linking problems (_inflate_fast undefined), try + * using -DGAS_COFF + */ +#if ! defined( GAS_COFF ) && ! defined( GAS_ELF ) + +#if defined( WIN32 ) || defined( __CYGWIN__ ) +#define GAS_COFF /* windows object format */ +#else +#define GAS_ELF +#endif + +#endif /* ! GAS_COFF && ! GAS_ELF */ + + +#if defined( GAS_COFF ) + +/* coff externals have underscores */ +#define inflate_fast _inflate_fast +#define inflate_fast_use_mmx _inflate_fast_use_mmx + +#endif /* GAS_COFF */ + + +.file "inffast.S" + +.globl inflate_fast + +.text +.align 4,0 +.L_invalid_literal_length_code_msg: +.string "invalid literal/length code" + +.align 4,0 +.L_invalid_distance_code_msg: +.string "invalid distance code" + +.align 4,0 +.L_invalid_distance_too_far_msg: +.string "invalid distance too far back" + +#if ! defined( NO_MMX ) +.align 4,0 +.L_mask: /* mask[N] = ( 1 << N ) - 1 */ +.long 0 +.long 1 +.long 3 +.long 7 +.long 15 +.long 31 +.long 63 +.long 127 +.long 255 +.long 511 +.long 1023 +.long 2047 +.long 4095 +.long 8191 +.long 16383 +.long 32767 +.long 65535 +.long 131071 +.long 262143 +.long 524287 +.long 1048575 +.long 2097151 +.long 4194303 +.long 8388607 +.long 16777215 +.long 33554431 +.long 67108863 +.long 134217727 +.long 268435455 +.long 536870911 +.long 1073741823 +.long 2147483647 +.long 4294967295 +#endif /* NO_MMX */ + +.text + +/* + * struct z_stream offsets, in zlib.h + */ +#define next_in_strm 0 /* strm->next_in */ +#define avail_in_strm 4 /* strm->avail_in */ +#define next_out_strm 12 /* strm->next_out */ +#define avail_out_strm 16 /* strm->avail_out */ +#define msg_strm 24 /* strm->msg */ +#define state_strm 28 /* strm->state */ + +/* + * struct inflate_state offsets, in inflate.h + */ +#define mode_state 0 /* state->mode */ +#define wsize_state 32 /* state->wsize */ +#define write_state 40 /* state->write */ +#define window_state 44 /* state->window */ +#define hold_state 48 /* state->hold */ +#define bits_state 52 /* state->bits */ +#define lencode_state 68 /* state->lencode */ +#define distcode_state 72 /* state->distcode */ +#define lenbits_state 76 /* state->lenbits */ +#define distbits_state 80 /* state->distbits */ + +/* + * inflate_fast's activation record + */ +#define local_var_size 64 /* how much local space for vars */ +#define strm_sp 88 /* first arg: z_stream * (local_var_size + 24) */ +#define start_sp 92 /* second arg: unsigned int (local_var_size + 28) */ + +/* + * offsets for local vars on stack + */ +#define out 60 /* unsigned char* */ +#define window 56 /* unsigned char* */ +#define wsize 52 /* unsigned int */ +#define write 48 /* unsigned int */ +#define in 44 /* unsigned char* */ +#define beg 40 /* unsigned char* */ +#define buf 28 /* char[ 12 ] */ +#define len 24 /* unsigned int */ +#define last 20 /* unsigned char* */ +#define end 16 /* unsigned char* */ +#define dcode 12 /* code* */ +#define lcode 8 /* code* */ +#define dmask 4 /* unsigned int */ +#define lmask 0 /* unsigned int */ + +/* + * typedef enum inflate_mode consts, in inflate.h + */ +#define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */ +#define INFLATE_MODE_BAD 26 + + +#if ! defined( USE_MMX ) && ! defined( NO_MMX ) + +#define RUN_TIME_MMX + +#define CHECK_MMX 1 +#define DO_USE_MMX 2 +#define DONT_USE_MMX 3 + +.globl inflate_fast_use_mmx + +.data + +.align 4,0 +inflate_fast_use_mmx: /* integer flag for run time control 1=check,2=mmx,3=no */ +.long CHECK_MMX + +#if defined( GAS_ELF ) +/* elf info */ +.type inflate_fast_use_mmx,@object +.size inflate_fast_use_mmx,4 +#endif + +#endif /* RUN_TIME_MMX */ + +#if defined( GAS_COFF ) +/* coff info: scl 2 = extern, type 32 = function */ +.def inflate_fast; .scl 2; .type 32; .endef +#endif + +.text + +.align 32,0x90 +inflate_fast: + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + pushf /* save eflags (strm_sp, state_sp assumes this is 32 bits) */ + subl $local_var_size, %esp + cld + +#define strm_r %esi +#define state_r %edi + + movl strm_sp(%esp), strm_r + movl state_strm(strm_r), state_r + + /* in = strm->next_in; + * out = strm->next_out; + * last = in + strm->avail_in - 11; + * beg = out - (start - strm->avail_out); + * end = out + (strm->avail_out - 257); + */ + movl avail_in_strm(strm_r), %edx + movl next_in_strm(strm_r), %eax + + addl %eax, %edx /* avail_in += next_in */ + subl $11, %edx /* avail_in -= 11 */ + + movl %eax, in(%esp) + movl %edx, last(%esp) + + movl start_sp(%esp), %ebp + movl avail_out_strm(strm_r), %ecx + movl next_out_strm(strm_r), %ebx + + subl %ecx, %ebp /* start -= avail_out */ + negl %ebp /* start = -start */ + addl %ebx, %ebp /* start += next_out */ + + subl $257, %ecx /* avail_out -= 257 */ + addl %ebx, %ecx /* avail_out += out */ + + movl %ebx, out(%esp) + movl %ebp, beg(%esp) + movl %ecx, end(%esp) + + /* wsize = state->wsize; + * write = state->write; + * window = state->window; + * hold = state->hold; + * bits = state->bits; + * lcode = state->lencode; + * dcode = state->distcode; + * lmask = ( 1 << state->lenbits ) - 1; + * dmask = ( 1 << state->distbits ) - 1; + */ + + movl lencode_state(state_r), %eax + movl distcode_state(state_r), %ecx + + movl %eax, lcode(%esp) + movl %ecx, dcode(%esp) + + movl $1, %eax + movl lenbits_state(state_r), %ecx + shll %cl, %eax + decl %eax + movl %eax, lmask(%esp) + + movl $1, %eax + movl distbits_state(state_r), %ecx + shll %cl, %eax + decl %eax + movl %eax, dmask(%esp) + + movl wsize_state(state_r), %eax + movl write_state(state_r), %ecx + movl window_state(state_r), %edx + + movl %eax, wsize(%esp) + movl %ecx, write(%esp) + movl %edx, window(%esp) + + movl hold_state(state_r), %ebp + movl bits_state(state_r), %ebx + +#undef strm_r +#undef state_r + +#define in_r %esi +#define from_r %esi +#define out_r %edi + + movl in(%esp), in_r + movl last(%esp), %ecx + cmpl in_r, %ecx + ja .L_align_long /* if in < last */ + + addl $11, %ecx /* ecx = &in[ avail_in ] */ + subl in_r, %ecx /* ecx = avail_in */ + movl $12, %eax + subl %ecx, %eax /* eax = 12 - avail_in */ + leal buf(%esp), %edi + rep movsb /* memcpy( buf, in, avail_in ) */ + movl %eax, %ecx + xorl %eax, %eax + rep stosb /* memset( &buf[ avail_in ], 0, 12 - avail_in ) */ + leal buf(%esp), in_r /* in = buf */ + movl in_r, last(%esp) /* last = in, do just one iteration */ + jmp .L_is_aligned + + /* align in_r on long boundary */ +.L_align_long: + testl $3, in_r + jz .L_is_aligned + xorl %eax, %eax + movb (in_r), %al + incl in_r + movl %ebx, %ecx + addl $8, %ebx + shll %cl, %eax + orl %eax, %ebp + jmp .L_align_long + +.L_is_aligned: + movl out(%esp), out_r + +#if defined( NO_MMX ) + jmp .L_do_loop +#endif + +#if defined( USE_MMX ) + jmp .L_init_mmx +#endif + +/*** Runtime MMX check ***/ + +#if defined( RUN_TIME_MMX ) +.L_check_mmx: + cmpl $DO_USE_MMX, inflate_fast_use_mmx + je .L_init_mmx + ja .L_do_loop /* > 2 */ + + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + pushf + movl (%esp), %eax /* copy eflags to eax */ + xorl $0x200000, (%esp) /* try toggling ID bit of eflags (bit 21) + * to see if cpu supports cpuid... + * ID bit method not supported by NexGen but + * bios may load a cpuid instruction and + * cpuid may be disabled on Cyrix 5-6x86 */ + popf + pushf + popl %edx /* copy new eflags to edx */ + xorl %eax, %edx /* test if ID bit is flipped */ + jz .L_dont_use_mmx /* not flipped if zero */ + xorl %eax, %eax + cpuid + cmpl $0x756e6547, %ebx /* check for GenuineIntel in ebx,ecx,edx */ + jne .L_dont_use_mmx + cmpl $0x6c65746e, %ecx + jne .L_dont_use_mmx + cmpl $0x49656e69, %edx + jne .L_dont_use_mmx + movl $1, %eax + cpuid /* get cpu features */ + shrl $8, %eax + andl $15, %eax + cmpl $6, %eax /* check for Pentium family, is 0xf for P4 */ + jne .L_dont_use_mmx + testl $0x800000, %edx /* test if MMX feature is set (bit 23) */ + jnz .L_use_mmx + jmp .L_dont_use_mmx +.L_use_mmx: + movl $DO_USE_MMX, inflate_fast_use_mmx + jmp .L_check_mmx_pop +.L_dont_use_mmx: + movl $DONT_USE_MMX, inflate_fast_use_mmx +.L_check_mmx_pop: + popl %edx + popl %ecx + popl %ebx + popl %eax + jmp .L_check_mmx +#endif + + +/*** Non-MMX code ***/ + +#if defined ( NO_MMX ) || defined( RUN_TIME_MMX ) + +#define hold_r %ebp +#define bits_r %bl +#define bitslong_r %ebx + +.align 32,0x90 +.L_while_test: + /* while (in < last && out < end) + */ + cmpl out_r, end(%esp) + jbe .L_break_loop /* if (out >= end) */ + + cmpl in_r, last(%esp) + jbe .L_break_loop + +.L_do_loop: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out + * + * do { + * if (bits < 15) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * this = lcode[hold & lmask] + */ + cmpb $15, bits_r + ja .L_get_length_code /* if (15 < bits) */ + + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + +.L_get_length_code: + movl lmask(%esp), %edx /* edx = lmask */ + movl lcode(%esp), %ecx /* ecx = lcode */ + andl hold_r, %edx /* edx &= hold */ + movl (%ecx,%edx,4), %eax /* eax = lcode[hold & lmask] */ + +.L_dolen: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out + * + * dolen: + * bits -= this.bits; + * hold >>= this.bits + */ + movb %ah, %cl /* cl = this.bits */ + subb %ah, bits_r /* bits -= this.bits */ + shrl %cl, hold_r /* hold >>= this.bits */ + + /* check if op is a literal + * if (op == 0) { + * PUP(out) = this.val; + * } + */ + testb %al, %al + jnz .L_test_for_length_base /* if (op != 0) 45.7% */ + + shrl $16, %eax /* output this.val char */ + stosb + jmp .L_while_test + +.L_test_for_length_base: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len + * + * else if (op & 16) { + * len = this.val + * op &= 15 + * if (op) { + * if (op > bits) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * len += hold & mask[op]; + * bits -= op; + * hold >>= op; + * } + */ +#define len_r %edx + movl %eax, len_r /* len = this */ + shrl $16, len_r /* len = this.val */ + movb %al, %cl + + testb $16, %al + jz .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */ + andb $15, %cl /* op &= 15 */ + jz .L_save_len /* if (!op) */ + cmpb %cl, bits_r + jae .L_add_bits_to_len /* if (op <= bits) */ + + movb %cl, %ch /* stash op in ch, freeing cl */ + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + movb %ch, %cl /* move op back to ecx */ + +.L_add_bits_to_len: + movl $1, %eax + shll %cl, %eax + decl %eax + subb %cl, bits_r + andl hold_r, %eax /* eax &= hold */ + shrl %cl, hold_r + addl %eax, len_r /* len += hold & mask[op] */ + +.L_save_len: + movl len_r, len(%esp) /* save len */ +#undef len_r + +.L_decode_distance: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * + * if (bits < 15) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * this = dcode[hold & dmask]; + * dodist: + * bits -= this.bits; + * hold >>= this.bits; + * op = this.op; + */ + + cmpb $15, bits_r + ja .L_get_distance_code /* if (15 < bits) */ + + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + +.L_get_distance_code: + movl dmask(%esp), %edx /* edx = dmask */ + movl dcode(%esp), %ecx /* ecx = dcode */ + andl hold_r, %edx /* edx &= hold */ + movl (%ecx,%edx,4), %eax /* eax = dcode[hold & dmask] */ + +#define dist_r %edx +.L_dodist: + movl %eax, dist_r /* dist = this */ + shrl $16, dist_r /* dist = this.val */ + movb %ah, %cl + subb %ah, bits_r /* bits -= this.bits */ + shrl %cl, hold_r /* hold >>= this.bits */ + + /* if (op & 16) { + * dist = this.val + * op &= 15 + * if (op > bits) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * dist += hold & mask[op]; + * bits -= op; + * hold >>= op; + */ + movb %al, %cl /* cl = this.op */ + + testb $16, %al /* if ((op & 16) == 0) */ + jz .L_test_for_second_level_dist + andb $15, %cl /* op &= 15 */ + jz .L_check_dist_one + cmpb %cl, bits_r + jae .L_add_bits_to_dist /* if (op <= bits) 97.6% */ + + movb %cl, %ch /* stash op in ch, freeing cl */ + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + movb %ch, %cl /* move op back to ecx */ + +.L_add_bits_to_dist: + movl $1, %eax + shll %cl, %eax + decl %eax /* (1 << op) - 1 */ + subb %cl, bits_r + andl hold_r, %eax /* eax &= hold */ + shrl %cl, hold_r + addl %eax, dist_r /* dist += hold & ((1 << op) - 1) */ + jmp .L_check_window + +.L_check_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes + * + * nbytes = out - beg; + * if (dist <= nbytes) { + * from = out - dist; + * do { + * PUP(out) = PUP(from); + * } while (--len > 0) { + * } + */ + + movl in_r, in(%esp) /* save in so from can use it's reg */ + movl out_r, %eax + subl beg(%esp), %eax /* nbytes = out - beg */ + + cmpl dist_r, %eax + jb .L_clip_window /* if (dist > nbytes) 4.2% */ + + movl len(%esp), %ecx + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + + subl $3, %ecx + movb (from_r), %al + movb %al, (out_r) + movb 1(from_r), %al + movb 2(from_r), %dl + addl $3, from_r + movb %al, 1(out_r) + movb %dl, 2(out_r) + addl $3, out_r + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + jmp .L_while_test + +.align 16,0x90 +.L_check_dist_one: + cmpl $1, dist_r + jne .L_check_window + cmpl out_r, beg(%esp) + je .L_check_window + + decl out_r + movl len(%esp), %ecx + movb (out_r), %al + subl $3, %ecx + + movb %al, 1(out_r) + movb %al, 2(out_r) + movb %al, 3(out_r) + addl $4, out_r + rep stosb + + jmp .L_while_test + +.align 16,0x90 +.L_test_for_second_level_length: + /* else if ((op & 64) == 0) { + * this = lcode[this.val + (hold & mask[op])]; + * } + */ + testb $64, %al + jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */ + + movl $1, %eax + shll %cl, %eax + decl %eax + andl hold_r, %eax /* eax &= hold */ + addl %edx, %eax /* eax += this.val */ + movl lcode(%esp), %edx /* edx = lcode */ + movl (%edx,%eax,4), %eax /* eax = lcode[val + (hold&mask[op])] */ + jmp .L_dolen + +.align 16,0x90 +.L_test_for_second_level_dist: + /* else if ((op & 64) == 0) { + * this = dcode[this.val + (hold & mask[op])]; + * } + */ + testb $64, %al + jnz .L_invalid_distance_code /* if ((op & 64) != 0) */ + + movl $1, %eax + shll %cl, %eax + decl %eax + andl hold_r, %eax /* eax &= hold */ + addl %edx, %eax /* eax += this.val */ + movl dcode(%esp), %edx /* edx = dcode */ + movl (%edx,%eax,4), %eax /* eax = dcode[val + (hold&mask[op])] */ + jmp .L_dodist + +.align 16,0x90 +.L_clip_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes + * + * else { + * if (dist > wsize) { + * invalid distance + * } + * from = window; + * nbytes = dist - nbytes; + * if (write == 0) { + * from += wsize - nbytes; + */ +#define nbytes_r %ecx + movl %eax, nbytes_r + movl wsize(%esp), %eax /* prepare for dist compare */ + negl nbytes_r /* nbytes = -nbytes */ + movl window(%esp), from_r /* from = window */ + + cmpl dist_r, %eax + jb .L_invalid_distance_too_far /* if (dist > wsize) */ + + addl dist_r, nbytes_r /* nbytes = dist - nbytes */ + cmpl $0, write(%esp) + jne .L_wrap_around_window /* if (write != 0) */ + + subl nbytes_r, %eax + addl %eax, from_r /* from += wsize - nbytes */ + + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes, %eax = len + * + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while (--nbytes); + * from = out - dist; + * } + * } + */ +#define len_r %eax + movl len(%esp), len_r + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1 + + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1 + +.L_wrap_around_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes, %eax = write, %eax = len + * + * else if (write < nbytes) { + * from += wsize + write - nbytes; + * nbytes -= write; + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while (--nbytes); + * from = window; + * nbytes = write; + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while(--nbytes); + * from = out - dist; + * } + * } + * } + */ +#define write_r %eax + movl write(%esp), write_r + cmpl write_r, nbytes_r + jbe .L_contiguous_in_window /* if (write >= nbytes) */ + + addl wsize(%esp), from_r + addl write_r, from_r + subl nbytes_r, from_r /* from += wsize + write - nbytes */ + subl write_r, nbytes_r /* nbytes -= write */ +#undef write_r + + movl len(%esp), len_r + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl window(%esp), from_r /* from = window */ + movl write(%esp), nbytes_r /* nbytes = write */ + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1 + +.L_contiguous_in_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes, %eax = write, %eax = len + * + * else { + * from += write - nbytes; + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while (--nbytes); + * from = out - dist; + * } + * } + */ +#define write_r %eax + addl write_r, from_r + subl nbytes_r, from_r /* from += write - nbytes */ +#undef write_r + + movl len(%esp), len_r + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + +.L_do_copy1: + /* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out + * %eax = len + * + * while (len > 0) { + * PUP(out) = PUP(from); + * len--; + * } + * } + * } while (in < last && out < end); + */ +#undef nbytes_r +#define in_r %esi + movl len_r, %ecx + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + jmp .L_while_test + +#undef len_r +#undef dist_r + +#endif /* NO_MMX || RUN_TIME_MMX */ + + +/*** MMX code ***/ + +#if defined( USE_MMX ) || defined( RUN_TIME_MMX ) + +.align 32,0x90 +.L_init_mmx: + emms + +#undef bits_r +#undef bitslong_r +#define bitslong_r %ebp +#define hold_mm %mm0 + movd %ebp, hold_mm + movl %ebx, bitslong_r + +#define used_mm %mm1 +#define dmask2_mm %mm2 +#define lmask2_mm %mm3 +#define lmask_mm %mm4 +#define dmask_mm %mm5 +#define tmp_mm %mm6 + + movd lmask(%esp), lmask_mm + movq lmask_mm, lmask2_mm + movd dmask(%esp), dmask_mm + movq dmask_mm, dmask2_mm + pxor used_mm, used_mm + movl lcode(%esp), %ebx /* ebx = lcode */ + jmp .L_do_loop_mmx + +.align 32,0x90 +.L_while_test_mmx: + /* while (in < last && out < end) + */ + cmpl out_r, end(%esp) + jbe .L_break_loop /* if (out >= end) */ + + cmpl in_r, last(%esp) + jbe .L_break_loop + +.L_do_loop_mmx: + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + + cmpl $32, bitslong_r + ja .L_get_length_code_mmx /* if (32 < bits) */ + + movd bitslong_r, tmp_mm + movd (in_r), %mm7 + addl $4, in_r + psllq tmp_mm, %mm7 + addl $32, bitslong_r + por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */ + +.L_get_length_code_mmx: + pand hold_mm, lmask_mm + movd lmask_mm, %eax + movq lmask2_mm, lmask_mm + movl (%ebx,%eax,4), %eax /* eax = lcode[hold & lmask] */ + +.L_dolen_mmx: + movzbl %ah, %ecx /* ecx = this.bits */ + movd %ecx, used_mm + subl %ecx, bitslong_r /* bits -= this.bits */ + + testb %al, %al + jnz .L_test_for_length_base_mmx /* if (op != 0) 45.7% */ + + shrl $16, %eax /* output this.val char */ + stosb + jmp .L_while_test_mmx + +.L_test_for_length_base_mmx: +#define len_r %edx + movl %eax, len_r /* len = this */ + shrl $16, len_r /* len = this.val */ + + testb $16, %al + jz .L_test_for_second_level_length_mmx /* if ((op & 16) == 0) 8% */ + andl $15, %eax /* op &= 15 */ + jz .L_decode_distance_mmx /* if (!op) */ + + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd %eax, used_mm + movd hold_mm, %ecx + subl %eax, bitslong_r + andl .L_mask(,%eax,4), %ecx + addl %ecx, len_r /* len += hold & mask[op] */ + +.L_decode_distance_mmx: + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + + cmpl $32, bitslong_r + ja .L_get_dist_code_mmx /* if (32 < bits) */ + + movd bitslong_r, tmp_mm + movd (in_r), %mm7 + addl $4, in_r + psllq tmp_mm, %mm7 + addl $32, bitslong_r + por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */ + +.L_get_dist_code_mmx: + movl dcode(%esp), %ebx /* ebx = dcode */ + pand hold_mm, dmask_mm + movd dmask_mm, %eax + movq dmask2_mm, dmask_mm + movl (%ebx,%eax,4), %eax /* eax = dcode[hold & lmask] */ + +.L_dodist_mmx: +#define dist_r %ebx + movzbl %ah, %ecx /* ecx = this.bits */ + movl %eax, dist_r + shrl $16, dist_r /* dist = this.val */ + subl %ecx, bitslong_r /* bits -= this.bits */ + movd %ecx, used_mm + + testb $16, %al /* if ((op & 16) == 0) */ + jz .L_test_for_second_level_dist_mmx + andl $15, %eax /* op &= 15 */ + jz .L_check_dist_one_mmx + +.L_add_bits_to_dist_mmx: + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd %eax, used_mm /* save bit length of current op */ + movd hold_mm, %ecx /* get the next bits on input stream */ + subl %eax, bitslong_r /* bits -= op bits */ + andl .L_mask(,%eax,4), %ecx /* ecx = hold & mask[op] */ + addl %ecx, dist_r /* dist += hold & mask[op] */ + +.L_check_window_mmx: + movl in_r, in(%esp) /* save in so from can use it's reg */ + movl out_r, %eax + subl beg(%esp), %eax /* nbytes = out - beg */ + + cmpl dist_r, %eax + jb .L_clip_window_mmx /* if (dist > nbytes) 4.2% */ + + movl len_r, %ecx + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + + subl $3, %ecx + movb (from_r), %al + movb %al, (out_r) + movb 1(from_r), %al + movb 2(from_r), %dl + addl $3, from_r + movb %al, 1(out_r) + movb %dl, 2(out_r) + addl $3, out_r + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */ + jmp .L_while_test_mmx + +.align 16,0x90 +.L_check_dist_one_mmx: + cmpl $1, dist_r + jne .L_check_window_mmx + cmpl out_r, beg(%esp) + je .L_check_window_mmx + + decl out_r + movl len_r, %ecx + movb (out_r), %al + subl $3, %ecx + + movb %al, 1(out_r) + movb %al, 2(out_r) + movb %al, 3(out_r) + addl $4, out_r + rep stosb + + movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */ + jmp .L_while_test_mmx + +.align 16,0x90 +.L_test_for_second_level_length_mmx: + testb $64, %al + jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */ + + andl $15, %eax + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd hold_mm, %ecx + andl .L_mask(,%eax,4), %ecx + addl len_r, %ecx + movl (%ebx,%ecx,4), %eax /* eax = lcode[hold & lmask] */ + jmp .L_dolen_mmx + +.align 16,0x90 +.L_test_for_second_level_dist_mmx: + testb $64, %al + jnz .L_invalid_distance_code /* if ((op & 64) != 0) */ + + andl $15, %eax + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd hold_mm, %ecx + andl .L_mask(,%eax,4), %ecx + movl dcode(%esp), %eax /* ecx = dcode */ + addl dist_r, %ecx + movl (%eax,%ecx,4), %eax /* eax = lcode[hold & lmask] */ + jmp .L_dodist_mmx + +.align 16,0x90 +.L_clip_window_mmx: +#define nbytes_r %ecx + movl %eax, nbytes_r + movl wsize(%esp), %eax /* prepare for dist compare */ + negl nbytes_r /* nbytes = -nbytes */ + movl window(%esp), from_r /* from = window */ + + cmpl dist_r, %eax + jb .L_invalid_distance_too_far /* if (dist > wsize) */ + + addl dist_r, nbytes_r /* nbytes = dist - nbytes */ + cmpl $0, write(%esp) + jne .L_wrap_around_window_mmx /* if (write != 0) */ + + subl nbytes_r, %eax + addl %eax, from_r /* from += wsize - nbytes */ + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1_mmx + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1_mmx + +.L_wrap_around_window_mmx: +#define write_r %eax + movl write(%esp), write_r + cmpl write_r, nbytes_r + jbe .L_contiguous_in_window_mmx /* if (write >= nbytes) */ + + addl wsize(%esp), from_r + addl write_r, from_r + subl nbytes_r, from_r /* from += wsize + write - nbytes */ + subl write_r, nbytes_r /* nbytes -= write */ +#undef write_r + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl window(%esp), from_r /* from = window */ + movl write(%esp), nbytes_r /* nbytes = write */ + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1_mmx + +.L_contiguous_in_window_mmx: +#define write_r %eax + addl write_r, from_r + subl nbytes_r, from_r /* from += write - nbytes */ +#undef write_r + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + +.L_do_copy1_mmx: +#undef nbytes_r +#define in_r %esi + movl len_r, %ecx + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */ + jmp .L_while_test_mmx + +#undef hold_r +#undef bitslong_r + +#endif /* USE_MMX || RUN_TIME_MMX */ + + +/*** USE_MMX, NO_MMX, and RUNTIME_MMX from here on ***/ + +.L_invalid_distance_code: + /* else { + * strm->msg = "invalid distance code"; + * state->mode = BAD; + * } + */ + movl $.L_invalid_distance_code_msg, %ecx + movl $INFLATE_MODE_BAD, %edx + jmp .L_update_stream_state + +.L_test_for_end_of_block: + /* else if (op & 32) { + * state->mode = TYPE; + * break; + * } + */ + testb $32, %al + jz .L_invalid_literal_length_code /* if ((op & 32) == 0) */ + + movl $0, %ecx + movl $INFLATE_MODE_TYPE, %edx + jmp .L_update_stream_state + +.L_invalid_literal_length_code: + /* else { + * strm->msg = "invalid literal/length code"; + * state->mode = BAD; + * } + */ + movl $.L_invalid_literal_length_code_msg, %ecx + movl $INFLATE_MODE_BAD, %edx + jmp .L_update_stream_state + +.L_invalid_distance_too_far: + /* strm->msg = "invalid distance too far back"; + * state->mode = BAD; + */ + movl in(%esp), in_r /* from_r has in's reg, put in back */ + movl $.L_invalid_distance_too_far_msg, %ecx + movl $INFLATE_MODE_BAD, %edx + jmp .L_update_stream_state + +.L_update_stream_state: + /* set strm->msg = %ecx, strm->state->mode = %edx */ + movl strm_sp(%esp), %eax + testl %ecx, %ecx /* if (msg != NULL) */ + jz .L_skip_msg + movl %ecx, msg_strm(%eax) /* strm->msg = msg */ +.L_skip_msg: + movl state_strm(%eax), %eax /* state = strm->state */ + movl %edx, mode_state(%eax) /* state->mode = edx (BAD | TYPE) */ + jmp .L_break_loop + +.align 32,0x90 +.L_break_loop: + +/* + * Regs: + * + * bits = %ebp when mmx, and in %ebx when non-mmx + * hold = %hold_mm when mmx, and in %ebp when non-mmx + * in = %esi + * out = %edi + */ + +#if defined( USE_MMX ) || defined( RUN_TIME_MMX ) + +#if defined( RUN_TIME_MMX ) + + cmpl $DO_USE_MMX, inflate_fast_use_mmx + jne .L_update_next_in + +#endif /* RUN_TIME_MMX */ + + movl %ebp, %ebx + +.L_update_next_in: + +#endif + +#define strm_r %eax +#define state_r %edx + + /* len = bits >> 3; + * in -= len; + * bits -= len << 3; + * hold &= (1U << bits) - 1; + * state->hold = hold; + * state->bits = bits; + * strm->next_in = in; + * strm->next_out = out; + */ + movl strm_sp(%esp), strm_r + movl %ebx, %ecx + movl state_strm(strm_r), state_r + shrl $3, %ecx + subl %ecx, in_r + shll $3, %ecx + subl %ecx, %ebx + movl out_r, next_out_strm(strm_r) + movl %ebx, bits_state(state_r) + movl %ebx, %ecx + + leal buf(%esp), %ebx + cmpl %ebx, last(%esp) + jne .L_buf_not_used /* if buf != last */ + + subl %ebx, in_r /* in -= buf */ + movl next_in_strm(strm_r), %ebx + movl %ebx, last(%esp) /* last = strm->next_in */ + addl %ebx, in_r /* in += strm->next_in */ + movl avail_in_strm(strm_r), %ebx + subl $11, %ebx + addl %ebx, last(%esp) /* last = &strm->next_in[ avail_in - 11 ] */ + +.L_buf_not_used: + movl in_r, next_in_strm(strm_r) + + movl $1, %ebx + shll %cl, %ebx + decl %ebx + +#if defined( USE_MMX ) || defined( RUN_TIME_MMX ) + +#if defined( RUN_TIME_MMX ) + + cmpl $DO_USE_MMX, inflate_fast_use_mmx + jne .L_update_hold + +#endif /* RUN_TIME_MMX */ + + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd hold_mm, %ebp + + emms + +.L_update_hold: + +#endif /* USE_MMX || RUN_TIME_MMX */ + + andl %ebx, %ebp + movl %ebp, hold_state(state_r) + +#define last_r %ebx + + /* strm->avail_in = in < last ? 11 + (last - in) : 11 - (in - last) */ + movl last(%esp), last_r + cmpl in_r, last_r + jbe .L_last_is_smaller /* if (in >= last) */ + + subl in_r, last_r /* last -= in */ + addl $11, last_r /* last += 11 */ + movl last_r, avail_in_strm(strm_r) + jmp .L_fixup_out +.L_last_is_smaller: + subl last_r, in_r /* in -= last */ + negl in_r /* in = -in */ + addl $11, in_r /* in += 11 */ + movl in_r, avail_in_strm(strm_r) + +#undef last_r +#define end_r %ebx + +.L_fixup_out: + /* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/ + movl end(%esp), end_r + cmpl out_r, end_r + jbe .L_end_is_smaller /* if (out >= end) */ + + subl out_r, end_r /* end -= out */ + addl $257, end_r /* end += 257 */ + movl end_r, avail_out_strm(strm_r) + jmp .L_done +.L_end_is_smaller: + subl end_r, out_r /* out -= end */ + negl out_r /* out = -out */ + addl $257, out_r /* out += 257 */ + movl out_r, avail_out_strm(strm_r) + +#undef end_r +#undef strm_r +#undef state_r + +.L_done: + addl $local_var_size, %esp + popf + popl %ebx + popl %ebp + popl %esi + popl %edi + ret + +#if defined( GAS_ELF ) +/* elf info */ +.type inflate_fast,@function +.size inflate_fast,.-inflate_fast +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream/test.cpp b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream/test.cpp new file mode 100644 index 00000000..7d265b3b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream/test.cpp @@ -0,0 +1,24 @@ + +#include "zfstream.h" + +int main() { + + // Construct a stream object with this filebuffer. Anything sent + // to this stream will go to standard out. + gzofstream os( 1, ios::out ); + + // This text is getting compressed and sent to stdout. + // To prove this, run 'test | zcat'. + os << "Hello, Mommy" << endl; + + os << setcompressionlevel( Z_NO_COMPRESSION ); + os << "hello, hello, hi, ho!" << endl; + + setcompressionlevel( os, Z_DEFAULT_COMPRESSION ) + << "I'm compressing again" << endl; + + os.close(); + + return 0; + +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream/zfstream.cpp b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream/zfstream.cpp new file mode 100644 index 00000000..d0cd85fa --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream/zfstream.cpp @@ -0,0 +1,329 @@ + +#include "zfstream.h" + +gzfilebuf::gzfilebuf() : + file(NULL), + mode(0), + own_file_descriptor(0) +{ } + +gzfilebuf::~gzfilebuf() { + + sync(); + if ( own_file_descriptor ) + close(); + +} + +gzfilebuf *gzfilebuf::open( const char *name, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + // Put the end-of-string indicator + *p = '\0'; + + if ( (file = gzopen(name, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 1; + + return this; + +} + +gzfilebuf *gzfilebuf::attach( int file_descriptor, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + // Put the end-of-string indicator + *p = '\0'; + + if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 0; + + return this; + +} + +gzfilebuf *gzfilebuf::close() { + + if ( is_open() ) { + + sync(); + gzclose( file ); + file = NULL; + + } + + return this; + +} + +int gzfilebuf::setcompressionlevel( int comp_level ) { + + return gzsetparams(file, comp_level, -2); + +} + +int gzfilebuf::setcompressionstrategy( int comp_strategy ) { + + return gzsetparams(file, -2, comp_strategy); + +} + + +streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { + + return streampos(EOF); + +} + +int gzfilebuf::underflow() { + + // If the file hasn't been opened for reading, error. + if ( !is_open() || !(mode & ios::in) ) + return EOF; + + // if a buffer doesn't exists, allocate one. + if ( !base() ) { + + if ( (allocate()) == EOF ) + return EOF; + setp(0,0); + + } else { + + if ( in_avail() ) + return (unsigned char) *gptr(); + + if ( out_waiting() ) { + if ( flushbuf() == EOF ) + return EOF; + } + + } + + // Attempt to fill the buffer. + + int result = fillbuf(); + if ( result == EOF ) { + // disable get area + setg(0,0,0); + return EOF; + } + + return (unsigned char) *gptr(); + +} + +int gzfilebuf::overflow( int c ) { + + if ( !is_open() || !(mode & ios::out) ) + return EOF; + + if ( !base() ) { + if ( allocate() == EOF ) + return EOF; + setg(0,0,0); + } else { + if (in_avail()) { + return EOF; + } + if (out_waiting()) { + if (flushbuf() == EOF) + return EOF; + } + } + + int bl = blen(); + setp( base(), base() + bl); + + if ( c != EOF ) { + + *pptr() = c; + pbump(1); + + } + + return 0; + +} + +int gzfilebuf::sync() { + + if ( !is_open() ) + return EOF; + + if ( out_waiting() ) + return flushbuf(); + + return 0; + +} + +int gzfilebuf::flushbuf() { + + int n; + char *q; + + q = pbase(); + n = pptr() - q; + + if ( gzwrite( file, q, n) < n ) + return EOF; + + setp(0,0); + + return 0; + +} + +int gzfilebuf::fillbuf() { + + int required; + char *p; + + p = base(); + + required = blen(); + + int t = gzread( file, p, required ); + + if ( t <= 0) return EOF; + + setg( base(), base(), base()+t); + + return t; + +} + +gzfilestream_common::gzfilestream_common() : + ios( gzfilestream_common::rdbuf() ) +{ } + +gzfilestream_common::~gzfilestream_common() +{ } + +void gzfilestream_common::attach( int fd, int io_mode ) { + + if ( !buffer.attach( fd, io_mode) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::open( const char *name, int io_mode ) { + + if ( !buffer.open( name, io_mode ) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::close() { + + if ( !buffer.close() ) + clear( ios::failbit | ios::badbit ); + +} + +gzfilebuf *gzfilestream_common::rdbuf() +{ + return &buffer; +} + +gzifstream::gzifstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzifstream::gzifstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzifstream::gzifstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzifstream::~gzifstream() { } + +gzofstream::gzofstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzofstream::gzofstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzofstream::gzofstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzofstream::~gzofstream() { } diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream/zfstream.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream/zfstream.h new file mode 100644 index 00000000..ed79098a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream/zfstream.h @@ -0,0 +1,128 @@ + +#ifndef zfstream_h +#define zfstream_h + +#include +#include "zlib.h" + +class gzfilebuf : public streambuf { + +public: + + gzfilebuf( ); + virtual ~gzfilebuf(); + + gzfilebuf *open( const char *name, int io_mode ); + gzfilebuf *attach( int file_descriptor, int io_mode ); + gzfilebuf *close(); + + int setcompressionlevel( int comp_level ); + int setcompressionstrategy( int comp_strategy ); + + inline int is_open() const { return (file !=NULL); } + + virtual streampos seekoff( streamoff, ios::seek_dir, int ); + + virtual int sync(); + +protected: + + virtual int underflow(); + virtual int overflow( int = EOF ); + +private: + + gzFile file; + short mode; + short own_file_descriptor; + + int flushbuf(); + int fillbuf(); + +}; + +class gzfilestream_common : virtual public ios { + + friend class gzifstream; + friend class gzofstream; + friend gzofstream &setcompressionlevel( gzofstream &, int ); + friend gzofstream &setcompressionstrategy( gzofstream &, int ); + +public: + virtual ~gzfilestream_common(); + + void attach( int fd, int io_mode ); + void open( const char *name, int io_mode ); + void close(); + +protected: + gzfilestream_common(); + +private: + gzfilebuf *rdbuf(); + + gzfilebuf buffer; + +}; + +class gzifstream : public gzfilestream_common, public istream { + +public: + + gzifstream(); + gzifstream( const char *name, int io_mode = ios::in ); + gzifstream( int fd, int io_mode = ios::in ); + + virtual ~gzifstream(); + +}; + +class gzofstream : public gzfilestream_common, public ostream { + +public: + + gzofstream(); + gzofstream( const char *name, int io_mode = ios::out ); + gzofstream( int fd, int io_mode = ios::out ); + + virtual ~gzofstream(); + +}; + +template class gzomanip { + friend gzofstream &operator<<(gzofstream &, const gzomanip &); +public: + gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { } +private: + gzofstream &(*func)(gzofstream &, T); + T val; +}; + +template gzofstream &operator<<(gzofstream &s, const gzomanip &m) +{ + return (*m.func)(s, m.val); +} + +inline gzofstream &setcompressionlevel( gzofstream &s, int l ) +{ + (s.rdbuf())->setcompressionlevel(l); + return s; +} + +inline gzofstream &setcompressionstrategy( gzofstream &s, int l ) +{ + (s.rdbuf())->setcompressionstrategy(l); + return s; +} + +inline gzomanip setcompressionlevel(int l) +{ + return gzomanip(&setcompressionlevel,l); +} + +inline gzomanip setcompressionstrategy(int l) +{ + return gzomanip(&setcompressionstrategy,l); +} + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream2/zstream.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream2/zstream.h new file mode 100644 index 00000000..43d2332b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream2/zstream.h @@ -0,0 +1,307 @@ +/* + * + * Copyright (c) 1997 + * Christian Michelsen Research AS + * Advanced Computing + * Fantoftvegen 38, 5036 BERGEN, Norway + * http://www.cmr.no + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Christian Michelsen Research AS makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef ZSTREAM__H +#define ZSTREAM__H + +/* + * zstream.h - C++ interface to the 'zlib' general purpose compression library + * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $ + */ + +#include +#include +#include +#include "zlib.h" + +#if defined(_WIN32) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +class zstringlen { +public: + zstringlen(class izstream&); + zstringlen(class ozstream&, const char*); + size_t value() const { return val.word; } +private: + struct Val { unsigned char byte; size_t word; } val; +}; + +// ----------------------------- izstream ----------------------------- + +class izstream +{ + public: + izstream() : m_fp(0) {} + izstream(FILE* fp) : m_fp(0) { open(fp); } + izstream(const char* name) : m_fp(0) { open(name); } + ~izstream() { close(); } + + /* Opens a gzip (.gz) file for reading. + * open() can be used to read a file which is not in gzip format; + * in this case read() will directly read from the file without + * decompression. errno can be checked to distinguish two error + * cases (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name) { + if (m_fp) close(); + m_fp = ::gzopen(name, "rb"); + } + + void open(FILE* fp) { + SET_BINARY_MODE(fp); + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), "rb"); + } + + /* Flushes all pending input if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + int r = ::gzclose(m_fp); + m_fp = 0; return r; + } + + /* Binary read the given number of bytes from the compressed file. + */ + int read(void* buf, size_t len) { + return ::gzread(m_fp, buf, len); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + private: + gzFile m_fp; +}; + +/* + * Binary read the given (array of) object(s) from the compressed file. + * If the input file was not in gzip format, read() copies the objects number + * of bytes into the buffer. + * returns the number of uncompressed bytes actually read + * (0 for end of file, -1 for error). + */ +template +inline int read(izstream& zs, T* x, Items items) { + return ::gzread(zs.fp(), x, items*sizeof(T)); +} + +/* + * Binary input with the '>' operator. + */ +template +inline izstream& operator>(izstream& zs, T& x) { + ::gzread(zs.fp(), &x, sizeof(T)); + return zs; +} + + +inline zstringlen::zstringlen(izstream& zs) { + zs > val.byte; + if (val.byte == 255) zs > val.word; + else val.word = val.byte; +} + +/* + * Read length of string + the string with the '>' operator. + */ +inline izstream& operator>(izstream& zs, char* x) { + zstringlen len(zs); + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return zs; +} + +inline char* read_string(izstream& zs) { + zstringlen len(zs); + char* x = new char[len.value()+1]; + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return x; +} + +// ----------------------------- ozstream ----------------------------- + +class ozstream +{ + public: + ozstream() : m_fp(0), m_os(0) { + } + ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(fp, level); + } + ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(name, level); + } + ~ozstream() { + close(); + } + + /* Opens a gzip (.gz) file for writing. + * The compression level parameter should be in 0..9 + * errno can be checked to distinguish two error cases + * (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name, int level = Z_DEFAULT_COMPRESSION) { + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzopen(name, mode); + } + + /* open from a FILE pointer. + */ + void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) { + SET_BINARY_MODE(fp); + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), mode); + } + + /* Flushes all pending output if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + if (m_os) { + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = 0; + } + int r = ::gzclose(m_fp); m_fp = 0; return r; + } + + /* Binary write the given number of bytes into the compressed file. + */ + int write(const void* buf, size_t len) { + return ::gzwrite(m_fp, (voidp) buf, len); + } + + /* Flushes all pending output into the compressed file. The parameter + * _flush is as in the deflate() function. The return value is the zlib + * error number (see function gzerror below). flush() returns Z_OK if + * the flush_ parameter is Z_FINISH and all output could be flushed. + * flush() should be called only when strictly necessary because it can + * degrade compression. + */ + int flush(int _flush) { + os_flush(); + return ::gzflush(m_fp, _flush); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + ostream& os() { + if (m_os == 0) m_os = new ostrstream; + return *m_os; + } + + void os_flush() { + if (m_os && m_os->pcount()>0) { + ostrstream* oss = new ostrstream; + oss->fill(m_os->fill()); + oss->flags(m_os->flags()); + oss->precision(m_os->precision()); + oss->width(m_os->width()); + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = oss; + } + } + + private: + gzFile m_fp; + ostrstream* m_os; +}; + +/* + * Binary write the given (array of) object(s) into the compressed file. + * returns the number of uncompressed bytes actually written + * (0 in case of error). + */ +template +inline int write(ozstream& zs, const T* x, Items items) { + return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T)); +} + +/* + * Binary output with the '<' operator. + */ +template +inline ozstream& operator<(ozstream& zs, const T& x) { + ::gzwrite(zs.fp(), (voidp) &x, sizeof(T)); + return zs; +} + +inline zstringlen::zstringlen(ozstream& zs, const char* x) { + val.byte = 255; val.word = ::strlen(x); + if (val.word < 255) zs < (val.byte = val.word); + else zs < val; +} + +/* + * Write length of string + the string with the '<' operator. + */ +inline ozstream& operator<(ozstream& zs, const char* x) { + zstringlen len(zs, x); + ::gzwrite(zs.fp(), (voidp) x, len.value()); + return zs; +} + +#ifdef _MSC_VER +inline ozstream& operator<(ozstream& zs, char* const& x) { + return zs < (const char*) x; +} +#endif + +/* + * Ascii write with the << operator; + */ +template +inline ostream& operator<<(ozstream& zs, const T& x) { + zs.os_flush(); + return zs.os() << x; +} + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream2/zstream_test.cpp b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream2/zstream_test.cpp new file mode 100644 index 00000000..6273f62d --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream2/zstream_test.cpp @@ -0,0 +1,25 @@ +#include "zstream.h" +#include +#include +#include + +void main() { + char h[256] = "Hello"; + char* g = "Goodbye"; + ozstream out("temp.gz"); + out < "This works well" < h < g; + out.close(); + + izstream in("temp.gz"); // read it back + char *x = read_string(in), *y = new char[256], z[256]; + in > y > z; + in.close(); + cout << x << endl << y << endl << z << endl; + + out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results + out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl; + out << z << endl << y << endl << x << endl; + out << 1.1234567890123456789 << endl; + + delete[] x; delete[] y; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/README b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/README new file mode 100644 index 00000000..f7b319ab --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/README @@ -0,0 +1,35 @@ +These classes provide a C++ stream interface to the zlib library. It allows you +to do things like: + + gzofstream outf("blah.gz"); + outf << "These go into the gzip file " << 123 << endl; + +It does this by deriving a specialized stream buffer for gzipped files, which is +the way Stroustrup would have done it. :-> + +The gzifstream and gzofstream classes were originally written by Kevin Ruland +and made available in the zlib contrib/iostream directory. The older version still +compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of +this version. + +The new classes are as standard-compliant as possible, closely following the +approach of the standard library's fstream classes. It compiles under gcc versions +3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard +library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs +from the previous one in the following respects: +- added showmanyc +- added setbuf, with support for unbuffered output via setbuf(0,0) +- a few bug fixes of stream behavior +- gzipped output file opened with default compression level instead of maximum level +- setcompressionlevel()/strategy() members replaced by single setcompression() + +The code is provided "as is", with the permission to use, copy, modify, distribute +and sell it for any purpose without fee. + +Ludwig Schwardt + + +DSP Lab +Electrical & Electronic Engineering Department +University of Stellenbosch +South Africa diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/TODO b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/TODO new file mode 100644 index 00000000..7032f97b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/TODO @@ -0,0 +1,17 @@ +Possible upgrades to gzfilebuf: + +- The ability to do putback (e.g. putbackfail) + +- The ability to seek (zlib supports this, but could be slow/tricky) + +- Simultaneous read/write access (does it make sense?) + +- Support for ios_base::ate open mode + +- Locale support? + +- Check public interface to see which calls give problems + (due to dependence on library internals) + +- Override operator<<(ostream&, gzfilebuf*) to allow direct copying + of stream buffer to stream ( i.e. os << is.rdbuf(); ) diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/test.cc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/test.cc new file mode 100644 index 00000000..94235334 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/test.cc @@ -0,0 +1,50 @@ +/* + * Test program for gzifstream and gzofstream + * + * by Ludwig Schwardt + * original version by Kevin Ruland + */ + +#include "zfstream.h" +#include // for cout + +int main() { + + gzofstream outf; + gzifstream inf; + char buf[80]; + + outf.open("test1.txt.gz"); + outf << "The quick brown fox sidestepped the lazy canine\n" + << 1.3 << "\nPlan " << 9 << std::endl; + outf.close(); + std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n" + << "The quick brown fox sidestepped the lazy canine\n" + << 1.3 << "\nPlan " << 9 << std::endl; + + std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n"; + inf.open("test1.txt.gz"); + while (inf.getline(buf,80,'\n')) { + std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n"; + } + inf.close(); + + outf.rdbuf()->pubsetbuf(0,0); + outf.open("test2.txt.gz"); + outf << setcompression(Z_NO_COMPRESSION) + << "The quick brown fox sidestepped the lazy canine\n" + << 1.3 << "\nPlan " << 9 << std::endl; + outf.close(); + std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form"; + + std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n"; + inf.rdbuf()->pubsetbuf(0,0); + inf.open("test2.txt.gz"); + while (inf.getline(buf,80,'\n')) { + std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n"; + } + inf.close(); + + return 0; + +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/zfstream.cc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/zfstream.cc new file mode 100644 index 00000000..94eb9334 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/zfstream.cc @@ -0,0 +1,479 @@ +/* + * A C++ I/O streams interface to the zlib gz* functions + * + * by Ludwig Schwardt + * original version by Kevin Ruland + * + * This version is standard-compliant and compatible with gcc 3.x. + */ + +#include "zfstream.h" +#include // for strcpy, strcat, strlen (mode strings) +#include // for BUFSIZ + +// Internal buffer sizes (default and "unbuffered" versions) +#define BIGBUFSIZE BUFSIZ +#define SMALLBUFSIZE 1 + +/*****************************************************************************/ + +// Default constructor +gzfilebuf::gzfilebuf() +: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false), + buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true) +{ + // No buffers to start with + this->disable_buffer(); +} + +// Destructor +gzfilebuf::~gzfilebuf() +{ + // Sync output buffer and close only if responsible for file + // (i.e. attached streams should be left open at this stage) + this->sync(); + if (own_fd) + this->close(); + // Make sure internal buffer is deallocated + this->disable_buffer(); +} + +// Set compression level and strategy +int +gzfilebuf::setcompression(int comp_level, + int comp_strategy) +{ + return gzsetparams(file, comp_level, comp_strategy); +} + +// Open gzipped file +gzfilebuf* +gzfilebuf::open(const char *name, + std::ios_base::openmode mode) +{ + // Fail if file already open + if (this->is_open()) + return NULL; + // Don't support simultaneous read/write access (yet) + if ((mode & std::ios_base::in) && (mode & std::ios_base::out)) + return NULL; + + // Build mode string for gzopen and check it [27.8.1.3.2] + char char_mode[6] = "\0\0\0\0\0"; + if (!this->open_mode(mode, char_mode)) + return NULL; + + // Attempt to open file + if ((file = gzopen(name, char_mode)) == NULL) + return NULL; + + // On success, allocate internal buffer and set flags + this->enable_buffer(); + io_mode = mode; + own_fd = true; + return this; +} + +// Attach to gzipped file +gzfilebuf* +gzfilebuf::attach(int fd, + std::ios_base::openmode mode) +{ + // Fail if file already open + if (this->is_open()) + return NULL; + // Don't support simultaneous read/write access (yet) + if ((mode & std::ios_base::in) && (mode & std::ios_base::out)) + return NULL; + + // Build mode string for gzdopen and check it [27.8.1.3.2] + char char_mode[6] = "\0\0\0\0\0"; + if (!this->open_mode(mode, char_mode)) + return NULL; + + // Attempt to attach to file + if ((file = gzdopen(fd, char_mode)) == NULL) + return NULL; + + // On success, allocate internal buffer and set flags + this->enable_buffer(); + io_mode = mode; + own_fd = false; + return this; +} + +// Close gzipped file +gzfilebuf* +gzfilebuf::close() +{ + // Fail immediately if no file is open + if (!this->is_open()) + return NULL; + // Assume success + gzfilebuf* retval = this; + // Attempt to sync and close gzipped file + if (this->sync() == -1) + retval = NULL; + if (gzclose(file) < 0) + retval = NULL; + // File is now gone anyway (postcondition [27.8.1.3.8]) + file = NULL; + own_fd = false; + // Destroy internal buffer if it exists + this->disable_buffer(); + return retval; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Convert int open mode to mode string +bool +gzfilebuf::open_mode(std::ios_base::openmode mode, + char* c_mode) const +{ + bool testb = mode & std::ios_base::binary; + bool testi = mode & std::ios_base::in; + bool testo = mode & std::ios_base::out; + bool testt = mode & std::ios_base::trunc; + bool testa = mode & std::ios_base::app; + + // Check for valid flag combinations - see [27.8.1.3.2] (Table 92) + // Original zfstream hardcoded the compression level to maximum here... + // Double the time for less than 1% size improvement seems + // excessive though - keeping it at the default level + // To change back, just append "9" to the next three mode strings + if (!testi && testo && !testt && !testa) + strcpy(c_mode, "w"); + if (!testi && testo && !testt && testa) + strcpy(c_mode, "a"); + if (!testi && testo && testt && !testa) + strcpy(c_mode, "w"); + if (testi && !testo && !testt && !testa) + strcpy(c_mode, "r"); + // No read/write mode yet +// if (testi && testo && !testt && !testa) +// strcpy(c_mode, "r+"); +// if (testi && testo && testt && !testa) +// strcpy(c_mode, "w+"); + + // Mode string should be empty for invalid combination of flags + if (strlen(c_mode) == 0) + return false; + if (testb) + strcat(c_mode, "b"); + return true; +} + +// Determine number of characters in internal get buffer +std::streamsize +gzfilebuf::showmanyc() +{ + // Calls to underflow will fail if file not opened for reading + if (!this->is_open() || !(io_mode & std::ios_base::in)) + return -1; + // Make sure get area is in use + if (this->gptr() && (this->gptr() < this->egptr())) + return std::streamsize(this->egptr() - this->gptr()); + else + return 0; +} + +// Fill get area from gzipped file +gzfilebuf::int_type +gzfilebuf::underflow() +{ + // If something is left in the get area by chance, return it + // (this shouldn't normally happen, as underflow is only supposed + // to be called when gptr >= egptr, but it serves as error check) + if (this->gptr() && (this->gptr() < this->egptr())) + return traits_type::to_int_type(*(this->gptr())); + + // If the file hasn't been opened for reading, produce error + if (!this->is_open() || !(io_mode & std::ios_base::in)) + return traits_type::eof(); + + // Attempt to fill internal buffer from gzipped file + // (buffer must be guaranteed to exist...) + int bytes_read = gzread(file, buffer, buffer_size); + // Indicates error or EOF + if (bytes_read <= 0) + { + // Reset get area + this->setg(buffer, buffer, buffer); + return traits_type::eof(); + } + // Make all bytes read from file available as get area + this->setg(buffer, buffer, buffer + bytes_read); + + // Return next character in get area + return traits_type::to_int_type(*(this->gptr())); +} + +// Write put area to gzipped file +gzfilebuf::int_type +gzfilebuf::overflow(int_type c) +{ + // Determine whether put area is in use + if (this->pbase()) + { + // Double-check pointer range + if (this->pptr() > this->epptr() || this->pptr() < this->pbase()) + return traits_type::eof(); + // Add extra character to buffer if not EOF + if (!traits_type::eq_int_type(c, traits_type::eof())) + { + *(this->pptr()) = traits_type::to_char_type(c); + this->pbump(1); + } + // Number of characters to write to file + int bytes_to_write = this->pptr() - this->pbase(); + // Overflow doesn't fail if nothing is to be written + if (bytes_to_write > 0) + { + // If the file hasn't been opened for writing, produce error + if (!this->is_open() || !(io_mode & std::ios_base::out)) + return traits_type::eof(); + // If gzipped file won't accept all bytes written to it, fail + if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write) + return traits_type::eof(); + // Reset next pointer to point to pbase on success + this->pbump(-bytes_to_write); + } + } + // Write extra character to file if not EOF + else if (!traits_type::eq_int_type(c, traits_type::eof())) + { + // If the file hasn't been opened for writing, produce error + if (!this->is_open() || !(io_mode & std::ios_base::out)) + return traits_type::eof(); + // Impromptu char buffer (allows "unbuffered" output) + char_type last_char = traits_type::to_char_type(c); + // If gzipped file won't accept this character, fail + if (gzwrite(file, &last_char, 1) != 1) + return traits_type::eof(); + } + + // If you got here, you have succeeded (even if c was EOF) + // The return value should therefore be non-EOF + if (traits_type::eq_int_type(c, traits_type::eof())) + return traits_type::not_eof(c); + else + return c; +} + +// Assign new buffer +std::streambuf* +gzfilebuf::setbuf(char_type* p, + std::streamsize n) +{ + // First make sure stuff is sync'ed, for safety + if (this->sync() == -1) + return NULL; + // If buffering is turned off on purpose via setbuf(0,0), still allocate one... + // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at + // least a buffer of size 1 (very inefficient though, therefore make it bigger?) + // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems) + if (!p || !n) + { + // Replace existing buffer (if any) with small internal buffer + this->disable_buffer(); + buffer = NULL; + buffer_size = 0; + own_buffer = true; + this->enable_buffer(); + } + else + { + // Replace existing buffer (if any) with external buffer + this->disable_buffer(); + buffer = p; + buffer_size = n; + own_buffer = false; + this->enable_buffer(); + } + return this; +} + +// Write put area to gzipped file (i.e. ensures that put area is empty) +int +gzfilebuf::sync() +{ + return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Allocate internal buffer +void +gzfilebuf::enable_buffer() +{ + // If internal buffer required, allocate one + if (own_buffer && !buffer) + { + // Check for buffered vs. "unbuffered" + if (buffer_size > 0) + { + // Allocate internal buffer + buffer = new char_type[buffer_size]; + // Get area starts empty and will be expanded by underflow as need arises + this->setg(buffer, buffer, buffer); + // Setup entire internal buffer as put area. + // The one-past-end pointer actually points to the last element of the buffer, + // so that overflow(c) can safely add the extra character c to the sequence. + // These pointers remain in place for the duration of the buffer + this->setp(buffer, buffer + buffer_size - 1); + } + else + { + // Even in "unbuffered" case, (small?) get buffer is still required + buffer_size = SMALLBUFSIZE; + buffer = new char_type[buffer_size]; + this->setg(buffer, buffer, buffer); + // "Unbuffered" means no put buffer + this->setp(0, 0); + } + } + else + { + // If buffer already allocated, reset buffer pointers just to make sure no + // stale chars are lying around + this->setg(buffer, buffer, buffer); + this->setp(buffer, buffer + buffer_size - 1); + } +} + +// Destroy internal buffer +void +gzfilebuf::disable_buffer() +{ + // If internal buffer exists, deallocate it + if (own_buffer && buffer) + { + // Preserve unbuffered status by zeroing size + if (!this->pbase()) + buffer_size = 0; + delete[] buffer; + buffer = NULL; + this->setg(0, 0, 0); + this->setp(0, 0); + } + else + { + // Reset buffer pointers to initial state if external buffer exists + this->setg(buffer, buffer, buffer); + if (buffer) + this->setp(buffer, buffer + buffer_size - 1); + else + this->setp(0, 0); + } +} + +/*****************************************************************************/ + +// Default constructor initializes stream buffer +gzifstream::gzifstream() +: std::istream(NULL), sb() +{ this->init(&sb); } + +// Initialize stream buffer and open file +gzifstream::gzifstream(const char* name, + std::ios_base::openmode mode) +: std::istream(NULL), sb() +{ + this->init(&sb); + this->open(name, mode); +} + +// Initialize stream buffer and attach to file +gzifstream::gzifstream(int fd, + std::ios_base::openmode mode) +: std::istream(NULL), sb() +{ + this->init(&sb); + this->attach(fd, mode); +} + +// Open file and go into fail() state if unsuccessful +void +gzifstream::open(const char* name, + std::ios_base::openmode mode) +{ + if (!sb.open(name, mode | std::ios_base::in)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Attach to file and go into fail() state if unsuccessful +void +gzifstream::attach(int fd, + std::ios_base::openmode mode) +{ + if (!sb.attach(fd, mode | std::ios_base::in)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Close file +void +gzifstream::close() +{ + if (!sb.close()) + this->setstate(std::ios_base::failbit); +} + +/*****************************************************************************/ + +// Default constructor initializes stream buffer +gzofstream::gzofstream() +: std::ostream(NULL), sb() +{ this->init(&sb); } + +// Initialize stream buffer and open file +gzofstream::gzofstream(const char* name, + std::ios_base::openmode mode) +: std::ostream(NULL), sb() +{ + this->init(&sb); + this->open(name, mode); +} + +// Initialize stream buffer and attach to file +gzofstream::gzofstream(int fd, + std::ios_base::openmode mode) +: std::ostream(NULL), sb() +{ + this->init(&sb); + this->attach(fd, mode); +} + +// Open file and go into fail() state if unsuccessful +void +gzofstream::open(const char* name, + std::ios_base::openmode mode) +{ + if (!sb.open(name, mode | std::ios_base::out)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Attach to file and go into fail() state if unsuccessful +void +gzofstream::attach(int fd, + std::ios_base::openmode mode) +{ + if (!sb.attach(fd, mode | std::ios_base::out)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Close file +void +gzofstream::close() +{ + if (!sb.close()) + this->setstate(std::ios_base::failbit); +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/zfstream.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/zfstream.h new file mode 100644 index 00000000..8574479a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/iostream3/zfstream.h @@ -0,0 +1,466 @@ +/* + * A C++ I/O streams interface to the zlib gz* functions + * + * by Ludwig Schwardt + * original version by Kevin Ruland + * + * This version is standard-compliant and compatible with gcc 3.x. + */ + +#ifndef ZFSTREAM_H +#define ZFSTREAM_H + +#include // not iostream, since we don't need cin/cout +#include +#include "zlib.h" + +/*****************************************************************************/ + +/** + * @brief Gzipped file stream buffer class. + * + * This class implements basic_filebuf for gzipped files. It doesn't yet support + * seeking (allowed by zlib but slow/limited), putback and read/write access + * (tricky). Otherwise, it attempts to be a drop-in replacement for the standard + * file streambuf. +*/ +class gzfilebuf : public std::streambuf +{ +public: + // Default constructor. + gzfilebuf(); + + // Destructor. + virtual + ~gzfilebuf(); + + /** + * @brief Set compression level and strategy on the fly. + * @param comp_level Compression level (see zlib.h for allowed values) + * @param comp_strategy Compression strategy (see zlib.h for allowed values) + * @return Z_OK on success, Z_STREAM_ERROR otherwise. + * + * Unfortunately, these parameters cannot be modified separately, as the + * previous zfstream version assumed. Since the strategy is seldom changed, + * it can default and setcompression(level) then becomes like the old + * setcompressionlevel(level). + */ + int + setcompression(int comp_level, + int comp_strategy = Z_DEFAULT_STRATEGY); + + /** + * @brief Check if file is open. + * @return True if file is open. + */ + bool + is_open() const { return (file != NULL); } + + /** + * @brief Open gzipped file. + * @param name File name. + * @param mode Open mode flags. + * @return @c this on success, NULL on failure. + */ + gzfilebuf* + open(const char* name, + std::ios_base::openmode mode); + + /** + * @brief Attach to already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags. + * @return @c this on success, NULL on failure. + */ + gzfilebuf* + attach(int fd, + std::ios_base::openmode mode); + + /** + * @brief Close gzipped file. + * @return @c this on success, NULL on failure. + */ + gzfilebuf* + close(); + +protected: + /** + * @brief Convert ios open mode int to mode string used by zlib. + * @return True if valid mode flag combination. + */ + bool + open_mode(std::ios_base::openmode mode, + char* c_mode) const; + + /** + * @brief Number of characters available in stream buffer. + * @return Number of characters. + * + * This indicates number of characters in get area of stream buffer. + * These characters can be read without accessing the gzipped file. + */ + virtual std::streamsize + showmanyc(); + + /** + * @brief Fill get area from gzipped file. + * @return First character in get area on success, EOF on error. + * + * This actually reads characters from gzipped file to stream + * buffer. Always buffered. + */ + virtual int_type + underflow(); + + /** + * @brief Write put area to gzipped file. + * @param c Extra character to add to buffer contents. + * @return Non-EOF on success, EOF on error. + * + * This actually writes characters in stream buffer to + * gzipped file. With unbuffered output this is done one + * character at a time. + */ + virtual int_type + overflow(int_type c = traits_type::eof()); + + /** + * @brief Installs external stream buffer. + * @param p Pointer to char buffer. + * @param n Size of external buffer. + * @return @c this on success, NULL on failure. + * + * Call setbuf(0,0) to enable unbuffered output. + */ + virtual std::streambuf* + setbuf(char_type* p, + std::streamsize n); + + /** + * @brief Flush stream buffer to file. + * @return 0 on success, -1 on error. + * + * This calls underflow(EOF) to do the job. + */ + virtual int + sync(); + +// +// Some future enhancements +// +// virtual int_type uflow(); +// virtual int_type pbackfail(int_type c = traits_type::eof()); +// virtual pos_type +// seekoff(off_type off, +// std::ios_base::seekdir way, +// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out); +// virtual pos_type +// seekpos(pos_type sp, +// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out); + +private: + /** + * @brief Allocate internal buffer. + * + * This function is safe to call multiple times. It will ensure + * that a proper internal buffer exists if it is required. If the + * buffer already exists or is external, the buffer pointers will be + * reset to their original state. + */ + void + enable_buffer(); + + /** + * @brief Destroy internal buffer. + * + * This function is safe to call multiple times. It will ensure + * that the internal buffer is deallocated if it exists. In any + * case, it will also reset the buffer pointers. + */ + void + disable_buffer(); + + /** + * Underlying file pointer. + */ + gzFile file; + + /** + * Mode in which file was opened. + */ + std::ios_base::openmode io_mode; + + /** + * @brief True if this object owns file descriptor. + * + * This makes the class responsible for closing the file + * upon destruction. + */ + bool own_fd; + + /** + * @brief Stream buffer. + * + * For simplicity this remains allocated on the free store for the + * entire life span of the gzfilebuf object, unless replaced by setbuf. + */ + char_type* buffer; + + /** + * @brief Stream buffer size. + * + * Defaults to system default buffer size (typically 8192 bytes). + * Modified by setbuf. + */ + std::streamsize buffer_size; + + /** + * @brief True if this object owns stream buffer. + * + * This makes the class responsible for deleting the buffer + * upon destruction. + */ + bool own_buffer; +}; + +/*****************************************************************************/ + +/** + * @brief Gzipped file input stream class. + * + * This class implements ifstream for gzipped files. Seeking and putback + * is not supported yet. +*/ +class gzifstream : public std::istream +{ +public: + // Default constructor + gzifstream(); + + /** + * @brief Construct stream on gzipped file to be opened. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::in). + */ + explicit + gzifstream(const char* name, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * @brief Construct stream on already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::in). + */ + explicit + gzifstream(int fd, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * Obtain underlying stream buffer. + */ + gzfilebuf* + rdbuf() const + { return const_cast(&sb); } + + /** + * @brief Check if file is open. + * @return True if file is open. + */ + bool + is_open() { return sb.is_open(); } + + /** + * @brief Open gzipped file. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::in). + * + * Stream will be in state good() if file opens successfully; + * otherwise in state fail(). This differs from the behavior of + * ifstream, which never sets the state to good() and therefore + * won't allow you to reuse the stream for a second file unless + * you manually clear() the state. The choice is a matter of + * convenience. + */ + void + open(const char* name, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * @brief Attach to already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::in). + * + * Stream will be in state good() if attach succeeded; otherwise + * in state fail(). + */ + void + attach(int fd, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * @brief Close gzipped file. + * + * Stream will be in state fail() if close failed. + */ + void + close(); + +private: + /** + * Underlying stream buffer. + */ + gzfilebuf sb; +}; + +/*****************************************************************************/ + +/** + * @brief Gzipped file output stream class. + * + * This class implements ofstream for gzipped files. Seeking and putback + * is not supported yet. +*/ +class gzofstream : public std::ostream +{ +public: + // Default constructor + gzofstream(); + + /** + * @brief Construct stream on gzipped file to be opened. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::out). + */ + explicit + gzofstream(const char* name, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * @brief Construct stream on already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::out). + */ + explicit + gzofstream(int fd, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * Obtain underlying stream buffer. + */ + gzfilebuf* + rdbuf() const + { return const_cast(&sb); } + + /** + * @brief Check if file is open. + * @return True if file is open. + */ + bool + is_open() { return sb.is_open(); } + + /** + * @brief Open gzipped file. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::out). + * + * Stream will be in state good() if file opens successfully; + * otherwise in state fail(). This differs from the behavior of + * ofstream, which never sets the state to good() and therefore + * won't allow you to reuse the stream for a second file unless + * you manually clear() the state. The choice is a matter of + * convenience. + */ + void + open(const char* name, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * @brief Attach to already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::out). + * + * Stream will be in state good() if attach succeeded; otherwise + * in state fail(). + */ + void + attach(int fd, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * @brief Close gzipped file. + * + * Stream will be in state fail() if close failed. + */ + void + close(); + +private: + /** + * Underlying stream buffer. + */ + gzfilebuf sb; +}; + +/*****************************************************************************/ + +/** + * @brief Gzipped file output stream manipulator class. + * + * This class defines a two-argument manipulator for gzofstream. It is used + * as base for the setcompression(int,int) manipulator. +*/ +template + class gzomanip2 + { + public: + // Allows insertor to peek at internals + template + friend gzofstream& + operator<<(gzofstream&, + const gzomanip2&); + + // Constructor + gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2), + T1 v1, + T2 v2); + private: + // Underlying manipulator function + gzofstream& + (*func)(gzofstream&, T1, T2); + + // Arguments for manipulator function + T1 val1; + T2 val2; + }; + +/*****************************************************************************/ + +// Manipulator function thunks through to stream buffer +inline gzofstream& +setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY) +{ + (gzs.rdbuf())->setcompression(l, s); + return gzs; +} + +// Manipulator constructor stores arguments +template + inline + gzomanip2::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2), + T1 v1, + T2 v2) + : func(f), val1(v1), val2(v2) + { } + +// Insertor applies underlying manipulator function to stream +template + inline gzofstream& + operator<<(gzofstream& s, const gzomanip2& m) + { return (*m.func)(s, m.val1, m.val2); } + +// Insert this onto stream to simplify setting of compression level +inline gzomanip2 +setcompression(int l, int s = Z_DEFAULT_STRATEGY) +{ return gzomanip2(&setcompression, l, s); } + +#endif // ZFSTREAM_H diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/bld_ml64.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/bld_ml64.bat new file mode 100644 index 00000000..8f9343d0 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/bld_ml64.bat @@ -0,0 +1,2 @@ +ml64.exe /Flinffasx64 /c /Zi inffasx64.asm +ml64.exe /Flgvmat64 /c /Zi gvmat64.asm diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/gvmat64.asm b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/gvmat64.asm new file mode 100644 index 00000000..9879c28b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/gvmat64.asm @@ -0,0 +1,553 @@ +;uInt longest_match_x64( +; deflate_state *s, +; IPos cur_match); /* current match */ + +; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86_64 +; (AMD64 on Athlon 64, Opteron, Phenom +; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7) +; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; +; File written by Gilles Vollant, by converting to assembly the longest_match +; from Jean-loup Gailly in deflate.c of zLib and infoZip zip. +; +; and by taking inspiration on asm686 with masm, optimised assembly code +; from Brian Raiter, written 1998 +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software +; 3. This notice may not be removed or altered from any source distribution. +; +; +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; to compile this file for infozip Zip, I use option: +; ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm +; +; to compile this file for zLib, I use option: +; ml64.exe /Flgvmat64 /c /Zi gvmat64.asm +; Be carrefull to adapt zlib1222add below to your version of zLib +; (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change +; value of zlib1222add later) +; +; This file compile with Microsoft Macro Assembler (x64) for AMD64 +; +; ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK +; +; (you can get Windows WDK with ml64 for AMD64 from +; http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price) +; + + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; /* current match */ +.code +longest_match PROC + + +;LocalVarsSize equ 88 + LocalVarsSize equ 72 + +; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12 +; free register : r14,r15 +; register can be saved : rsp + + chainlenwmask equ rsp + 8 - LocalVarsSize ; high word: current chain len + ; low word: s->wmask +;window equ rsp + xx - LocalVarsSize ; local copy of s->window ; stored in r10 +;windowbestlen equ rsp + xx - LocalVarsSize ; s->window + bestlen , use r10+r11 +;scanstart equ rsp + xx - LocalVarsSize ; first two bytes of string ; stored in r12w +;scanend equ rsp + xx - LocalVarsSize ; last two bytes of string use ebx +;scanalign equ rsp + xx - LocalVarsSize ; dword-misalignment of string r13 +;bestlen equ rsp + xx - LocalVarsSize ; size of best match so far -> r11d +;scan equ rsp + xx - LocalVarsSize ; ptr to string wanting match -> r9 +IFDEF INFOZIP +ELSE + nicematch equ (rsp + 16 - LocalVarsSize) ; a good enough match size +ENDIF + +save_rdi equ rsp + 24 - LocalVarsSize +save_rsi equ rsp + 32 - LocalVarsSize +save_rbx equ rsp + 40 - LocalVarsSize +save_rbp equ rsp + 48 - LocalVarsSize +save_r12 equ rsp + 56 - LocalVarsSize +save_r13 equ rsp + 64 - LocalVarsSize +;save_r14 equ rsp + 72 - LocalVarsSize +;save_r15 equ rsp + 80 - LocalVarsSize + + +; summary of register usage +; scanend ebx +; scanendw bx +; chainlenwmask edx +; curmatch rsi +; curmatchd esi +; windowbestlen r8 +; scanalign r9 +; scanalignd r9d +; window r10 +; bestlen r11 +; bestlend r11d +; scanstart r12d +; scanstartw r12w +; scan r13 +; nicematch r14d +; limit r15 +; limitd r15d +; prev rcx + +; all the +4 offsets are due to the addition of pending_buf_size (in zlib +; in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, remove the +4). +; Note : these value are good with a 8 bytes boundary pack structure + + + MAX_MATCH equ 258 + MIN_MATCH equ 3 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + + +IFDEF INFOZIP + +_DATA SEGMENT +COMM window_size:DWORD +; WMask ; 7fff +COMM window:BYTE:010040H +COMM prev:WORD:08000H +; MatchLen : unused +; PrevMatch : unused +COMM strstart:DWORD +COMM match_start:DWORD +; Lookahead : ignore +COMM prev_length:DWORD ; PrevLen +COMM max_chain_length:DWORD +COMM good_match:DWORD +COMM nice_match:DWORD +prev_ad equ OFFSET prev +window_ad equ OFFSET window +nicematch equ nice_match +_DATA ENDS +WMask equ 07fffh + +ELSE + + IFNDEF zlib1222add + zlib1222add equ 8 + ENDIF +dsWSize equ 56+zlib1222add+(zlib1222add/2) +dsWMask equ 64+zlib1222add+(zlib1222add/2) +dsWindow equ 72+zlib1222add +dsPrev equ 88+zlib1222add +dsMatchLen equ 128+zlib1222add +dsPrevMatch equ 132+zlib1222add +dsStrStart equ 140+zlib1222add +dsMatchStart equ 144+zlib1222add +dsLookahead equ 148+zlib1222add +dsPrevLen equ 152+zlib1222add +dsMaxChainLen equ 156+zlib1222add +dsGoodMatch equ 172+zlib1222add +dsNiceMatch equ 176+zlib1222add + +window_size equ [ rcx + dsWSize] +WMask equ [ rcx + dsWMask] +window_ad equ [ rcx + dsWindow] +prev_ad equ [ rcx + dsPrev] +strstart equ [ rcx + dsStrStart] +match_start equ [ rcx + dsMatchStart] +Lookahead equ [ rcx + dsLookahead] ; 0ffffffffh on infozip +prev_length equ [ rcx + dsPrevLen] +max_chain_length equ [ rcx + dsMaxChainLen] +good_match equ [ rcx + dsGoodMatch] +nice_match equ [ rcx + dsNiceMatch] +ENDIF + +; parameter 1 in r8(deflate state s), param 2 in rdx (cur match) + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch. + + + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + +;;; Retrieve the function arguments. r8d will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + +; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match) + +; this clear high 32 bits of r8, which can be garbage in both r8 and rdx + + mov [save_rdi],rdi + mov [save_rsi],rsi + mov [save_rbx],rbx + mov [save_rbp],rbp +IFDEF INFOZIP + mov r8d,ecx +ELSE + mov r8d,edx +ENDIF + mov [save_r12],r12 + mov [save_r13],r13 +; mov [save_r14],r14 +; mov [save_r15],r15 + + +;;; uInt wmask = s->w_mask; +;;; unsigned chain_length = s->max_chain_length; +;;; if (s->prev_length >= s->good_match) { +;;; chain_length >>= 2; +;;; } + + mov edi, prev_length + mov esi, good_match + mov eax, WMask + mov ebx, max_chain_length + cmp edi, esi + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +;;; chainlen is decremented once beforehand so that the function can +;;; use the sign flag instead of the zero flag for the exit test. +;;; It is then shifted into the high word, to make room for the wmask +;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + +;;; on zlib only +;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + +IFDEF INFOZIP + mov [chainlenwmask], ebx +; on infozip nice_match = [nice_match] +ELSE + mov eax, nice_match + mov [chainlenwmask], ebx + mov r10d, Lookahead + cmp r10d, eax + cmovnl r10d, eax + mov [nicematch],r10d +ENDIF + +;;; register Bytef *scan = s->window + s->strstart; + mov r10, window_ad + mov ebp, strstart + lea r13, [r10 + rbp] + +;;; Determine how many bytes the scan ptr is off from being +;;; dword-aligned. + + mov r9,r13 + neg r13 + and r13,3 + +;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +;;; s->strstart - (IPos)MAX_DIST(s) : NIL; +IFDEF INFOZIP + mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1)) +ELSE + mov eax, window_size + sub eax, MIN_LOOKAHEAD +ENDIF + xor edi,edi + sub ebp, eax + + mov r11d, prev_length + + cmovng ebp,edi + +;;; int best_len = s->prev_length; + + +;;; Store the sum of s->window + best_len in esi locally, and in esi. + + lea rsi,[r10+r11] + +;;; register ush scan_start = *(ushf*)scan; +;;; register ush scan_end = *(ushf*)(scan+best_len-1); +;;; Posf *prev = s->prev; + + movzx r12d,word ptr [r9] + movzx ebx, word ptr [r9 + r11 - 1] + + mov rdi, prev_ad + +;;; Jump into the main loop. + + mov edx, [chainlenwmask] + + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop1: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry1: + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop2: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry2: + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop4: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry4: + + cmp bx,word ptr [rsi + r8 - 1] + jnz LookupLoop1 + jmp LookupLoopIsZero + + +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; r8d = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit + +LookupLoop: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry: + + cmp bx,word ptr [rsi + r8 - 1] + jnz LookupLoop1 +LookupLoopIsZero: + cmp r12w, word ptr [r10 + r8] + jnz LookupLoop1 + + +;;; Store the current value of chainlen. + mov [chainlenwmask], edx + +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). + + lea rsi,[r8+r10] + mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8) + lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8] + lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8] + + prefetcht1 [rsi+rdx] + prefetcht1 [rdi+rdx] + + +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust rdx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (rsi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. + + +LoopCmps: + mov rax, [rsi + rdx] + xor rax, [rdi + rdx] + jnz LeaveLoopCmps + + mov rax, [rsi + rdx + 8] + xor rax, [rdi + rdx + 8] + jnz LeaveLoopCmps8 + + + mov rax, [rsi + rdx + 8+8] + xor rax, [rdi + rdx + 8+8] + jnz LeaveLoopCmps16 + + add rdx,8+8+8 + + jnz short LoopCmps + jmp short LenMaximum +LeaveLoopCmps16: add rdx,8 +LeaveLoopCmps8: add rdx,8 +LeaveLoopCmps: + + test eax, 0000FFFFh + jnz LenLower + + test eax,0ffffffffh + + jnz LenLower32 + + add rdx,4 + shr rax,32 + or ax,ax + jnz LenLower + +LenLower32: + shr eax,16 + add rdx,2 +LenLower: sub al, 1 + adc rdx, 0 +;;; Calculate the length of the match. If it is longer than MAX_MATCH, +;;; then automatically accept it as the best possible match and leave. + + lea rax, [rdi + rdx] + sub rax, r9 + cmp eax, MAX_MATCH + jge LenMaximum + +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. +;/////////////////////////////////// + + cmp eax, r11d + jg LongerMatch + + lea rsi,[r10+r11] + + mov rdi, prev_ad + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); + +LongerMatch: + mov r11d, eax + mov match_start, r8d + cmp eax, [nicematch] + jge LeaveNow + + lea rsi,[r10+rax] + + movzx ebx, word ptr [r9 + rax - 1] + mov rdi, prev_ad + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; Accept the current string, with the maximum possible length. + +LenMaximum: + mov r11d,MAX_MATCH + mov match_start, r8d + +;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +;;; return s->lookahead; + +LeaveNow: +IFDEF INFOZIP + mov eax,r11d +ELSE + mov eax, Lookahead + cmp r11d, eax + cmovng eax, r11d +ENDIF + +;;; Restore the stack and return from whence we came. + + + mov rsi,[save_rsi] + mov rdi,[save_rdi] + mov rbx,[save_rbx] + mov rbp,[save_rbp] + mov r12,[save_r12] + mov r13,[save_r13] +; mov r14,[save_r14] +; mov r15,[save_r15] + + + ret 0 +; please don't remove this string ! +; Your can freely use gvmat64 in any free or commercial app +; but it is far better don't remove the string in the binary! + db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0 +longest_match ENDP + +match_init PROC + ret 0 +match_init ENDP + + +END diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/inffas8664.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/inffas8664.c new file mode 100644 index 00000000..e8af06fa --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/inffas8664.c @@ -0,0 +1,186 @@ +/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding + * version for AMD64 on Windows using Microsoft C compiler + * + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant + * + * inffas8664.c call function inffas8664fnc in inffasx64.asm + * inffasx64.asm is automatically convert from AMD64 portion of inffas86.c + * + * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also + * slightly quicker on x86 systems because, instead of using rep movsb to copy + * data, it uses rep movsw, which moves data in 2-byte chunks instead of single + * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates + * from http://fedora.linux.duke.edu/fc1_x86_64 + * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with + * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version, + * when decompressing mozilla-source-1.3.tar.gz. + * + * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from + * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at + * the moment. I have successfully compiled and tested this code with gcc2.96, + * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S + * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX + * enabled. I will attempt to merge the MMX code into this version. Newer + * versions of this and inffast.S can be found at + * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ + * + */ + +#include +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* Mark Adler's comments from inffast.c: */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ + + + + typedef struct inffast_ar { +/* 64 32 x86 x86_64 */ +/* ar offset register */ +/* 0 0 */ void *esp; /* esp save */ +/* 8 4 */ void *ebp; /* ebp save */ +/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */ +/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */ +/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */ +/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */ +/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */ +/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */ +/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */ +/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */ +/* 80 40 */ size_t /*unsigned long */hold; /* edx rdx local strm->hold */ +/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */ +/* 92 48 */ unsigned wsize; /* window size */ +/* 96 52 */ unsigned write; /* window write index */ +/*100 56 */ unsigned lmask; /* r12 mask for lcode */ +/*104 60 */ unsigned dmask; /* r13 mask for dcode */ +/*108 64 */ unsigned len; /* r14 match length */ +/*112 68 */ unsigned dist; /* r15 match distance */ +/*116 72 */ unsigned status; /* set when state chng*/ + } type_ar; +#ifdef ASMINF + +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + type_ar ar; + void inffas8664fnc(struct inffast_ar * par); + + + +#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64)) +#define PAD_AVAIL_IN 6 +#define PAD_AVAIL_OUT 258 +#else +#define PAD_AVAIL_IN 5 +#define PAD_AVAIL_OUT 257 +#endif + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + + ar.in = strm->next_in; + ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN); + ar.out = strm->next_out; + ar.beg = ar.out - (start - strm->avail_out); + ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT); + ar.wsize = state->wsize; + ar.write = state->wnext; + ar.window = state->window; + ar.hold = state->hold; + ar.bits = state->bits; + ar.lcode = state->lencode; + ar.dcode = state->distcode; + ar.lmask = (1U << state->lenbits) - 1; + ar.dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + /* align in on 1/2 hold size boundary */ + while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) { + ar.hold += (unsigned long)*ar.in++ << ar.bits; + ar.bits += 8; + } + + inffas8664fnc(&ar); + + if (ar.status > 1) { + if (ar.status == 2) + strm->msg = "invalid literal/length code"; + else if (ar.status == 3) + strm->msg = "invalid distance code"; + else + strm->msg = "invalid distance too far back"; + state->mode = BAD; + } + else if ( ar.status == 1 ) { + state->mode = TYPE; + } + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + ar.len = ar.bits >> 3; + ar.in -= ar.len; + ar.bits -= ar.len << 3; + ar.hold &= (1U << ar.bits) - 1; + + /* update state and return */ + strm->next_in = ar.in; + strm->next_out = ar.out; + strm->avail_in = (unsigned)(ar.in < ar.last ? + PAD_AVAIL_IN + (ar.last - ar.in) : + PAD_AVAIL_IN - (ar.in - ar.last)); + strm->avail_out = (unsigned)(ar.out < ar.end ? + PAD_AVAIL_OUT + (ar.end - ar.out) : + PAD_AVAIL_OUT - (ar.out - ar.end)); + state->hold = (unsigned long)ar.hold; + state->bits = ar.bits; + return; +} + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/inffasx64.asm b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/inffasx64.asm new file mode 100644 index 00000000..60a8d89b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/inffasx64.asm @@ -0,0 +1,396 @@ +; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding +; version for AMD64 on Windows using Microsoft C compiler +; +; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c +; inffasx64.asm is called by inffas8664.c, which contain more info. + + +; to compile this file, I use option +; ml64.exe /Flinffasx64 /c /Zi inffasx64.asm +; with Microsoft Macro Assembler (x64) for AMD64 +; + +; This file compile with Microsoft Macro Assembler (x64) for AMD64 +; +; ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK +; +; (you can get Windows WDK with ml64 for AMD64 from +; http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price) +; + + +.code +inffas8664fnc PROC + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch. + + + mov [rsp-8],rsi + mov [rsp-16],rdi + mov [rsp-24],r12 + mov [rsp-32],r13 + mov [rsp-40],r14 + mov [rsp-48],r15 + mov [rsp-56],rbx + + mov rax,rcx + + mov [rax+8], rbp ; /* save regs rbp and rsp */ + mov [rax], rsp + + mov rsp, rax ; /* make rsp point to &ar */ + + mov rsi, [rsp+16] ; /* rsi = in */ + mov rdi, [rsp+32] ; /* rdi = out */ + mov r9, [rsp+24] ; /* r9 = last */ + mov r10, [rsp+48] ; /* r10 = end */ + mov rbp, [rsp+64] ; /* rbp = lcode */ + mov r11, [rsp+72] ; /* r11 = dcode */ + mov rdx, [rsp+80] ; /* rdx = hold */ + mov ebx, [rsp+88] ; /* ebx = bits */ + mov r12d, [rsp+100] ; /* r12d = lmask */ + mov r13d, [rsp+104] ; /* r13d = dmask */ + ; /* r14d = len */ + ; /* r15d = dist */ + + + cld + cmp r10, rdi + je L_one_time ; /* if only one decode left */ + cmp r9, rsi + + jne L_do_loop + + +L_one_time: + mov r8, r12 ; /* r8 = lmask */ + cmp bl, 32 + ja L_get_length_code_one_time + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + jmp L_get_length_code_one_time + +ALIGN 4 +L_while_test: + cmp r10, rdi + jbe L_break_loop + cmp r9, rsi + jbe L_break_loop + +L_do_loop: + mov r8, r12 ; /* r8 = lmask */ + cmp bl, 32 + ja L_get_length_code ; /* if (32 < bits) */ + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + +L_get_length_code: + and r8, rdx ; /* r8 &= hold */ + mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */ + + mov cl, ah ; /* cl = this.bits */ + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base ; /* if (op != 0) 45.7% */ + + mov r8, r12 ; /* r8 = lmask */ + shr eax, 16 ; /* output this.val char */ + stosb + +L_get_length_code_one_time: + and r8, rdx ; /* r8 &= hold */ + mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */ + +L_dolen: + mov cl, ah ; /* cl = this.bits */ + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base ; /* if (op != 0) 45.7% */ + + shr eax, 16 ; /* output this.val char */ + stosb + jmp L_while_test + +ALIGN 4 +L_test_for_length_base: + mov r14d, eax ; /* len = this */ + shr r14d, 16 ; /* len = this.val */ + mov cl, al + + test al, 16 + jz L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */ + and cl, 15 ; /* op &= 15 */ + jz L_decode_distance ; /* if (!op) */ + +L_add_bits_to_len: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + shr rdx, cl + add r14d, eax ; /* len += hold & mask[op] */ + +L_decode_distance: + mov r8, r13 ; /* r8 = dmask */ + cmp bl, 32 + ja L_get_distance_code ; /* if (32 < bits) */ + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + +L_get_distance_code: + and r8, rdx ; /* r8 &= hold */ + mov eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */ + +L_dodist: + mov r15d, eax ; /* dist = this */ + shr r15d, 16 ; /* dist = this.val */ + mov cl, ah + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + mov cl, al ; /* cl = this.op */ + + test al, 16 ; /* if ((op & 16) == 0) */ + jz L_test_for_second_level_dist + and cl, 15 ; /* op &= 15 */ + jz L_check_dist_one + +L_add_bits_to_dist: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax ; /* (1 << op) - 1 */ + and eax, edx ; /* eax &= hold */ + shr rdx, cl + add r15d, eax ; /* dist += hold & ((1 << op) - 1) */ + +L_check_window: + mov r8, rsi ; /* save in so from can use it's reg */ + mov rax, rdi + sub rax, [rsp+40] ; /* nbytes = out - beg */ + + cmp eax, r15d + jb L_clip_window ; /* if (dist > nbytes) 4.2% */ + + mov ecx, r14d ; /* ecx = len */ + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + + sar ecx, 1 + jnc L_copy_two ; /* if len % 2 == 0 */ + + rep movsw + mov al, [rsi] + mov [rdi], al + inc rdi + + mov rsi, r8 ; /* move in back to %rsi, toss from */ + jmp L_while_test + +L_copy_two: + rep movsw + mov rsi, r8 ; /* move in back to %rsi, toss from */ + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp r15d, 1 ; /* if dist 1, is a memset */ + jne L_check_window + cmp [rsp+40], rdi ; /* if out == beg, outside window */ + je L_check_window + + mov ecx, r14d ; /* ecx = len */ + mov al, [rdi-1] + mov ah, al + + sar ecx, 1 + jnc L_set_two + mov [rdi], al + inc rdi + +L_set_two: + rep stosw + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + test al, 64 + jnz L_test_for_end_of_block ; /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + add eax, r14d ; /* eax += len */ + mov eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/ + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + test al, 64 + jnz L_invalid_distance_code ; /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + add eax, r15d ; /* eax += dist */ + mov eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/ + jmp L_dodist + +ALIGN 4 +L_clip_window: + mov ecx, eax ; /* ecx = nbytes */ + mov eax, [rsp+92] ; /* eax = wsize, prepare for dist cmp */ + neg ecx ; /* nbytes = -nbytes */ + + cmp eax, r15d + jb L_invalid_distance_too_far ; /* if (dist > wsize) */ + + add ecx, r15d ; /* nbytes = dist - nbytes */ + cmp dword ptr [rsp+96], 0 + jne L_wrap_around_window ; /* if (write != 0) */ + + mov rsi, [rsp+56] ; /* from = window */ + sub eax, ecx ; /* eax -= nbytes */ + add rsi, rax ; /* from += wsize - nbytes */ + + mov eax, r14d ; /* eax = len */ + cmp r14d, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* eax -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = &out[ -dist ] */ + jmp L_do_copy + +ALIGN 4 +L_wrap_around_window: + mov eax, [rsp+96] ; /* eax = write */ + cmp ecx, eax + jbe L_contiguous_in_window ; /* if (write >= nbytes) */ + + mov esi, [rsp+92] ; /* from = wsize */ + add rsi, [rsp+56] ; /* from += window */ + add rsi, rax ; /* from += write */ + sub rsi, rcx ; /* from -= nbytes */ + sub ecx, eax ; /* nbytes -= write */ + + mov eax, r14d ; /* eax = len */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, [rsp+56] ; /* from = window */ + mov ecx, [rsp+96] ; /* nbytes = write */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_contiguous_in_window: + mov rsi, [rsp+56] ; /* rsi = window */ + add rsi, rax + sub rsi, rcx ; /* from += write - nbytes */ + + mov eax, r14d ; /* eax = len */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + jmp L_do_copy ; /* if (nbytes >= len) */ + +ALIGN 4 +L_do_copy: + mov ecx, eax ; /* ecx = len */ + rep movsb + + mov rsi, r8 ; /* move in back to %esi, toss from */ + jmp L_while_test + +L_test_for_end_of_block: + test al, 32 + jz L_invalid_literal_length_code + mov dword ptr [rsp+116], 1 + jmp L_break_loop_with_status + +L_invalid_literal_length_code: + mov dword ptr [rsp+116], 2 + jmp L_break_loop_with_status + +L_invalid_distance_code: + mov dword ptr [rsp+116], 3 + jmp L_break_loop_with_status + +L_invalid_distance_too_far: + mov dword ptr [rsp+116], 4 + jmp L_break_loop_with_status + +L_break_loop: + mov dword ptr [rsp+116], 0 + +L_break_loop_with_status: +; /* put in, out, bits, and hold back into ar and pop esp */ + mov [rsp+16], rsi ; /* in */ + mov [rsp+32], rdi ; /* out */ + mov [rsp+88], ebx ; /* bits */ + mov [rsp+80], rdx ; /* hold */ + + mov rax, [rsp] ; /* restore rbp and rsp */ + mov rbp, [rsp+8] + mov rsp, rax + + + + mov rsi,[rsp-8] + mov rdi,[rsp-16] + mov r12,[rsp-24] + mov r13,[rsp-32] + mov r14,[rsp-40] + mov r15,[rsp-48] + mov rbx,[rsp-56] + + ret 0 +; : +; : "m" (ar) +; : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", +; "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" +; ); + +inffas8664fnc ENDP +;_TEXT ENDS +END diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/readme.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/readme.txt new file mode 100644 index 00000000..2da67334 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx64/readme.txt @@ -0,0 +1,31 @@ +Summary +------- +This directory contains ASM implementations of the functions +longest_match() and inflate_fast(), for 64 bits x86 (both AMD64 and Intel EM64t), +for use with Microsoft Macro Assembler (x64) for AMD64 and Microsoft C++ 64 bits. + +gvmat64.asm is written by Gilles Vollant (2005), by using Brian Raiter 686/32 bits + assembly optimized version from Jean-loup Gailly original longest_match function + +inffasx64.asm and inffas8664.c were written by Chris Anderson, by optimizing + original function from Mark Adler + +Use instructions +---------------- +Assemble the .asm files using MASM and put the object files into the zlib source +directory. You can also get object files here: + + http://www.winimage.com/zLibDll/zlib124_masm_obj.zip + +define ASMV and ASMINF in your project. Include inffas8664.c in your source tree, +and inffasx64.obj and gvmat64.obj as object to link. + + +Build instructions +------------------ +run bld_64.bat with Microsoft Macro Assembler (x64) for AMD64 (ml64.exe) + +ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK + +You can get Windows 2003 server DDK with ml64 and cl for AMD64 from + http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price) diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/bld_ml32.bat b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/bld_ml32.bat new file mode 100644 index 00000000..e1b86bf6 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/bld_ml32.bat @@ -0,0 +1,2 @@ +ml /coff /Zi /c /Flmatch686.lst match686.asm +ml /coff /Zi /c /Flinffas32.lst inffas32.asm diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/inffas32.asm b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/inffas32.asm new file mode 100644 index 00000000..03d20f83 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/inffas32.asm @@ -0,0 +1,1080 @@ +;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding +; * +; * inffas32.asm is derivated from inffas86.c, with translation of assembly code +; * +; * Copyright (C) 1995-2003 Mark Adler +; * For conditions of distribution and use, see copyright notice in zlib.h +; * +; * Copyright (C) 2003 Chris Anderson +; * Please use the copyright conditions above. +; * +; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from +; * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at +; * the moment. I have successfully compiled and tested this code with gcc2.96, +; * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S +; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX +; * enabled. I will attempt to merge the MMX code into this version. Newer +; * versions of this and inffast.S can be found at +; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ +; * +; * 2005 : modification by Gilles Vollant +; */ +; For Visual C++ 4.x and higher and ML 6.x and higher +; ml.exe is in directory \MASM611C of Win95 DDK +; ml.exe is also distributed in http://www.masm32.com/masmdl.htm +; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/ +; +; +; compile with command line option +; ml /coff /Zi /c /Flinffas32.lst inffas32.asm + +; if you define NO_GZIP (see inflate.h), compile with +; ml /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm + + +; zlib122sup is 0 fort zlib 1.2.2.1 and lower +; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head +; in inflate_state in inflate.h) +zlib1222sup equ 8 + + +IFDEF GUNZIP + INFLATE_MODE_TYPE equ 11 + INFLATE_MODE_BAD equ 26 +ELSE + IFNDEF NO_GUNZIP + INFLATE_MODE_TYPE equ 11 + INFLATE_MODE_BAD equ 26 + ELSE + INFLATE_MODE_TYPE equ 3 + INFLATE_MODE_BAD equ 17 + ENDIF +ENDIF + + +; 75 "inffast.S" +;FILE "inffast.S" + +;;;GLOBAL _inflate_fast + +;;;SECTION .text + + + + .586p + .mmx + + name inflate_fast_x86 + .MODEL FLAT + +_DATA segment +inflate_fast_use_mmx: + dd 1 + + +_TEXT segment + + + +ALIGN 4 + db 'Fast decoding Code from Chris Anderson' + db 0 + +ALIGN 4 +invalid_literal_length_code_msg: + db 'invalid literal/length code' + db 0 + +ALIGN 4 +invalid_distance_code_msg: + db 'invalid distance code' + db 0 + +ALIGN 4 +invalid_distance_too_far_msg: + db 'invalid distance too far back' + db 0 + + +ALIGN 4 +inflate_fast_mask: +dd 0 +dd 1 +dd 3 +dd 7 +dd 15 +dd 31 +dd 63 +dd 127 +dd 255 +dd 511 +dd 1023 +dd 2047 +dd 4095 +dd 8191 +dd 16383 +dd 32767 +dd 65535 +dd 131071 +dd 262143 +dd 524287 +dd 1048575 +dd 2097151 +dd 4194303 +dd 8388607 +dd 16777215 +dd 33554431 +dd 67108863 +dd 134217727 +dd 268435455 +dd 536870911 +dd 1073741823 +dd 2147483647 +dd 4294967295 + + +mode_state equ 0 ;/* state->mode */ +wsize_state equ (32+zlib1222sup) ;/* state->wsize */ +write_state equ (36+4+zlib1222sup) ;/* state->write */ +window_state equ (40+4+zlib1222sup) ;/* state->window */ +hold_state equ (44+4+zlib1222sup) ;/* state->hold */ +bits_state equ (48+4+zlib1222sup) ;/* state->bits */ +lencode_state equ (64+4+zlib1222sup) ;/* state->lencode */ +distcode_state equ (68+4+zlib1222sup) ;/* state->distcode */ +lenbits_state equ (72+4+zlib1222sup) ;/* state->lenbits */ +distbits_state equ (76+4+zlib1222sup) ;/* state->distbits */ + + +;;SECTION .text +; 205 "inffast.S" +;GLOBAL inflate_fast_use_mmx + +;SECTION .data + + +; GLOBAL inflate_fast_use_mmx:object +;.size inflate_fast_use_mmx, 4 +; 226 "inffast.S" +;SECTION .text + +ALIGN 4 +_inflate_fast proc near +.FPO (16, 4, 0, 0, 1, 0) + push edi + push esi + push ebp + push ebx + pushfd + sub esp,64 + cld + + + + + mov esi, [esp+88] + mov edi, [esi+28] + + + + + + + + mov edx, [esi+4] + mov eax, [esi+0] + + add edx,eax + sub edx,11 + + mov [esp+44],eax + mov [esp+20],edx + + mov ebp, [esp+92] + mov ecx, [esi+16] + mov ebx, [esi+12] + + sub ebp,ecx + neg ebp + add ebp,ebx + + sub ecx,257 + add ecx,ebx + + mov [esp+60],ebx + mov [esp+40],ebp + mov [esp+16],ecx +; 285 "inffast.S" + mov eax, [edi+lencode_state] + mov ecx, [edi+distcode_state] + + mov [esp+8],eax + mov [esp+12],ecx + + mov eax,1 + mov ecx, [edi+lenbits_state] + shl eax,cl + dec eax + mov [esp+0],eax + + mov eax,1 + mov ecx, [edi+distbits_state] + shl eax,cl + dec eax + mov [esp+4],eax + + mov eax, [edi+wsize_state] + mov ecx, [edi+write_state] + mov edx, [edi+window_state] + + mov [esp+52],eax + mov [esp+48],ecx + mov [esp+56],edx + + mov ebp, [edi+hold_state] + mov ebx, [edi+bits_state] +; 321 "inffast.S" + mov esi, [esp+44] + mov ecx, [esp+20] + cmp ecx,esi + ja L_align_long + + add ecx,11 + sub ecx,esi + mov eax,12 + sub eax,ecx + lea edi, [esp+28] + rep movsb + mov ecx,eax + xor eax,eax + rep stosb + lea esi, [esp+28] + mov [esp+20],esi + jmp L_is_aligned + + +L_align_long: + test esi,3 + jz L_is_aligned + xor eax,eax + mov al, [esi] + inc esi + mov ecx,ebx + add ebx,8 + shl eax,cl + or ebp,eax + jmp L_align_long + +L_is_aligned: + mov edi, [esp+60] +; 366 "inffast.S" +L_check_mmx: + cmp dword ptr [inflate_fast_use_mmx],2 + je L_init_mmx + ja L_do_loop + + push eax + push ebx + push ecx + push edx + pushfd + mov eax, [esp] + xor dword ptr [esp],0200000h + + + + + popfd + pushfd + pop edx + xor edx,eax + jz L_dont_use_mmx + xor eax,eax + cpuid + cmp ebx,0756e6547h + jne L_dont_use_mmx + cmp ecx,06c65746eh + jne L_dont_use_mmx + cmp edx,049656e69h + jne L_dont_use_mmx + mov eax,1 + cpuid + shr eax,8 + and eax,15 + cmp eax,6 + jne L_dont_use_mmx + test edx,0800000h + jnz L_use_mmx + jmp L_dont_use_mmx +L_use_mmx: + mov dword ptr [inflate_fast_use_mmx],2 + jmp L_check_mmx_pop +L_dont_use_mmx: + mov dword ptr [inflate_fast_use_mmx],3 +L_check_mmx_pop: + pop edx + pop ecx + pop ebx + pop eax + jmp L_check_mmx +; 426 "inffast.S" +ALIGN 4 +L_do_loop: +; 437 "inffast.S" + cmp bl,15 + ja L_get_length_code + + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + +L_get_length_code: + mov edx, [esp+0] + mov ecx, [esp+8] + and edx,ebp + mov eax, [ecx+edx*4] + +L_dolen: + + + + + + + mov cl,ah + sub bl,ah + shr ebp,cl + + + + + + + test al,al + jnz L_test_for_length_base + + shr eax,16 + stosb + +L_while_test: + + + cmp [esp+16],edi + jbe L_break_loop + + cmp [esp+20],esi + ja L_do_loop + jmp L_break_loop + +L_test_for_length_base: +; 502 "inffast.S" + mov edx,eax + shr edx,16 + mov cl,al + + test al,16 + jz L_test_for_second_level_length + and cl,15 + jz L_save_len + cmp bl,cl + jae L_add_bits_to_len + + mov ch,cl + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + mov cl,ch + +L_add_bits_to_len: + mov eax,1 + shl eax,cl + dec eax + sub bl,cl + and eax,ebp + shr ebp,cl + add edx,eax + +L_save_len: + mov [esp+24],edx + + +L_decode_distance: +; 549 "inffast.S" + cmp bl,15 + ja L_get_distance_code + + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + +L_get_distance_code: + mov edx, [esp+4] + mov ecx, [esp+12] + and edx,ebp + mov eax, [ecx+edx*4] + + +L_dodist: + mov edx,eax + shr edx,16 + mov cl,ah + sub bl,ah + shr ebp,cl +; 584 "inffast.S" + mov cl,al + + test al,16 + jz L_test_for_second_level_dist + and cl,15 + jz L_check_dist_one + cmp bl,cl + jae L_add_bits_to_dist + + mov ch,cl + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + mov cl,ch + +L_add_bits_to_dist: + mov eax,1 + shl eax,cl + dec eax + sub bl,cl + and eax,ebp + shr ebp,cl + add edx,eax + jmp L_check_window + +L_check_window: +; 625 "inffast.S" + mov [esp+44],esi + mov eax,edi + sub eax, [esp+40] + + cmp eax,edx + jb L_clip_window + + mov ecx, [esp+24] + mov esi,edi + sub esi,edx + + sub ecx,3 + mov al, [esi] + mov [edi],al + mov al, [esi+1] + mov dl, [esi+2] + add esi,3 + mov [edi+1],al + mov [edi+2],dl + add edi,3 + rep movsb + + mov esi, [esp+44] + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp edx,1 + jne L_check_window + cmp [esp+40],edi + je L_check_window + + dec edi + mov ecx, [esp+24] + mov al, [edi] + sub ecx,3 + + mov [edi+1],al + mov [edi+2],al + mov [edi+3],al + add edi,4 + rep stosb + + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + + + + + test al,64 + jnz L_test_for_end_of_block + + mov eax,1 + shl eax,cl + dec eax + and eax,ebp + add eax,edx + mov edx, [esp+8] + mov eax, [edx+eax*4] + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + + + + + test al,64 + jnz L_invalid_distance_code + + mov eax,1 + shl eax,cl + dec eax + and eax,ebp + add eax,edx + mov edx, [esp+12] + mov eax, [edx+eax*4] + jmp L_dodist + +ALIGN 4 +L_clip_window: +; 721 "inffast.S" + mov ecx,eax + mov eax, [esp+52] + neg ecx + mov esi, [esp+56] + + cmp eax,edx + jb L_invalid_distance_too_far + + add ecx,edx + cmp dword ptr [esp+48],0 + jne L_wrap_around_window + + sub eax,ecx + add esi,eax +; 749 "inffast.S" + mov eax, [esp+24] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + jmp L_do_copy1 + + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + jmp L_do_copy1 + +L_wrap_around_window: +; 793 "inffast.S" + mov eax, [esp+48] + cmp ecx,eax + jbe L_contiguous_in_window + + add esi, [esp+52] + add esi,eax + sub esi,ecx + sub ecx,eax + + + mov eax, [esp+24] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi, [esp+56] + mov ecx, [esp+48] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + jmp L_do_copy1 + +L_contiguous_in_window: +; 836 "inffast.S" + add esi,eax + sub esi,ecx + + + mov eax, [esp+24] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + +L_do_copy1: +; 862 "inffast.S" + mov ecx,eax + rep movsb + + mov esi, [esp+44] + jmp L_while_test +; 878 "inffast.S" +ALIGN 4 +L_init_mmx: + emms + + + + + + movd mm0,ebp + mov ebp,ebx +; 896 "inffast.S" + movd mm4,dword ptr [esp+0] + movq mm3,mm4 + movd mm5,dword ptr [esp+4] + movq mm2,mm5 + pxor mm1,mm1 + mov ebx, [esp+8] + jmp L_do_loop_mmx + +ALIGN 4 +L_do_loop_mmx: + psrlq mm0,mm1 + + cmp ebp,32 + ja L_get_length_code_mmx + + movd mm6,ebp + movd mm7,dword ptr [esi] + add esi,4 + psllq mm7,mm6 + add ebp,32 + por mm0,mm7 + +L_get_length_code_mmx: + pand mm4,mm0 + movd eax,mm4 + movq mm4,mm3 + mov eax, [ebx+eax*4] + +L_dolen_mmx: + movzx ecx,ah + movd mm1,ecx + sub ebp,ecx + + test al,al + jnz L_test_for_length_base_mmx + + shr eax,16 + stosb + +L_while_test_mmx: + + + cmp [esp+16],edi + jbe L_break_loop + + cmp [esp+20],esi + ja L_do_loop_mmx + jmp L_break_loop + +L_test_for_length_base_mmx: + + mov edx,eax + shr edx,16 + + test al,16 + jz L_test_for_second_level_length_mmx + and eax,15 + jz L_decode_distance_mmx + + psrlq mm0,mm1 + movd mm1,eax + movd ecx,mm0 + sub ebp,eax + and ecx, [inflate_fast_mask+eax*4] + add edx,ecx + +L_decode_distance_mmx: + psrlq mm0,mm1 + + cmp ebp,32 + ja L_get_dist_code_mmx + + movd mm6,ebp + movd mm7,dword ptr [esi] + add esi,4 + psllq mm7,mm6 + add ebp,32 + por mm0,mm7 + +L_get_dist_code_mmx: + mov ebx, [esp+12] + pand mm5,mm0 + movd eax,mm5 + movq mm5,mm2 + mov eax, [ebx+eax*4] + +L_dodist_mmx: + + movzx ecx,ah + mov ebx,eax + shr ebx,16 + sub ebp,ecx + movd mm1,ecx + + test al,16 + jz L_test_for_second_level_dist_mmx + and eax,15 + jz L_check_dist_one_mmx + +L_add_bits_to_dist_mmx: + psrlq mm0,mm1 + movd mm1,eax + movd ecx,mm0 + sub ebp,eax + and ecx, [inflate_fast_mask+eax*4] + add ebx,ecx + +L_check_window_mmx: + mov [esp+44],esi + mov eax,edi + sub eax, [esp+40] + + cmp eax,ebx + jb L_clip_window_mmx + + mov ecx,edx + mov esi,edi + sub esi,ebx + + sub ecx,3 + mov al, [esi] + mov [edi],al + mov al, [esi+1] + mov dl, [esi+2] + add esi,3 + mov [edi+1],al + mov [edi+2],dl + add edi,3 + rep movsb + + mov esi, [esp+44] + mov ebx, [esp+8] + jmp L_while_test_mmx + +ALIGN 4 +L_check_dist_one_mmx: + cmp ebx,1 + jne L_check_window_mmx + cmp [esp+40],edi + je L_check_window_mmx + + dec edi + mov ecx,edx + mov al, [edi] + sub ecx,3 + + mov [edi+1],al + mov [edi+2],al + mov [edi+3],al + add edi,4 + rep stosb + + mov ebx, [esp+8] + jmp L_while_test_mmx + +ALIGN 4 +L_test_for_second_level_length_mmx: + test al,64 + jnz L_test_for_end_of_block + + and eax,15 + psrlq mm0,mm1 + movd ecx,mm0 + and ecx, [inflate_fast_mask+eax*4] + add ecx,edx + mov eax, [ebx+ecx*4] + jmp L_dolen_mmx + +ALIGN 4 +L_test_for_second_level_dist_mmx: + test al,64 + jnz L_invalid_distance_code + + and eax,15 + psrlq mm0,mm1 + movd ecx,mm0 + and ecx, [inflate_fast_mask+eax*4] + mov eax, [esp+12] + add ecx,ebx + mov eax, [eax+ecx*4] + jmp L_dodist_mmx + +ALIGN 4 +L_clip_window_mmx: + + mov ecx,eax + mov eax, [esp+52] + neg ecx + mov esi, [esp+56] + + cmp eax,ebx + jb L_invalid_distance_too_far + + add ecx,ebx + cmp dword ptr [esp+48],0 + jne L_wrap_around_window_mmx + + sub eax,ecx + add esi,eax + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + jmp L_do_copy1_mmx + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + jmp L_do_copy1_mmx + +L_wrap_around_window_mmx: + + mov eax, [esp+48] + cmp ecx,eax + jbe L_contiguous_in_window_mmx + + add esi, [esp+52] + add esi,eax + sub esi,ecx + sub ecx,eax + + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi, [esp+56] + mov ecx, [esp+48] + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + jmp L_do_copy1_mmx + +L_contiguous_in_window_mmx: + + add esi,eax + sub esi,ecx + + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + +L_do_copy1_mmx: + + + mov ecx,edx + rep movsb + + mov esi, [esp+44] + mov ebx, [esp+8] + jmp L_while_test_mmx +; 1174 "inffast.S" +L_invalid_distance_code: + + + + + + mov ecx, invalid_distance_code_msg + mov edx,INFLATE_MODE_BAD + jmp L_update_stream_state + +L_test_for_end_of_block: + + + + + + test al,32 + jz L_invalid_literal_length_code + + mov ecx,0 + mov edx,INFLATE_MODE_TYPE + jmp L_update_stream_state + +L_invalid_literal_length_code: + + + + + + mov ecx, invalid_literal_length_code_msg + mov edx,INFLATE_MODE_BAD + jmp L_update_stream_state + +L_invalid_distance_too_far: + + + + mov esi, [esp+44] + mov ecx, invalid_distance_too_far_msg + mov edx,INFLATE_MODE_BAD + jmp L_update_stream_state + +L_update_stream_state: + + mov eax, [esp+88] + test ecx,ecx + jz L_skip_msg + mov [eax+24],ecx +L_skip_msg: + mov eax, [eax+28] + mov [eax+mode_state],edx + jmp L_break_loop + +ALIGN 4 +L_break_loop: +; 1243 "inffast.S" + cmp dword ptr [inflate_fast_use_mmx],2 + jne L_update_next_in + + + + mov ebx,ebp + +L_update_next_in: +; 1266 "inffast.S" + mov eax, [esp+88] + mov ecx,ebx + mov edx, [eax+28] + shr ecx,3 + sub esi,ecx + shl ecx,3 + sub ebx,ecx + mov [eax+12],edi + mov [edx+bits_state],ebx + mov ecx,ebx + + lea ebx, [esp+28] + cmp [esp+20],ebx + jne L_buf_not_used + + sub esi,ebx + mov ebx, [eax+0] + mov [esp+20],ebx + add esi,ebx + mov ebx, [eax+4] + sub ebx,11 + add [esp+20],ebx + +L_buf_not_used: + mov [eax+0],esi + + mov ebx,1 + shl ebx,cl + dec ebx + + + + + + cmp dword ptr [inflate_fast_use_mmx],2 + jne L_update_hold + + + + psrlq mm0,mm1 + movd ebp,mm0 + + emms + +L_update_hold: + + + + and ebp,ebx + mov [edx+hold_state],ebp + + + + + mov ebx, [esp+20] + cmp ebx,esi + jbe L_last_is_smaller + + sub ebx,esi + add ebx,11 + mov [eax+4],ebx + jmp L_fixup_out +L_last_is_smaller: + sub esi,ebx + neg esi + add esi,11 + mov [eax+4],esi + + + + +L_fixup_out: + + mov ebx, [esp+16] + cmp ebx,edi + jbe L_end_is_smaller + + sub ebx,edi + add ebx,257 + mov [eax+16],ebx + jmp L_done +L_end_is_smaller: + sub edi,ebx + neg edi + add edi,257 + mov [eax+16],edi + + + + + +L_done: + add esp,64 + popfd + pop ebx + pop ebp + pop esi + pop edi + ret +_inflate_fast endp + +_TEXT ends +end diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/inffas32.lst b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/inffas32.lst new file mode 100644 index 00000000..d38b3a6e --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/inffas32.lst @@ -0,0 +1,1224 @@ +Microsoft (R) Macro Assembler Version 10.00.30319.01 04/13/12 13:33:41 +inffas32.asm Page 1 - 1 + + + ;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding + ; * + ; * inffas32.asm is derivated from inffas86.c, with translation of assembly code + ; * + ; * Copyright (C) 1995-2003 Mark Adler + ; * For conditions of distribution and use, see copyright notice in zlib.h + ; * + ; * Copyright (C) 2003 Chris Anderson + ; * Please use the copyright conditions above. + ; * + ; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from + ; * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at + ; * the moment. I have successfully compiled and tested this code with gcc2.96, + ; * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S + ; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX + ; * enabled. I will attempt to merge the MMX code into this version. Newer + ; * versions of this and inffast.S can be found at + ; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ + ; * + ; * 2005 : modification by Gilles Vollant + ; */ + ; For Visual C++ 4.x and higher and ML 6.x and higher + ; ml.exe is in directory \MASM611C of Win95 DDK + ; ml.exe is also distributed in http://www.masm32.com/masmdl.htm + ; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/ + ; + ; + ; compile with command line option + ; ml /coff /Zi /c /Flinffas32.lst inffas32.asm + + ; if you define NO_GZIP (see inflate.h), compile with + ; ml /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm + + + ; zlib122sup is 0 fort zlib 1.2.2.1 and lower + ; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head + ; in inflate_state in inflate.h) + = 00000008 zlib1222sup equ 8 + + + IFDEF GUNZIP + ELSE + IFNDEF NO_GUNZIP + = 0000000B INFLATE_MODE_TYPE equ 11 + = 0000001A INFLATE_MODE_BAD equ 26 + ELSE + ENDIF + ENDIF + + + ; 75 "inffast.S" + ;FILE "inffast.S" + + ;;;GLOBAL _inflate_fast + + ;;;SECTION .text + + + + .586p + .mmx + + name inflate_fast_x86 + .MODEL FLAT + + 00000000 _DATA segment + 00000000 inflate_fast_use_mmx: + 00000000 00000001 dd 1 + + + 00000000 _TEXT segment + + + + ALIGN 4 + 00000000 46 61 73 74 20 db 'Fast decoding Code from Chris Anderson' + 64 65 63 6F 64 + 69 6E 67 20 43 + 6F 64 65 20 66 + 72 6F 6D 20 43 + 68 72 69 73 20 + 41 6E 64 65 72 + 73 6F 6E + 00000026 00 db 0 + + ALIGN 4 + 00000028 invalid_literal_length_code_msg: + 00000028 69 6E 76 61 6C db 'invalid literal/length code' + 69 64 20 6C 69 + 74 65 72 61 6C + 2F 6C 65 6E 67 + 74 68 20 63 6F + 64 65 + 00000043 00 db 0 + + ALIGN 4 + 00000044 invalid_distance_code_msg: + 00000044 69 6E 76 61 6C db 'invalid distance code' + 69 64 20 64 69 + 73 74 61 6E 63 + 65 20 63 6F 64 + 65 + 00000059 00 db 0 + + ALIGN 4 + 0000005C invalid_distance_too_far_msg: + 0000005C 69 6E 76 61 6C db 'invalid distance too far back' + 69 64 20 64 69 + 73 74 61 6E 63 + 65 20 74 6F 6F + 20 66 61 72 20 + 62 61 63 6B + 00000079 00 db 0 + + + ALIGN 4 + 0000007C inflate_fast_mask: + 0000007C 00000000 dd 0 + 00000080 00000001 dd 1 + 00000084 00000003 dd 3 + 00000088 00000007 dd 7 + 0000008C 0000000F dd 15 + 00000090 0000001F dd 31 + 00000094 0000003F dd 63 + 00000098 0000007F dd 127 + 0000009C 000000FF dd 255 + 000000A0 000001FF dd 511 + 000000A4 000003FF dd 1023 + 000000A8 000007FF dd 2047 + 000000AC 00000FFF dd 4095 + 000000B0 00001FFF dd 8191 + 000000B4 00003FFF dd 16383 + 000000B8 00007FFF dd 32767 + 000000BC 0000FFFF dd 65535 + 000000C0 0001FFFF dd 131071 + 000000C4 0003FFFF dd 262143 + 000000C8 0007FFFF dd 524287 + 000000CC 000FFFFF dd 1048575 + 000000D0 001FFFFF dd 2097151 + 000000D4 003FFFFF dd 4194303 + 000000D8 007FFFFF dd 8388607 + 000000DC 00FFFFFF dd 16777215 + 000000E0 01FFFFFF dd 33554431 + 000000E4 03FFFFFF dd 67108863 + 000000E8 07FFFFFF dd 134217727 + 000000EC 0FFFFFFF dd 268435455 + 000000F0 1FFFFFFF dd 536870911 + 000000F4 3FFFFFFF dd 1073741823 + 000000F8 7FFFFFFF dd 2147483647 + 000000FC FFFFFFFF dd 4294967295 + + + = 00000000 mode_state equ 0 ;/* state->mode */ + = 00000028 wsize_state equ (32+zlib1222sup) ;/* state->wsize */ + = 00000030 write_state equ (36+4+zlib1222sup) ;/* state->write */ + = 00000034 window_state equ (40+4+zlib1222sup) ;/* state->window */ + = 00000038 hold_state equ (44+4+zlib1222sup) ;/* state->hold */ + = 0000003C bits_state equ (48+4+zlib1222sup) ;/* state->bits */ + = 0000004C lencode_state equ (64+4+zlib1222sup) ;/* state->lencode */ + = 00000050 distcode_state equ (68+4+zlib1222sup) ;/* state->distcode */ + = 00000054 lenbits_state equ (72+4+zlib1222sup) ;/* state->lenbits */ + = 00000058 distbits_state equ (76+4+zlib1222sup) ;/* state->distbits */ + + + ;;SECTION .text + ; 205 "inffast.S" + ;GLOBAL inflate_fast_use_mmx + + ;SECTION .data + + + ; GLOBAL inflate_fast_use_mmx:object + ;.size inflate_fast_use_mmx, 4 + ; 226 "inffast.S" + ;SECTION .text + + ALIGN 4 + 00000100 _inflate_fast proc near + 00000100 .FPO (16, 4, 0, 0, 1, 0) + 00000100 57 push edi + 00000101 56 push esi + 00000102 55 push ebp + 00000103 53 push ebx + 00000104 9C pushfd + 00000105 83 EC 40 sub esp,64 + 00000108 FC cld + + + + + 00000109 8B 74 24 58 mov esi, [esp+88] + 0000010D 8B 7E 1C mov edi, [esi+28] + + + + + + + + 00000110 8B 56 04 mov edx, [esi+4] + 00000113 8B 06 mov eax, [esi+0] + + 00000115 03 D0 add edx,eax + 00000117 83 EA 0B sub edx,11 + + 0000011A 89 44 24 2C mov [esp+44],eax + 0000011E 89 54 24 14 mov [esp+20],edx + + 00000122 8B 6C 24 5C mov ebp, [esp+92] + 00000126 8B 4E 10 mov ecx, [esi+16] + 00000129 8B 5E 0C mov ebx, [esi+12] + + 0000012C 2B E9 sub ebp,ecx + 0000012E F7 DD neg ebp + 00000130 03 EB add ebp,ebx + + 00000132 81 E9 00000101 sub ecx,257 + 00000138 03 CB add ecx,ebx + + 0000013A 89 5C 24 3C mov [esp+60],ebx + 0000013E 89 6C 24 28 mov [esp+40],ebp + 00000142 89 4C 24 10 mov [esp+16],ecx + ; 285 "inffast.S" + 00000146 8B 47 4C mov eax, [edi+lencode_state] + 00000149 8B 4F 50 mov ecx, [edi+distcode_state] + + 0000014C 89 44 24 08 mov [esp+8],eax + 00000150 89 4C 24 0C mov [esp+12],ecx + + 00000154 B8 00000001 mov eax,1 + 00000159 8B 4F 54 mov ecx, [edi+lenbits_state] + 0000015C D3 E0 shl eax,cl + 0000015E 48 dec eax + 0000015F 89 04 24 mov [esp+0],eax + + 00000162 B8 00000001 mov eax,1 + 00000167 8B 4F 58 mov ecx, [edi+distbits_state] + 0000016A D3 E0 shl eax,cl + 0000016C 48 dec eax + 0000016D 89 44 24 04 mov [esp+4],eax + + 00000171 8B 47 28 mov eax, [edi+wsize_state] + 00000174 8B 4F 30 mov ecx, [edi+write_state] + 00000177 8B 57 34 mov edx, [edi+window_state] + + 0000017A 89 44 24 34 mov [esp+52],eax + 0000017E 89 4C 24 30 mov [esp+48],ecx + 00000182 89 54 24 38 mov [esp+56],edx + + 00000186 8B 6F 38 mov ebp, [edi+hold_state] + 00000189 8B 5F 3C mov ebx, [edi+bits_state] + ; 321 "inffast.S" + 0000018C 8B 74 24 2C mov esi, [esp+44] + 00000190 8B 4C 24 14 mov ecx, [esp+20] + 00000194 3B CE cmp ecx,esi + 00000196 77 22 ja L_align_long + + 00000198 83 C1 0B add ecx,11 + 0000019B 2B CE sub ecx,esi + 0000019D B8 0000000C mov eax,12 + 000001A2 2B C1 sub eax,ecx + 000001A4 8D 7C 24 1C lea edi, [esp+28] + 000001A8 F3/ A4 rep movsb + 000001AA 8B C8 mov ecx,eax + 000001AC 33 C0 xor eax,eax + 000001AE F3/ AA rep stosb + 000001B0 8D 74 24 1C lea esi, [esp+28] + 000001B4 89 74 24 14 mov [esp+20],esi + 000001B8 EB 18 jmp L_is_aligned + + + 000001BA L_align_long: + 000001BA F7 C6 00000003 test esi,3 + 000001C0 74 10 jz L_is_aligned + 000001C2 33 C0 xor eax,eax + 000001C4 8A 06 mov al, [esi] + 000001C6 46 inc esi + 000001C7 8B CB mov ecx,ebx + 000001C9 83 C3 08 add ebx,8 + 000001CC D3 E0 shl eax,cl + 000001CE 0B E8 or ebp,eax + 000001D0 EB E8 jmp L_align_long + + 000001D2 L_is_aligned: + 000001D2 8B 7C 24 3C mov edi, [esp+60] + ; 366 "inffast.S" + 000001D6 L_check_mmx: + 000001D6 83 3D 00000000 R cmp dword ptr [inflate_fast_use_mmx],2 + 02 + 000001DD 0F 84 00000289 je L_init_mmx + 000001E3 77 6B ja L_do_loop + + 000001E5 50 push eax + 000001E6 53 push ebx + 000001E7 51 push ecx + 000001E8 52 push edx + 000001E9 9C pushfd + 000001EA 8B 04 24 mov eax, [esp] + 000001ED 81 34 24 xor dword ptr [esp],0200000h + 00200000 + + + + + 000001F4 9D popfd + 000001F5 9C pushfd + 000001F6 5A pop edx + 000001F7 33 D0 xor edx,eax + 000001F9 74 44 jz L_dont_use_mmx + 000001FB 33 C0 xor eax,eax + 000001FD 0F A2 cpuid + 000001FF 81 FB 756E6547 cmp ebx,0756e6547h + 00000205 75 38 jne L_dont_use_mmx + 00000207 81 F9 6C65746E cmp ecx,06c65746eh + 0000020D 75 30 jne L_dont_use_mmx + 0000020F 81 FA 49656E69 cmp edx,049656e69h + 00000215 75 28 jne L_dont_use_mmx + 00000217 B8 00000001 mov eax,1 + 0000021C 0F A2 cpuid + 0000021E C1 E8 08 shr eax,8 + 00000221 83 E0 0F and eax,15 + 00000224 83 F8 06 cmp eax,6 + 00000227 75 16 jne L_dont_use_mmx + 00000229 F7 C2 00800000 test edx,0800000h + 0000022F 75 02 jnz L_use_mmx + 00000231 EB 0C jmp L_dont_use_mmx + 00000233 L_use_mmx: + 00000233 C7 05 00000000 R mov dword ptr [inflate_fast_use_mmx],2 + 00000002 + 0000023D EB 0A jmp L_check_mmx_pop + 0000023F L_dont_use_mmx: + 0000023F C7 05 00000000 R mov dword ptr [inflate_fast_use_mmx],3 + 00000003 + 00000249 L_check_mmx_pop: + 00000249 5A pop edx + 0000024A 59 pop ecx + 0000024B 5B pop ebx + 0000024C 58 pop eax + 0000024D EB 87 jmp L_check_mmx + ; 426 "inffast.S" + ALIGN 4 + 00000250 L_do_loop: + ; 437 "inffast.S" + 00000250 80 FB 0F cmp bl,15 + 00000253 77 0D ja L_get_length_code + + 00000255 33 C0 xor eax,eax + 00000257 66| AD lodsw + 00000259 8A CB mov cl,bl + 0000025B 80 C3 10 add bl,16 + 0000025E D3 E0 shl eax,cl + 00000260 0B E8 or ebp,eax + + 00000262 L_get_length_code: + 00000262 8B 14 24 mov edx, [esp+0] + 00000265 8B 4C 24 08 mov ecx, [esp+8] + 00000269 23 D5 and edx,ebp + 0000026B 8B 04 91 mov eax, [ecx+edx*4] + + 0000026E L_dolen: + + + + + + + 0000026E 8A CC mov cl,ah + 00000270 2A DC sub bl,ah + 00000272 D3 ED shr ebp,cl + + + + + + + 00000274 84 C0 test al,al + 00000276 75 19 jnz L_test_for_length_base + + 00000278 C1 E8 10 shr eax,16 + 0000027B AA stosb + + 0000027C L_while_test: + + + 0000027C 39 7C 24 10 cmp [esp+16],edi + 00000280 0F 86 00000462 jbe L_break_loop + + 00000286 39 74 24 14 cmp [esp+20],esi + 0000028A 77 C4 ja L_do_loop + 0000028C E9 00000457 jmp L_break_loop + + 00000291 L_test_for_length_base: + ; 502 "inffast.S" + 00000291 8B D0 mov edx,eax + 00000293 C1 EA 10 shr edx,16 + 00000296 8A C8 mov cl,al + + 00000298 A8 10 test al,16 + 0000029A 0F 84 000000F4 jz L_test_for_second_level_length + 000002A0 80 E1 0F and cl,15 + 000002A3 74 25 jz L_save_len + 000002A5 3A D9 cmp bl,cl + 000002A7 73 11 jae L_add_bits_to_len + + 000002A9 8A E9 mov ch,cl + 000002AB 33 C0 xor eax,eax + 000002AD 66| AD lodsw + 000002AF 8A CB mov cl,bl + 000002B1 80 C3 10 add bl,16 + 000002B4 D3 E0 shl eax,cl + 000002B6 0B E8 or ebp,eax + 000002B8 8A CD mov cl,ch + + 000002BA L_add_bits_to_len: + 000002BA B8 00000001 mov eax,1 + 000002BF D3 E0 shl eax,cl + 000002C1 48 dec eax + 000002C2 2A D9 sub bl,cl + 000002C4 23 C5 and eax,ebp + 000002C6 D3 ED shr ebp,cl + 000002C8 03 D0 add edx,eax + + 000002CA L_save_len: + 000002CA 89 54 24 18 mov [esp+24],edx + + + 000002CE L_decode_distance: + ; 549 "inffast.S" + 000002CE 80 FB 0F cmp bl,15 + 000002D1 77 0D ja L_get_distance_code + + 000002D3 33 C0 xor eax,eax + 000002D5 66| AD lodsw + 000002D7 8A CB mov cl,bl + 000002D9 80 C3 10 add bl,16 + 000002DC D3 E0 shl eax,cl + 000002DE 0B E8 or ebp,eax + + 000002E0 L_get_distance_code: + 000002E0 8B 54 24 04 mov edx, [esp+4] + 000002E4 8B 4C 24 0C mov ecx, [esp+12] + 000002E8 23 D5 and edx,ebp + 000002EA 8B 04 91 mov eax, [ecx+edx*4] + + + 000002ED L_dodist: + 000002ED 8B D0 mov edx,eax + 000002EF C1 EA 10 shr edx,16 + 000002F2 8A CC mov cl,ah + 000002F4 2A DC sub bl,ah + 000002F6 D3 ED shr ebp,cl + ; 584 "inffast.S" + 000002F8 8A C8 mov cl,al + + 000002FA A8 10 test al,16 + 000002FC 0F 84 000000B2 jz L_test_for_second_level_dist + 00000302 80 E1 0F and cl,15 + 00000305 74 65 jz L_check_dist_one + 00000307 3A D9 cmp bl,cl + 00000309 73 11 jae L_add_bits_to_dist + + 0000030B 8A E9 mov ch,cl + 0000030D 33 C0 xor eax,eax + 0000030F 66| AD lodsw + 00000311 8A CB mov cl,bl + 00000313 80 C3 10 add bl,16 + 00000316 D3 E0 shl eax,cl + 00000318 0B E8 or ebp,eax + 0000031A 8A CD mov cl,ch + + 0000031C L_add_bits_to_dist: + 0000031C B8 00000001 mov eax,1 + 00000321 D3 E0 shl eax,cl + 00000323 48 dec eax + 00000324 2A D9 sub bl,cl + 00000326 23 C5 and eax,ebp + 00000328 D3 ED shr ebp,cl + 0000032A 03 D0 add edx,eax + 0000032C EB 00 jmp L_check_window + + 0000032E L_check_window: + ; 625 "inffast.S" + 0000032E 89 74 24 2C mov [esp+44],esi + 00000332 8B C7 mov eax,edi + 00000334 2B 44 24 28 sub eax, [esp+40] + + 00000338 3B C2 cmp eax,edx + 0000033A 0F 82 00000094 jb L_clip_window + + 00000340 8B 4C 24 18 mov ecx, [esp+24] + 00000344 8B F7 mov esi,edi + 00000346 2B F2 sub esi,edx + + 00000348 83 E9 03 sub ecx,3 + 0000034B 8A 06 mov al, [esi] + 0000034D 88 07 mov [edi],al + 0000034F 8A 46 01 mov al, [esi+1] + 00000352 8A 56 02 mov dl, [esi+2] + 00000355 83 C6 03 add esi,3 + 00000358 88 47 01 mov [edi+1],al + 0000035B 88 57 02 mov [edi+2],dl + 0000035E 83 C7 03 add edi,3 + 00000361 F3/ A4 rep movsb + + 00000363 8B 74 24 2C mov esi, [esp+44] + 00000367 E9 FFFFFF10 jmp L_while_test + + ALIGN 4 + 0000036C L_check_dist_one: + 0000036C 83 FA 01 cmp edx,1 + 0000036F 75 BD jne L_check_window + 00000371 39 7C 24 28 cmp [esp+40],edi + 00000375 74 B7 je L_check_window + + 00000377 4F dec edi + 00000378 8B 4C 24 18 mov ecx, [esp+24] + 0000037C 8A 07 mov al, [edi] + 0000037E 83 E9 03 sub ecx,3 + + 00000381 88 47 01 mov [edi+1],al + 00000384 88 47 02 mov [edi+2],al + 00000387 88 47 03 mov [edi+3],al + 0000038A 83 C7 04 add edi,4 + 0000038D F3/ AA rep stosb + + 0000038F E9 FFFFFEE8 jmp L_while_test + + ALIGN 4 + 00000394 L_test_for_second_level_length: + + + + + 00000394 A8 40 test al,64 + 00000396 0F 85 0000030E jnz L_test_for_end_of_block + + 0000039C B8 00000001 mov eax,1 + 000003A1 D3 E0 shl eax,cl + 000003A3 48 dec eax + 000003A4 23 C5 and eax,ebp + 000003A6 03 C2 add eax,edx + 000003A8 8B 54 24 08 mov edx, [esp+8] + 000003AC 8B 04 82 mov eax, [edx+eax*4] + 000003AF E9 FFFFFEBA jmp L_dolen + + ALIGN 4 + 000003B4 L_test_for_second_level_dist: + + + + + 000003B4 A8 40 test al,64 + 000003B6 0F 85 000002E2 jnz L_invalid_distance_code + + 000003BC B8 00000001 mov eax,1 + 000003C1 D3 E0 shl eax,cl + 000003C3 48 dec eax + 000003C4 23 C5 and eax,ebp + 000003C6 03 C2 add eax,edx + 000003C8 8B 54 24 0C mov edx, [esp+12] + 000003CC 8B 04 82 mov eax, [edx+eax*4] + 000003CF E9 FFFFFF19 jmp L_dodist + + ALIGN 4 + 000003D4 L_clip_window: + ; 721 "inffast.S" + 000003D4 8B C8 mov ecx,eax + 000003D6 8B 44 24 34 mov eax, [esp+52] + 000003DA F7 D9 neg ecx + 000003DC 8B 74 24 38 mov esi, [esp+56] + + 000003E0 3B C2 cmp eax,edx + 000003E2 0F 82 000002DE jb L_invalid_distance_too_far + + 000003E8 03 CA add ecx,edx + 000003EA 83 7C 24 30 00 cmp dword ptr [esp+48],0 + 000003EF 75 24 jne L_wrap_around_window + + 000003F1 2B C1 sub eax,ecx + 000003F3 03 F0 add esi,eax + ; 749 "inffast.S" + 000003F5 8B 44 24 18 mov eax, [esp+24] + 000003F9 3B C1 cmp eax,ecx + 000003FB 76 60 jbe L_do_copy1 + + 000003FD 2B C1 sub eax,ecx + 000003FF F3/ A4 rep movsb + 00000401 8B F7 mov esi,edi + 00000403 2B F2 sub esi,edx + 00000405 EB 56 jmp L_do_copy1 + + 00000407 3B C1 cmp eax,ecx + 00000409 76 52 jbe L_do_copy1 + + 0000040B 2B C1 sub eax,ecx + 0000040D F3/ A4 rep movsb + 0000040F 8B F7 mov esi,edi + 00000411 2B F2 sub esi,edx + 00000413 EB 48 jmp L_do_copy1 + + 00000415 L_wrap_around_window: + ; 793 "inffast.S" + 00000415 8B 44 24 30 mov eax, [esp+48] + 00000419 3B C8 cmp ecx,eax + 0000041B 76 2C jbe L_contiguous_in_window + + 0000041D 03 74 24 34 add esi, [esp+52] + 00000421 03 F0 add esi,eax + 00000423 2B F1 sub esi,ecx + 00000425 2B C8 sub ecx,eax + + + 00000427 8B 44 24 18 mov eax, [esp+24] + 0000042B 3B C1 cmp eax,ecx + 0000042D 76 2E jbe L_do_copy1 + + 0000042F 2B C1 sub eax,ecx + 00000431 F3/ A4 rep movsb + 00000433 8B 74 24 38 mov esi, [esp+56] + 00000437 8B 4C 24 30 mov ecx, [esp+48] + 0000043B 3B C1 cmp eax,ecx + 0000043D 76 1E jbe L_do_copy1 + + 0000043F 2B C1 sub eax,ecx + 00000441 F3/ A4 rep movsb + 00000443 8B F7 mov esi,edi + 00000445 2B F2 sub esi,edx + 00000447 EB 14 jmp L_do_copy1 + + 00000449 L_contiguous_in_window: + ; 836 "inffast.S" + 00000449 03 F0 add esi,eax + 0000044B 2B F1 sub esi,ecx + + + 0000044D 8B 44 24 18 mov eax, [esp+24] + 00000451 3B C1 cmp eax,ecx + 00000453 76 08 jbe L_do_copy1 + + 00000455 2B C1 sub eax,ecx + 00000457 F3/ A4 rep movsb + 00000459 8B F7 mov esi,edi + 0000045B 2B F2 sub esi,edx + + 0000045D L_do_copy1: + ; 862 "inffast.S" + 0000045D 8B C8 mov ecx,eax + 0000045F F3/ A4 rep movsb + + 00000461 8B 74 24 2C mov esi, [esp+44] + 00000465 E9 FFFFFE12 jmp L_while_test + ; 878 "inffast.S" + ALIGN 4 + 0000046C L_init_mmx: + 0000046C 0F 77 emms + + + + + + 0000046E 0F 6E C5 movd mm0,ebp + 00000471 8B EB mov ebp,ebx + ; 896 "inffast.S" + 00000473 0F 6E 24 24 movd mm4,dword ptr [esp+0] + 00000477 0F 7F E3 movq mm3,mm4 + 0000047A 0F 6E 6C 24 04 movd mm5,dword ptr [esp+4] + 0000047F 0F 7F EA movq mm2,mm5 + 00000482 0F EF C9 pxor mm1,mm1 + 00000485 8B 5C 24 08 mov ebx, [esp+8] + 00000489 EB 01 jmp L_do_loop_mmx + + ALIGN 4 + 0000048C L_do_loop_mmx: + 0000048C 0F D3 C1 psrlq mm0,mm1 + + 0000048F 83 FD 20 cmp ebp,32 + 00000492 77 12 ja L_get_length_code_mmx + + 00000494 0F 6E F5 movd mm6,ebp + 00000497 0F 6E 3E movd mm7,dword ptr [esi] + 0000049A 83 C6 04 add esi,4 + 0000049D 0F F3 FE psllq mm7,mm6 + 000004A0 83 C5 20 add ebp,32 + 000004A3 0F EB C7 por mm0,mm7 + + 000004A6 L_get_length_code_mmx: + 000004A6 0F DB E0 pand mm4,mm0 + 000004A9 0F 7E E0 movd eax,mm4 + 000004AC 0F 7F DC movq mm4,mm3 + 000004AF 8B 04 83 mov eax, [ebx+eax*4] + + 000004B2 L_dolen_mmx: + 000004B2 0F B6 CC movzx ecx,ah + 000004B5 0F 6E C9 movd mm1,ecx + 000004B8 2B E9 sub ebp,ecx + + 000004BA 84 C0 test al,al + 000004BC 75 19 jnz L_test_for_length_base_mmx + + 000004BE C1 E8 10 shr eax,16 + 000004C1 AA stosb + + 000004C2 L_while_test_mmx: + + + 000004C2 39 7C 24 10 cmp [esp+16],edi + 000004C6 0F 86 0000021C jbe L_break_loop + + 000004CC 39 74 24 14 cmp [esp+20],esi + 000004D0 77 BA ja L_do_loop_mmx + 000004D2 E9 00000211 jmp L_break_loop + + 000004D7 L_test_for_length_base_mmx: + + 000004D7 8B D0 mov edx,eax + 000004D9 C1 EA 10 shr edx,16 + + 000004DC A8 10 test al,16 + 000004DE 0F 84 000000E0 jz L_test_for_second_level_length_mmx + 000004E4 83 E0 0F and eax,15 + 000004E7 74 14 jz L_decode_distance_mmx + + 000004E9 0F D3 C1 psrlq mm0,mm1 + 000004EC 0F 6E C8 movd mm1,eax + 000004EF 0F 7E C1 movd ecx,mm0 + 000004F2 2B E8 sub ebp,eax + 000004F4 23 0C 85 and ecx, [inflate_fast_mask+eax*4] + 0000007C R + 000004FB 03 D1 add edx,ecx + + 000004FD L_decode_distance_mmx: + 000004FD 0F D3 C1 psrlq mm0,mm1 + + 00000500 83 FD 20 cmp ebp,32 + 00000503 77 12 ja L_get_dist_code_mmx + + 00000505 0F 6E F5 movd mm6,ebp + 00000508 0F 6E 3E movd mm7,dword ptr [esi] + 0000050B 83 C6 04 add esi,4 + 0000050E 0F F3 FE psllq mm7,mm6 + 00000511 83 C5 20 add ebp,32 + 00000514 0F EB C7 por mm0,mm7 + + 00000517 L_get_dist_code_mmx: + 00000517 8B 5C 24 0C mov ebx, [esp+12] + 0000051B 0F DB E8 pand mm5,mm0 + 0000051E 0F 7E E8 movd eax,mm5 + 00000521 0F 7F D5 movq mm5,mm2 + 00000524 8B 04 83 mov eax, [ebx+eax*4] + + 00000527 L_dodist_mmx: + + 00000527 0F B6 CC movzx ecx,ah + 0000052A 8B D8 mov ebx,eax + 0000052C C1 EB 10 shr ebx,16 + 0000052F 2B E9 sub ebp,ecx + 00000531 0F 6E C9 movd mm1,ecx + + 00000534 A8 10 test al,16 + 00000536 0F 84 000000AC jz L_test_for_second_level_dist_mmx + 0000053C 83 E0 0F and eax,15 + 0000053F 74 57 jz L_check_dist_one_mmx + + 00000541 L_add_bits_to_dist_mmx: + 00000541 0F D3 C1 psrlq mm0,mm1 + 00000544 0F 6E C8 movd mm1,eax + 00000547 0F 7E C1 movd ecx,mm0 + 0000054A 2B E8 sub ebp,eax + 0000054C 23 0C 85 and ecx, [inflate_fast_mask+eax*4] + 0000007C R + 00000553 03 D9 add ebx,ecx + + 00000555 L_check_window_mmx: + 00000555 89 74 24 2C mov [esp+44],esi + 00000559 8B C7 mov eax,edi + 0000055B 2B 44 24 28 sub eax, [esp+40] + + 0000055F 3B C3 cmp eax,ebx + 00000561 0F 82 000000A9 jb L_clip_window_mmx + + 00000567 8B CA mov ecx,edx + 00000569 8B F7 mov esi,edi + 0000056B 2B F3 sub esi,ebx + + 0000056D 83 E9 03 sub ecx,3 + 00000570 8A 06 mov al, [esi] + 00000572 88 07 mov [edi],al + 00000574 8A 46 01 mov al, [esi+1] + 00000577 8A 56 02 mov dl, [esi+2] + 0000057A 83 C6 03 add esi,3 + 0000057D 88 47 01 mov [edi+1],al + 00000580 88 57 02 mov [edi+2],dl + 00000583 83 C7 03 add edi,3 + 00000586 F3/ A4 rep movsb + + 00000588 8B 74 24 2C mov esi, [esp+44] + 0000058C 8B 5C 24 08 mov ebx, [esp+8] + 00000590 E9 FFFFFF2D jmp L_while_test_mmx + + ALIGN 4 + 00000598 L_check_dist_one_mmx: + 00000598 83 FB 01 cmp ebx,1 + 0000059B 75 B8 jne L_check_window_mmx + 0000059D 39 7C 24 28 cmp [esp+40],edi + 000005A1 74 B2 je L_check_window_mmx + + 000005A3 4F dec edi + 000005A4 8B CA mov ecx,edx + 000005A6 8A 07 mov al, [edi] + 000005A8 83 E9 03 sub ecx,3 + + 000005AB 88 47 01 mov [edi+1],al + 000005AE 88 47 02 mov [edi+2],al + 000005B1 88 47 03 mov [edi+3],al + 000005B4 83 C7 04 add edi,4 + 000005B7 F3/ AA rep stosb + + 000005B9 8B 5C 24 08 mov ebx, [esp+8] + 000005BD E9 FFFFFF00 jmp L_while_test_mmx + + ALIGN 4 + 000005C4 L_test_for_second_level_length_mmx: + 000005C4 A8 40 test al,64 + 000005C6 0F 85 000000DE jnz L_test_for_end_of_block + + 000005CC 83 E0 0F and eax,15 + 000005CF 0F D3 C1 psrlq mm0,mm1 + 000005D2 0F 7E C1 movd ecx,mm0 + 000005D5 23 0C 85 and ecx, [inflate_fast_mask+eax*4] + 0000007C R + 000005DC 03 CA add ecx,edx + 000005DE 8B 04 8B mov eax, [ebx+ecx*4] + 000005E1 E9 FFFFFECC jmp L_dolen_mmx + + ALIGN 4 + 000005E8 L_test_for_second_level_dist_mmx: + 000005E8 A8 40 test al,64 + 000005EA 0F 85 000000AE jnz L_invalid_distance_code + + 000005F0 83 E0 0F and eax,15 + 000005F3 0F D3 C1 psrlq mm0,mm1 + 000005F6 0F 7E C1 movd ecx,mm0 + 000005F9 23 0C 85 and ecx, [inflate_fast_mask+eax*4] + 0000007C R + 00000600 8B 44 24 0C mov eax, [esp+12] + 00000604 03 CB add ecx,ebx + 00000606 8B 04 88 mov eax, [eax+ecx*4] + 00000609 E9 FFFFFF19 jmp L_dodist_mmx + + ALIGN 4 + 00000610 L_clip_window_mmx: + + 00000610 8B C8 mov ecx,eax + 00000612 8B 44 24 34 mov eax, [esp+52] + 00000616 F7 D9 neg ecx + 00000618 8B 74 24 38 mov esi, [esp+56] + + 0000061C 3B C3 cmp eax,ebx + 0000061E 0F 82 000000A2 jb L_invalid_distance_too_far + + 00000624 03 CB add ecx,ebx + 00000626 83 7C 24 30 00 cmp dword ptr [esp+48],0 + 0000062B 75 20 jne L_wrap_around_window_mmx + + 0000062D 2B C1 sub eax,ecx + 0000062F 03 F0 add esi,eax + + 00000631 3B D1 cmp edx,ecx + 00000633 76 58 jbe L_do_copy1_mmx + + 00000635 2B D1 sub edx,ecx + 00000637 F3/ A4 rep movsb + 00000639 8B F7 mov esi,edi + 0000063B 2B F3 sub esi,ebx + 0000063D EB 4E jmp L_do_copy1_mmx + + 0000063F 3B D1 cmp edx,ecx + 00000641 76 4A jbe L_do_copy1_mmx + + 00000643 2B D1 sub edx,ecx + 00000645 F3/ A4 rep movsb + 00000647 8B F7 mov esi,edi + 00000649 2B F3 sub esi,ebx + 0000064B EB 40 jmp L_do_copy1_mmx + + 0000064D L_wrap_around_window_mmx: + + 0000064D 8B 44 24 30 mov eax, [esp+48] + 00000651 3B C8 cmp ecx,eax + 00000653 76 28 jbe L_contiguous_in_window_mmx + + 00000655 03 74 24 34 add esi, [esp+52] + 00000659 03 F0 add esi,eax + 0000065B 2B F1 sub esi,ecx + 0000065D 2B C8 sub ecx,eax + + + 0000065F 3B D1 cmp edx,ecx + 00000661 76 2A jbe L_do_copy1_mmx + + 00000663 2B D1 sub edx,ecx + 00000665 F3/ A4 rep movsb + 00000667 8B 74 24 38 mov esi, [esp+56] + 0000066B 8B 4C 24 30 mov ecx, [esp+48] + 0000066F 3B D1 cmp edx,ecx + 00000671 76 1A jbe L_do_copy1_mmx + + 00000673 2B D1 sub edx,ecx + 00000675 F3/ A4 rep movsb + 00000677 8B F7 mov esi,edi + 00000679 2B F3 sub esi,ebx + 0000067B EB 10 jmp L_do_copy1_mmx + + 0000067D L_contiguous_in_window_mmx: + + 0000067D 03 F0 add esi,eax + 0000067F 2B F1 sub esi,ecx + + + 00000681 3B D1 cmp edx,ecx + 00000683 76 08 jbe L_do_copy1_mmx + + 00000685 2B D1 sub edx,ecx + 00000687 F3/ A4 rep movsb + 00000689 8B F7 mov esi,edi + 0000068B 2B F3 sub esi,ebx + + 0000068D L_do_copy1_mmx: + + + 0000068D 8B CA mov ecx,edx + 0000068F F3/ A4 rep movsb + + 00000691 8B 74 24 2C mov esi, [esp+44] + 00000695 8B 5C 24 08 mov ebx, [esp+8] + 00000699 E9 FFFFFE24 jmp L_while_test_mmx + ; 1174 "inffast.S" + 0000069E L_invalid_distance_code: + + + + + + 0000069E B9 00000044 R mov ecx, invalid_distance_code_msg + 000006A3 BA 0000001A mov edx,INFLATE_MODE_BAD + 000006A8 EB 2C jmp L_update_stream_state + + 000006AA L_test_for_end_of_block: + + + + + + 000006AA A8 20 test al,32 + 000006AC 74 0C jz L_invalid_literal_length_code + + 000006AE B9 00000000 mov ecx,0 + 000006B3 BA 0000000B mov edx,INFLATE_MODE_TYPE + 000006B8 EB 1C jmp L_update_stream_state + + 000006BA L_invalid_literal_length_code: + + + + + + 000006BA B9 00000028 R mov ecx, invalid_literal_length_code_msg + 000006BF BA 0000001A mov edx,INFLATE_MODE_BAD + 000006C4 EB 10 jmp L_update_stream_state + + 000006C6 L_invalid_distance_too_far: + + + + 000006C6 8B 74 24 2C mov esi, [esp+44] + 000006CA B9 0000005C R mov ecx, invalid_distance_too_far_msg + 000006CF BA 0000001A mov edx,INFLATE_MODE_BAD + 000006D4 EB 00 jmp L_update_stream_state + + 000006D6 L_update_stream_state: + + 000006D6 8B 44 24 58 mov eax, [esp+88] + 000006DA 85 C9 test ecx,ecx + 000006DC 74 03 jz L_skip_msg + 000006DE 89 48 18 mov [eax+24],ecx + 000006E1 L_skip_msg: + 000006E1 8B 40 1C mov eax, [eax+28] + 000006E4 89 10 mov [eax+mode_state],edx + 000006E6 EB 00 jmp L_break_loop + + ALIGN 4 + 000006E8 L_break_loop: + ; 1243 "inffast.S" + 000006E8 83 3D 00000000 R cmp dword ptr [inflate_fast_use_mmx],2 + 02 + 000006EF 75 02 jne L_update_next_in + + + + 000006F1 8B DD mov ebx,ebp + + 000006F3 L_update_next_in: + ; 1266 "inffast.S" + 000006F3 8B 44 24 58 mov eax, [esp+88] + 000006F7 8B CB mov ecx,ebx + 000006F9 8B 50 1C mov edx, [eax+28] + 000006FC C1 E9 03 shr ecx,3 + 000006FF 2B F1 sub esi,ecx + 00000701 C1 E1 03 shl ecx,3 + 00000704 2B D9 sub ebx,ecx + 00000706 89 78 0C mov [eax+12],edi + 00000709 89 5A 3C mov [edx+bits_state],ebx + 0000070C 8B CB mov ecx,ebx + + 0000070E 8D 5C 24 1C lea ebx, [esp+28] + 00000712 39 5C 24 14 cmp [esp+20],ebx + 00000716 75 14 jne L_buf_not_used + + 00000718 2B F3 sub esi,ebx + 0000071A 8B 18 mov ebx, [eax+0] + 0000071C 89 5C 24 14 mov [esp+20],ebx + 00000720 03 F3 add esi,ebx + 00000722 8B 58 04 mov ebx, [eax+4] + 00000725 83 EB 0B sub ebx,11 + 00000728 01 5C 24 14 add [esp+20],ebx + + 0000072C L_buf_not_used: + 0000072C 89 30 mov [eax+0],esi + + 0000072E BB 00000001 mov ebx,1 + 00000733 D3 E3 shl ebx,cl + 00000735 4B dec ebx + + + + + + 00000736 83 3D 00000000 R cmp dword ptr [inflate_fast_use_mmx],2 + 02 + 0000073D 75 08 jne L_update_hold + + + + 0000073F 0F D3 C1 psrlq mm0,mm1 + 00000742 0F 7E C5 movd ebp,mm0 + + 00000745 0F 77 emms + + 00000747 L_update_hold: + + + + 00000747 23 EB and ebp,ebx + 00000749 89 6A 38 mov [edx+hold_state],ebp + + + + + 0000074C 8B 5C 24 14 mov ebx, [esp+20] + 00000750 3B DE cmp ebx,esi + 00000752 76 0A jbe L_last_is_smaller + + 00000754 2B DE sub ebx,esi + 00000756 83 C3 0B add ebx,11 + 00000759 89 58 04 mov [eax+4],ebx + 0000075C EB 0A jmp L_fixup_out + 0000075E L_last_is_smaller: + 0000075E 2B F3 sub esi,ebx + 00000760 F7 DE neg esi + 00000762 83 C6 0B add esi,11 + 00000765 89 70 04 mov [eax+4],esi + + + + + 00000768 L_fixup_out: + + 00000768 8B 5C 24 10 mov ebx, [esp+16] + 0000076C 3B DF cmp ebx,edi + 0000076E 76 0D jbe L_end_is_smaller + + 00000770 2B DF sub ebx,edi + 00000772 81 C3 00000101 add ebx,257 + 00000778 89 58 10 mov [eax+16],ebx + 0000077B EB 0D jmp L_done + 0000077D L_end_is_smaller: + 0000077D 2B FB sub edi,ebx + 0000077F F7 DF neg edi + 00000781 81 C7 00000101 add edi,257 + 00000787 89 78 10 mov [eax+16],edi + + + + + + 0000078A L_done: + 0000078A 83 C4 40 add esp,64 + 0000078D 9D popfd + 0000078E 5B pop ebx + 0000078F 5D pop ebp + 00000790 5E pop esi + 00000791 5F pop edi + 00000792 C3 ret + 00000793 _inflate_fast endp + + 00000004 _TEXT ends + end + Microsoft (R) Macro Assembler Version 10.00.30319.01 04/13/12 13:33:41 +inffas32.asm Symbols 2 - 1 + + + + +Segments and Groups: + + N a m e Size Length Align Combine Class + +FLAT . . . . . . . . . . . . . . GROUP +_DATA . . . . . . . . . . . . . 32 Bit 00000004 Para Public 'DATA' +_TEXT . . . . . . . . . . . . . 32 Bit 00000793 Para Public 'CODE' + + +Procedures, parameters, and locals: + + N a m e Type Value Attr + +_inflate_fast . . . . . . . . . P Near 00000100 _TEXT Length= 00000693 Public + L_align_long . . . . . . . . . L Near 000001BA _TEXT + L_is_aligned . . . . . . . . . L Near 000001D2 _TEXT + L_check_mmx . . . . . . . . . L Near 000001D6 _TEXT + L_use_mmx . . . . . . . . . . L Near 00000233 _TEXT + L_dont_use_mmx . . . . . . . . L Near 0000023F _TEXT + L_check_mmx_pop . . . . . . . L Near 00000249 _TEXT + L_do_loop . . . . . . . . . . L Near 00000250 _TEXT + L_get_length_code . . . . . . L Near 00000262 _TEXT + L_dolen . . . . . . . . . . . L Near 0000026E _TEXT + L_while_test . . . . . . . . . L Near 0000027C _TEXT + L_test_for_length_base . . . . L Near 00000291 _TEXT + L_add_bits_to_len . . . . . . L Near 000002BA _TEXT + L_save_len . . . . . . . . . . L Near 000002CA _TEXT + L_decode_distance . . . . . . L Near 000002CE _TEXT + L_get_distance_code . . . . . L Near 000002E0 _TEXT + L_dodist . . . . . . . . . . . L Near 000002ED _TEXT + L_add_bits_to_dist . . . . . . L Near 0000031C _TEXT + L_check_window . . . . . . . . L Near 0000032E _TEXT + L_check_dist_one . . . . . . . L Near 0000036C _TEXT + L_test_for_second_level_length . L Near 00000394 _TEXT + L_test_for_second_level_dist . L Near 000003B4 _TEXT + L_clip_window . . . . . . . . L Near 000003D4 _TEXT + L_wrap_around_window . . . . . L Near 00000415 _TEXT + L_contiguous_in_window . . . . L Near 00000449 _TEXT + L_do_copy1 . . . . . . . . . . L Near 0000045D _TEXT + L_init_mmx . . . . . . . . . . L Near 0000046C _TEXT + L_do_loop_mmx . . . . . . . . L Near 0000048C _TEXT + L_get_length_code_mmx . . . . L Near 000004A6 _TEXT + L_dolen_mmx . . . . . . . . . L Near 000004B2 _TEXT + L_while_test_mmx . . . . . . . L Near 000004C2 _TEXT + L_test_for_length_base_mmx . . L Near 000004D7 _TEXT + L_decode_distance_mmx . . . . L Near 000004FD _TEXT + L_get_dist_code_mmx . . . . . L Near 00000517 _TEXT + L_dodist_mmx . . . . . . . . . L Near 00000527 _TEXT + L_add_bits_to_dist_mmx . . . . L Near 00000541 _TEXT + L_check_window_mmx . . . . . . L Near 00000555 _TEXT + L_check_dist_one_mmx . . . . . L Near 00000598 _TEXT + L_test_for_second_level_length_mmx . L Near 000005C4 _TEXT + L_test_for_second_level_dist_mmx . L Near 000005E8 _TEXT + L_clip_window_mmx . . . . . . L Near 00000610 _TEXT + L_wrap_around_window_mmx . . . L Near 0000064D _TEXT + L_contiguous_in_window_mmx . . L Near 0000067D _TEXT + L_do_copy1_mmx . . . . . . . . L Near 0000068D _TEXT + L_invalid_distance_code . . . L Near 0000069E _TEXT + L_test_for_end_of_block . . . L Near 000006AA _TEXT + L_invalid_literal_length_code L Near 000006BA _TEXT + L_invalid_distance_too_far . . L Near 000006C6 _TEXT + L_update_stream_state . . . . L Near 000006D6 _TEXT + L_skip_msg . . . . . . . . . . L Near 000006E1 _TEXT + L_break_loop . . . . . . . . . L Near 000006E8 _TEXT + L_update_next_in . . . . . . . L Near 000006F3 _TEXT + L_buf_not_used . . . . . . . . L Near 0000072C _TEXT + L_update_hold . . . . . . . . L Near 00000747 _TEXT + L_last_is_smaller . . . . . . L Near 0000075E _TEXT + L_fixup_out . . . . . . . . . L Near 00000768 _TEXT + L_end_is_smaller . . . . . . . L Near 0000077D _TEXT + L_done . . . . . . . . . . . . L Near 0000078A _TEXT + + +Symbols: + + N a m e Type Value Attr + +@CodeSize . . . . . . . . . . . Number 00000000h +@DataSize . . . . . . . . . . . Number 00000000h +@Interface . . . . . . . . . . . Number 00000000h +@Model . . . . . . . . . . . . . Number 00000007h +@code . . . . . . . . . . . . . Text _TEXT +@data . . . . . . . . . . . . . Text FLAT +@fardata? . . . . . . . . . . . Text FLAT +@fardata . . . . . . . . . . . . Text FLAT +@stack . . . . . . . . . . . . . Text FLAT +INFLATE_MODE_BAD . . . . . . . . Number 0000001Ah +INFLATE_MODE_TYPE . . . . . . . Number 0000000Bh +bits_state . . . . . . . . . . . Number 0000003Ch +distbits_state . . . . . . . . . Number 00000058h +distcode_state . . . . . . . . . Number 00000050h +hold_state . . . . . . . . . . . Number 00000038h +inflate_fast_mask . . . . . . . L Near 0000007C _TEXT +inflate_fast_use_mmx . . . . . . L Near 00000000 _DATA +invalid_distance_code_msg . . . L Near 00000044 _TEXT +invalid_distance_too_far_msg . . L Near 0000005C _TEXT +invalid_literal_length_code_msg L Near 00000028 _TEXT +lenbits_state . . . . . . . . . Number 00000054h +lencode_state . . . . . . . . . Number 0000004Ch +mode_state . . . . . . . . . . . Number 00000000h +window_state . . . . . . . . . . Number 00000034h +write_state . . . . . . . . . . Number 00000030h +wsize_state . . . . . . . . . . Number 00000028h +zlib1222sup . . . . . . . . . . Number 00000008h + + 0 Warnings + 0 Errors diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/match686.asm b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/match686.asm new file mode 100644 index 00000000..3b09212f --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/match686.asm @@ -0,0 +1,479 @@ +; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86 +; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; File written by Gilles Vollant, by converting match686.S from Brian Raiter +; for MASM. This is as assembly version of longest_match +; from Jean-loup Gailly in deflate.c +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; For Visual C++ 4.x and higher and ML 6.x and higher +; ml.exe is distributed in +; http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64 +; +; this file contain two implementation of longest_match +; +; this longest_match was written by Brian raiter (1998), optimized for Pentium Pro +; (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom) +; +; for using an assembly version of longest_match, you need define ASMV in project +; +; compile the asm file running +; ml /coff /Zi /c /Flmatch686.lst match686.asm +; and do not include match686.obj in your project +; +; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for +; Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor +; with autoselect (with cpu detection code) +; if you want support the old pentium optimization, you can still use these version +; +; this file is not optimized for old pentium, but it compatible with all x86 32 bits +; processor (starting 80386) +; +; +; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2 + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; /* current match */ + + NbStack equ 76 + cur_match equ dword ptr[esp+NbStack-0] + str_s equ dword ptr[esp+NbStack-4] +; 5 dword on top (ret,ebp,esi,edi,ebx) + adrret equ dword ptr[esp+NbStack-8] + pushebp equ dword ptr[esp+NbStack-12] + pushedi equ dword ptr[esp+NbStack-16] + pushesi equ dword ptr[esp+NbStack-20] + pushebx equ dword ptr[esp+NbStack-24] + + chain_length equ dword ptr [esp+NbStack-28] + limit equ dword ptr [esp+NbStack-32] + best_len equ dword ptr [esp+NbStack-36] + window equ dword ptr [esp+NbStack-40] + prev equ dword ptr [esp+NbStack-44] + scan_start equ word ptr [esp+NbStack-48] + wmask equ dword ptr [esp+NbStack-52] + match_start_ptr equ dword ptr [esp+NbStack-56] + nice_match equ dword ptr [esp+NbStack-60] + scan equ dword ptr [esp+NbStack-64] + + windowlen equ dword ptr [esp+NbStack-68] + match_start equ dword ptr [esp+NbStack-72] + strend equ dword ptr [esp+NbStack-76] + NbStackAdd equ (NbStack-24) + + .386p + + name gvmatch + .MODEL FLAT + + + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + + zlib1222add equ 8 + +; Note : these value are good with a 8 bytes boundary pack structure + dep_chain_length equ 74h+zlib1222add + dep_window equ 30h+zlib1222add + dep_strstart equ 64h+zlib1222add + dep_prev_length equ 70h+zlib1222add + dep_nice_match equ 88h+zlib1222add + dep_w_size equ 24h+zlib1222add + dep_prev equ 38h+zlib1222add + dep_w_mask equ 2ch+zlib1222add + dep_good_match equ 84h+zlib1222add + dep_match_start equ 68h+zlib1222add + dep_lookahead equ 6ch+zlib1222add + + +_TEXT segment + +IFDEF NOUNDERLINE + public longest_match + public match_init +ELSE + public _longest_match + public _match_init +ENDIF + + MAX_MATCH equ 258 + MIN_MATCH equ 3 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1) +MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h) + + +;;; stack frame offsets + +chainlenwmask equ esp + 0 ; high word: current chain len + ; low word: s->wmask +window equ esp + 4 ; local copy of s->window +windowbestlen equ esp + 8 ; s->window + bestlen +scanstart equ esp + 16 ; first two bytes of string +scanend equ esp + 12 ; last two bytes of string +scanalign equ esp + 20 ; dword-misalignment of string +nicematch equ esp + 24 ; a good enough match size +bestlen equ esp + 28 ; size of best match so far +scan equ esp + 32 ; ptr to string wanting match + +LocalVarsSize equ 36 +; saved ebx byte esp + 36 +; saved edi byte esp + 40 +; saved esi byte esp + 44 +; saved ebp byte esp + 48 +; return address byte esp + 52 +deflatestate equ esp + 56 ; the function arguments +curmatch equ esp + 60 + +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +dsWSize equ 36+zlib1222add +dsWMask equ 44+zlib1222add +dsWindow equ 48+zlib1222add +dsPrev equ 56+zlib1222add +dsMatchLen equ 88+zlib1222add +dsPrevMatch equ 92+zlib1222add +dsStrStart equ 100+zlib1222add +dsMatchStart equ 104+zlib1222add +dsLookahead equ 108+zlib1222add +dsPrevLen equ 112+zlib1222add +dsMaxChainLen equ 116+zlib1222add +dsGoodMatch equ 132+zlib1222add +dsNiceMatch equ 136+zlib1222add + + +;;; match686.asm -- Pentium-Pro-optimized version of longest_match() +;;; Written for zlib 1.1.2 +;;; Copyright (C) 1998 Brian Raiter +;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html +;;; +;; +;; This software is provided 'as-is', without any express or implied +;; warranty. In no event will the authors be held liable for any damages +;; arising from the use of this software. +;; +;; Permission is granted to anyone to use this software for any purpose, +;; including commercial applications, and to alter it and redistribute it +;; freely, subject to the following restrictions: +;; +;; 1. The origin of this software must not be misrepresented; you must not +;; claim that you wrote the original software. If you use this software +;; in a product, an acknowledgment in the product documentation would be +;; appreciated but is not required. +;; 2. Altered source versions must be plainly marked as such, and must not be +;; misrepresented as being the original software +;; 3. This notice may not be removed or altered from any source distribution. +;; + +;GLOBAL _longest_match, _match_init + + +;SECTION .text + +;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch) + +;_longest_match: + IFDEF NOUNDERLINE + longest_match proc near + ELSE + _longest_match proc near + ENDIF +.FPO (9, 4, 0, 0, 1, 0) + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + push ebp + push edi + push esi + push ebx + sub esp, LocalVarsSize + +;;; Retrieve the function arguments. ecx will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + + mov edx, [deflatestate] + mov ecx, [curmatch] + +;;; uInt wmask = s->w_mask; +;;; unsigned chain_length = s->max_chain_length; +;;; if (s->prev_length >= s->good_match) { +;;; chain_length >>= 2; +;;; } + + mov eax, [edx + dsPrevLen] + mov ebx, [edx + dsGoodMatch] + cmp eax, ebx + mov eax, [edx + dsWMask] + mov ebx, [edx + dsMaxChainLen] + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +;;; chainlen is decremented once beforehand so that the function can +;;; use the sign flag instead of the zero flag for the exit test. +;;; It is then shifted into the high word, to make room for the wmask +;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + mov [chainlenwmask], ebx + +;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + mov eax, [edx + dsNiceMatch] + mov ebx, [edx + dsLookahead] + cmp ebx, eax + jl LookaheadLess + mov ebx, eax +LookaheadLess: mov [nicematch], ebx + +;;; register Bytef *scan = s->window + s->strstart; + + mov esi, [edx + dsWindow] + mov [window], esi + mov ebp, [edx + dsStrStart] + lea edi, [esi + ebp] + mov [scan], edi + +;;; Determine how many bytes the scan ptr is off from being +;;; dword-aligned. + + mov eax, edi + neg eax + and eax, 3 + mov [scanalign], eax + +;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +;;; s->strstart - (IPos)MAX_DIST(s) : NIL; + + mov eax, [edx + dsWSize] + sub eax, MIN_LOOKAHEAD + sub ebp, eax + jg LimitPositive + xor ebp, ebp +LimitPositive: + +;;; int best_len = s->prev_length; + + mov eax, [edx + dsPrevLen] + mov [bestlen], eax + +;;; Store the sum of s->window + best_len in esi locally, and in esi. + + add esi, eax + mov [windowbestlen], esi + +;;; register ush scan_start = *(ushf*)scan; +;;; register ush scan_end = *(ushf*)(scan+best_len-1); +;;; Posf *prev = s->prev; + + movzx ebx, word ptr [edi] + mov [scanstart], ebx + movzx ebx, word ptr [edi + eax - 1] + mov [scanend], ebx + mov edi, [edx + dsPrev] + +;;; Jump into the main loop. + + mov edx, [chainlenwmask] + jmp short LoopEntry + +align 4 + +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; ecx = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit + +LookupLoop: + and ecx, edx + movzx ecx, word ptr [edi + ecx*2] + cmp ecx, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow +LoopEntry: movzx eax, word ptr [esi + ecx - 1] + cmp eax, ebx + jnz LookupLoop + mov eax, [window] + movzx eax, word ptr [eax + ecx] + cmp eax, [scanstart] + jnz LookupLoop + +;;; Store the current value of chainlen. + + mov [chainlenwmask], edx + +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). + + mov esi, [window] + mov edi, [scan] + add esi, ecx + mov eax, [scanalign] + mov edx, 0fffffef8h; -(MAX_MATCH_8) + lea edi, [edi + eax + 0108h] ;MAX_MATCH_8] + lea esi, [esi + eax + 0108h] ;MAX_MATCH_8] + +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust edx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (esi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. + +LoopCmps: + mov eax, [esi + edx] + xor eax, [edi + edx] + jnz LeaveLoopCmps + mov eax, [esi + edx + 4] + xor eax, [edi + edx + 4] + jnz LeaveLoopCmps4 + add edx, 8 + jnz LoopCmps + jmp short LenMaximum +LeaveLoopCmps4: add edx, 4 +LeaveLoopCmps: test eax, 0000FFFFh + jnz LenLower + add edx, 2 + shr eax, 16 +LenLower: sub al, 1 + adc edx, 0 + +;;; Calculate the length of the match. If it is longer than MAX_MATCH, +;;; then automatically accept it as the best possible match and leave. + + lea eax, [edi + edx] + mov edi, [scan] + sub eax, edi + cmp eax, MAX_MATCH + jge LenMaximum + +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. + + mov edx, [deflatestate] + mov ebx, [bestlen] + cmp eax, ebx + jg LongerMatch + mov esi, [windowbestlen] + mov edi, [edx + dsPrev] + mov ebx, [scanend] + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); + +LongerMatch: mov ebx, [nicematch] + mov [bestlen], eax + mov [edx + dsMatchStart], ecx + cmp eax, ebx + jge LeaveNow + mov esi, [window] + add esi, eax + mov [windowbestlen], esi + movzx ebx, word ptr [edi + eax - 1] + mov edi, [edx + dsPrev] + mov [scanend], ebx + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; Accept the current string, with the maximum possible length. + +LenMaximum: mov edx, [deflatestate] + mov dword ptr [bestlen], MAX_MATCH + mov [edx + dsMatchStart], ecx + +;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +;;; return s->lookahead; + +LeaveNow: + mov edx, [deflatestate] + mov ebx, [bestlen] + mov eax, [edx + dsLookahead] + cmp ebx, eax + jg LookaheadRet + mov eax, ebx +LookaheadRet: + +;;; Restore the stack and return from whence we came. + + add esp, LocalVarsSize + pop ebx + pop esi + pop edi + pop ebp + + ret +; please don't remove this string ! +; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary! + db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah + + + IFDEF NOUNDERLINE + longest_match endp + ELSE + _longest_match endp + ENDIF + + IFDEF NOUNDERLINE + match_init proc near + ret + match_init endp + ELSE + _match_init proc near + ret + _match_init endp + ENDIF + + +_TEXT ends +end diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/match686.lst b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/match686.lst new file mode 100644 index 00000000..efa90e17 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/match686.lst @@ -0,0 +1,624 @@ +Microsoft (R) Macro Assembler Version 10.00.30319.01 04/13/12 13:33:40 +match686.asm Page 1 - 1 + + + ; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86 + ; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant. + ; File written by Gilles Vollant, by converting match686.S from Brian Raiter + ; for MASM. This is as assembly version of longest_match + ; from Jean-loup Gailly in deflate.c + ; + ; http://www.zlib.net + ; http://www.winimage.com/zLibDll + ; http://www.muppetlabs.com/~breadbox/software/assembly.html + ; + ; For Visual C++ 4.x and higher and ML 6.x and higher + ; ml.exe is distributed in + ; http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64 + ; + ; this file contain two implementation of longest_match + ; + ; this longest_match was written by Brian raiter (1998), optimized for Pentium Pro + ; (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom) + ; + ; for using an assembly version of longest_match, you need define ASMV in project + ; + ; compile the asm file running + ; ml /coff /Zi /c /Flmatch686.lst match686.asm + ; and do not include match686.obj in your project + ; + ; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for + ; Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor + ; with autoselect (with cpu detection code) + ; if you want support the old pentium optimization, you can still use these version + ; + ; this file is not optimized for old pentium, but it compatible with all x86 32 bits + ; processor (starting 80386) + ; + ; + ; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2 + + ;uInt longest_match(s, cur_match) + ; deflate_state *s; + ; IPos cur_match; /* current match */ + + = 0000004C NbStack equ 76 + = dword ptr[esp+NbStack-0] cur_match equ dword ptr[esp+NbStack-0] + = dword ptr[esp+NbStack-4] str_s equ dword ptr[esp+NbStack-4] + ; 5 dword on top (ret,ebp,esi,edi,ebx) + = dword ptr[esp+NbStack-8] adrret equ dword ptr[esp+NbStack-8] + = dword ptr[esp+NbStack-12 pushebp equ dword ptr[esp+NbStack-12] + ] + = dword ptr[esp+NbStack-16 pushedi equ dword ptr[esp+NbStack-16] + ] + = dword ptr[esp+NbStack-20 pushesi equ dword ptr[esp+NbStack-20] + ] + = dword ptr[esp+NbStack-24 pushebx equ dword ptr[esp+NbStack-24] + ] + + = dword ptr [esp+NbStack-2 chain_length equ dword ptr [esp+NbStack-28] + 8] + = dword ptr [esp+NbStack-3 limit equ dword ptr [esp+NbStack-32] + 2] + = dword ptr [esp+NbStack-3 best_len equ dword ptr [esp+NbStack-36] + 6] + = dword ptr [esp+NbStack-4 window equ dword ptr [esp+NbStack-40] + 0] + = dword ptr [esp+NbStack-4 prev equ dword ptr [esp+NbStack-44] + 4] + = word ptr [esp+NbStack-48 scan_start equ word ptr [esp+NbStack-48] + ] + = dword ptr [esp+NbStack-5 wmask equ dword ptr [esp+NbStack-52] + 2] + = dword ptr [esp+NbStack-5 match_start_ptr equ dword ptr [esp+NbStack-56] + 6] + = dword ptr [esp+NbStack-6 nice_match equ dword ptr [esp+NbStack-60] + 0] + = dword ptr [esp+NbStack-6 scan equ dword ptr [esp+NbStack-64] + 4] + + = dword ptr [esp+NbStack-6 windowlen equ dword ptr [esp+NbStack-68] + 8] + = dword ptr [esp+NbStack-7 match_start equ dword ptr [esp+NbStack-72] + 2] + = dword ptr [esp+NbStack-7 strend equ dword ptr [esp+NbStack-76] + 6] + = 00000034 NbStackAdd equ (NbStack-24) + + .386p + + name gvmatch + .MODEL FLAT + + + + ; all the +zlib1222add offsets are due to the addition of fields + ; in zlib in the deflate_state structure since the asm code was first written + ; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). + ; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). + ; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + + = 00000008 zlib1222add equ 8 + + ; Note : these value are good with a 8 bytes boundary pack structure + = 0000007C dep_chain_length equ 74h+zlib1222add + = 00000038 dep_window equ 30h+zlib1222add + = 0000006C dep_strstart equ 64h+zlib1222add + = 00000078 dep_prev_length equ 70h+zlib1222add + = 00000090 dep_nice_match equ 88h+zlib1222add + = 0000002C dep_w_size equ 24h+zlib1222add + = 00000040 dep_prev equ 38h+zlib1222add + = 00000034 dep_w_mask equ 2ch+zlib1222add + = 0000008C dep_good_match equ 84h+zlib1222add + = 00000070 dep_match_start equ 68h+zlib1222add + = 00000074 dep_lookahead equ 6ch+zlib1222add + + + 00000000 _TEXT segment + + IFDEF NOUNDERLINE + ELSE + public _longest_match + public _match_init + ENDIF + + = 00000102 MAX_MATCH equ 258 + = 00000003 MIN_MATCH equ 3 + = 00000106 MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + + + = 00000102 MAX_MATCH equ 258 + = 00000003 MIN_MATCH equ 3 + = 00000106 MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1) + = 00000100 MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h) + + + ;;; stack frame offsets + + = esp + 0 chainlenwmask equ esp + 0 ; high word: current chain len + ; low word: s->wmask + = esp + 4 window equ esp + 4 ; local copy of s->window + = esp + 8 windowbestlen equ esp + 8 ; s->window + bestlen + = esp + 16 scanstart equ esp + 16 ; first two bytes of string + = esp + 12 scanend equ esp + 12 ; last two bytes of string + = esp + 20 scanalign equ esp + 20 ; dword-misalignment of string + = esp + 24 nicematch equ esp + 24 ; a good enough match size + = esp + 28 bestlen equ esp + 28 ; size of best match so far + = esp + 32 scan equ esp + 32 ; ptr to string wanting match + + = 00000024 LocalVarsSize equ 36 + ; saved ebx byte esp + 36 + ; saved edi byte esp + 40 + ; saved esi byte esp + 44 + ; saved ebp byte esp + 48 + ; return address byte esp + 52 + = esp + 56 deflatestate equ esp + 56 ; the function arguments + = esp + 60 curmatch equ esp + 60 + + ;;; Offsets for fields in the deflate_state structure. These numbers + ;;; are calculated from the definition of deflate_state, with the + ;;; assumption that the compiler will dword-align the fields. (Thus, + ;;; changing the definition of deflate_state could easily cause this + ;;; program to crash horribly, without so much as a warning at + ;;; compile time. Sigh.) + + = 0000002C dsWSize equ 36+zlib1222add + = 00000034 dsWMask equ 44+zlib1222add + = 00000038 dsWindow equ 48+zlib1222add + = 00000040 dsPrev equ 56+zlib1222add + = 00000060 dsMatchLen equ 88+zlib1222add + = 00000064 dsPrevMatch equ 92+zlib1222add + = 0000006C dsStrStart equ 100+zlib1222add + = 00000070 dsMatchStart equ 104+zlib1222add + = 00000074 dsLookahead equ 108+zlib1222add + = 00000078 dsPrevLen equ 112+zlib1222add + = 0000007C dsMaxChainLen equ 116+zlib1222add + = 0000008C dsGoodMatch equ 132+zlib1222add + = 00000090 dsNiceMatch equ 136+zlib1222add + + + ;;; match686.asm -- Pentium-Pro-optimized version of longest_match() + ;;; Written for zlib 1.1.2 + ;;; Copyright (C) 1998 Brian Raiter + ;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html + ;;; + ;; + ;; This software is provided 'as-is', without any express or implied + ;; warranty. In no event will the authors be held liable for any damages + ;; arising from the use of this software. + ;; + ;; Permission is granted to anyone to use this software for any purpose, + ;; including commercial applications, and to alter it and redistribute it + ;; freely, subject to the following restrictions: + ;; + ;; 1. The origin of this software must not be misrepresented; you must not + ;; claim that you wrote the original software. If you use this software + ;; in a product, an acknowledgment in the product documentation would be + ;; appreciated but is not required. + ;; 2. Altered source versions must be plainly marked as such, and must not be + ;; misrepresented as being the original software + ;; 3. This notice may not be removed or altered from any source distribution. + ;; + + ;GLOBAL _longest_match, _match_init + + + ;SECTION .text + + ;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch) + + ;_longest_match: + IFDEF NOUNDERLINE + ELSE + 00000000 _longest_match proc near + ENDIF + 00000000 .FPO (9, 4, 0, 0, 1, 0) + + ;;; Save registers that the compiler may be using, and adjust esp to + ;;; make room for our stack frame. + + 00000000 55 push ebp + 00000001 57 push edi + 00000002 56 push esi + 00000003 53 push ebx + 00000004 83 EC 24 sub esp, LocalVarsSize + + ;;; Retrieve the function arguments. ecx will hold cur_match + ;;; throughout the entire function. edx will hold the pointer to the + ;;; deflate_state structure during the function's setup (before + ;;; entering the main loop. + + 00000007 8B 54 24 38 mov edx, [deflatestate] + 0000000B 8B 4C 24 3C mov ecx, [curmatch] + + ;;; uInt wmask = s->w_mask; + ;;; unsigned chain_length = s->max_chain_length; + ;;; if (s->prev_length >= s->good_match) { + ;;; chain_length >>= 2; + ;;; } + + 0000000F 8B 42 78 mov eax, [edx + dsPrevLen] + 00000012 8B 9A 0000008C mov ebx, [edx + dsGoodMatch] + 00000018 3B C3 cmp eax, ebx + 0000001A 8B 42 34 mov eax, [edx + dsWMask] + 0000001D 8B 5A 7C mov ebx, [edx + dsMaxChainLen] + 00000020 7C 03 jl LastMatchGood + 00000022 C1 EB 02 shr ebx, 2 + 00000025 LastMatchGood: + + ;;; chainlen is decremented once beforehand so that the function can + ;;; use the sign flag instead of the zero flag for the exit test. + ;;; It is then shifted into the high word, to make room for the wmask + ;;; value, which it will always accompany. + + 00000025 4B dec ebx + 00000026 C1 E3 10 shl ebx, 16 + 00000029 0B D8 or ebx, eax + 0000002B 89 1C 24 mov [chainlenwmask], ebx + + ;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + 0000002E 8B 82 00000090 mov eax, [edx + dsNiceMatch] + 00000034 8B 5A 74 mov ebx, [edx + dsLookahead] + 00000037 3B D8 cmp ebx, eax + 00000039 7C 02 jl LookaheadLess + 0000003B 8B D8 mov ebx, eax + 0000003D 89 5C 24 18 LookaheadLess: mov [nicematch], ebx + + ;;; register Bytef *scan = s->window + s->strstart; + + 00000041 8B 72 38 mov esi, [edx + dsWindow] + 00000044 89 74 24 04 mov [window], esi + 00000048 8B 6A 6C mov ebp, [edx + dsStrStart] + 0000004B 8D 7C 35 00 lea edi, [esi + ebp] + 0000004F 89 7C 24 20 mov [scan], edi + + ;;; Determine how many bytes the scan ptr is off from being + ;;; dword-aligned. + + 00000053 8B C7 mov eax, edi + 00000055 F7 D8 neg eax + 00000057 83 E0 03 and eax, 3 + 0000005A 89 44 24 14 mov [scanalign], eax + + ;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + ;;; s->strstart - (IPos)MAX_DIST(s) : NIL; + + 0000005E 8B 42 2C mov eax, [edx + dsWSize] + 00000061 2D 00000106 sub eax, MIN_LOOKAHEAD + 00000066 2B E8 sub ebp, eax + 00000068 7F 02 jg LimitPositive + 0000006A 33 ED xor ebp, ebp + 0000006C LimitPositive: + + ;;; int best_len = s->prev_length; + + 0000006C 8B 42 78 mov eax, [edx + dsPrevLen] + 0000006F 89 44 24 1C mov [bestlen], eax + + ;;; Store the sum of s->window + best_len in esi locally, and in esi. + + 00000073 03 F0 add esi, eax + 00000075 89 74 24 08 mov [windowbestlen], esi + + ;;; register ush scan_start = *(ushf*)scan; + ;;; register ush scan_end = *(ushf*)(scan+best_len-1); + ;;; Posf *prev = s->prev; + + 00000079 0F B7 1F movzx ebx, word ptr [edi] + 0000007C 89 5C 24 10 mov [scanstart], ebx + 00000080 0F B7 5C 38 FF movzx ebx, word ptr [edi + eax - 1] + 00000085 89 5C 24 0C mov [scanend], ebx + 00000089 8B 7A 40 mov edi, [edx + dsPrev] + + ;;; Jump into the main loop. + + 0000008C 8B 14 24 mov edx, [chainlenwmask] + 0000008F EB 1D jmp short LoopEntry + + align 4 + + ;;; do { + ;;; match = s->window + cur_match; + ;;; if (*(ushf*)(match+best_len-1) != scan_end || + ;;; *(ushf*)match != scan_start) continue; + ;;; [...] + ;;; } while ((cur_match = prev[cur_match & wmask]) > limit + ;;; && --chain_length != 0); + ;;; + ;;; Here is the inner loop of the function. The function will spend the + ;;; majority of its time in this loop, and majority of that time will + ;;; be spent in the first ten instructions. + ;;; + ;;; Within this loop: + ;;; ebx = scanend + ;;; ecx = curmatch + ;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) + ;;; esi = windowbestlen - i.e., (window + bestlen) + ;;; edi = prev + ;;; ebp = limit + + 00000094 LookupLoop: + 00000094 23 CA and ecx, edx + 00000096 0F B7 0C 4F movzx ecx, word ptr [edi + ecx*2] + 0000009A 3B CD cmp ecx, ebp + 0000009C 0F 86 000000E0 jbe LeaveNow + 000000A2 81 EA 00010000 sub edx, 00010000h + 000000A8 0F 88 000000D4 js LeaveNow + 000000AE 0F B7 44 31 FF LoopEntry: movzx eax, word ptr [esi + ecx - 1] + 000000B3 3B C3 cmp eax, ebx + 000000B5 75 DD jnz LookupLoop + 000000B7 8B 44 24 04 mov eax, [window] + 000000BB 0F B7 04 01 movzx eax, word ptr [eax + ecx] + 000000BF 3B 44 24 10 cmp eax, [scanstart] + 000000C3 75 CF jnz LookupLoop + + ;;; Store the current value of chainlen. + + 000000C5 89 14 24 mov [chainlenwmask], edx + + ;;; Point edi to the string under scrutiny, and esi to the string we + ;;; are hoping to match it up with. In actuality, esi and edi are + ;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is + ;;; initialized to -(MAX_MATCH_8 - scanalign). + + 000000C8 8B 74 24 04 mov esi, [window] + 000000CC 8B 7C 24 20 mov edi, [scan] + 000000D0 03 F1 add esi, ecx + 000000D2 8B 44 24 14 mov eax, [scanalign] + 000000D6 BA FFFFFEF8 mov edx, 0fffffef8h; -(MAX_MATCH_8) + 000000DB 8D BC 38 lea edi, [edi + eax + 0108h] ;MAX_MATCH_8] + 00000108 + 000000E2 8D B4 30 lea esi, [esi + eax + 0108h] ;MAX_MATCH_8] + 00000108 + + ;;; Test the strings for equality, 8 bytes at a time. At the end, + ;;; adjust edx so that it is offset to the exact byte that mismatched. + ;;; + ;;; We already know at this point that the first three bytes of the + ;;; strings match each other, and they can be safely passed over before + ;;; starting the compare loop. So what this code does is skip over 0-3 + ;;; bytes, as much as necessary in order to dword-align the edi + ;;; pointer. (esi will still be misaligned three times out of four.) + ;;; + ;;; It should be confessed that this loop usually does not represent + ;;; much of the total running time. Replacing it with a more + ;;; straightforward "rep cmpsb" would not drastically degrade + ;;; performance. + + 000000E9 LoopCmps: + 000000E9 8B 04 32 mov eax, [esi + edx] + 000000EC 33 04 3A xor eax, [edi + edx] + 000000EF 75 14 jnz LeaveLoopCmps + 000000F1 8B 44 32 04 mov eax, [esi + edx + 4] + 000000F5 33 44 3A 04 xor eax, [edi + edx + 4] + 000000F9 75 07 jnz LeaveLoopCmps4 + 000000FB 83 C2 08 add edx, 8 + 000000FE 75 E9 jnz LoopCmps + 00000100 EB 71 jmp short LenMaximum + 00000102 83 C2 04 LeaveLoopCmps4: add edx, 4 + 00000105 A9 0000FFFF LeaveLoopCmps: test eax, 0000FFFFh + 0000010A 75 06 jnz LenLower + 0000010C 83 C2 02 add edx, 2 + 0000010F C1 E8 10 shr eax, 16 + 00000112 2C 01 LenLower: sub al, 1 + 00000114 83 D2 00 adc edx, 0 + + ;;; Calculate the length of the match. If it is longer than MAX_MATCH, + ;;; then automatically accept it as the best possible match and leave. + + 00000117 8D 04 3A lea eax, [edi + edx] + 0000011A 8B 7C 24 20 mov edi, [scan] + 0000011E 2B C7 sub eax, edi + 00000120 3D 00000102 cmp eax, MAX_MATCH + 00000125 7D 4C jge LenMaximum + + ;;; If the length of the match is not longer than the best match we + ;;; have so far, then forget it and return to the lookup loop. + + 00000127 8B 54 24 38 mov edx, [deflatestate] + 0000012B 8B 5C 24 1C mov ebx, [bestlen] + 0000012F 3B C3 cmp eax, ebx + 00000131 7F 13 jg LongerMatch + 00000133 8B 74 24 08 mov esi, [windowbestlen] + 00000137 8B 7A 40 mov edi, [edx + dsPrev] + 0000013A 8B 5C 24 0C mov ebx, [scanend] + 0000013E 8B 14 24 mov edx, [chainlenwmask] + 00000141 E9 FFFFFF4E jmp LookupLoop + + ;;; s->match_start = cur_match; + ;;; best_len = len; + ;;; if (len >= nice_match) break; + ;;; scan_end = *(ushf*)(scan+best_len-1); + + 00000146 8B 5C 24 18 LongerMatch: mov ebx, [nicematch] + 0000014A 89 44 24 1C mov [bestlen], eax + 0000014E 89 4A 70 mov [edx + dsMatchStart], ecx + 00000151 3B C3 cmp eax, ebx + 00000153 7D 2D jge LeaveNow + 00000155 8B 74 24 04 mov esi, [window] + 00000159 03 F0 add esi, eax + 0000015B 89 74 24 08 mov [windowbestlen], esi + 0000015F 0F B7 5C 38 FF movzx ebx, word ptr [edi + eax - 1] + 00000164 8B 7A 40 mov edi, [edx + dsPrev] + 00000167 89 5C 24 0C mov [scanend], ebx + 0000016B 8B 14 24 mov edx, [chainlenwmask] + 0000016E E9 FFFFFF21 jmp LookupLoop + + ;;; Accept the current string, with the maximum possible length. + + 00000173 8B 54 24 38 LenMaximum: mov edx, [deflatestate] + 00000177 C7 44 24 1C mov dword ptr [bestlen], MAX_MATCH + 00000102 + 0000017F 89 4A 70 mov [edx + dsMatchStart], ecx + + ;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + ;;; return s->lookahead; + + 00000182 LeaveNow: + 00000182 8B 54 24 38 mov edx, [deflatestate] + 00000186 8B 5C 24 1C mov ebx, [bestlen] + 0000018A 8B 42 74 mov eax, [edx + dsLookahead] + 0000018D 3B D8 cmp ebx, eax + 0000018F 7F 02 jg LookaheadRet + 00000191 8B C3 mov eax, ebx + 00000193 LookaheadRet: + + ;;; Restore the stack and return from whence we came. + + 00000193 83 C4 24 add esp, LocalVarsSize + 00000196 5B pop ebx + 00000197 5E pop esi + 00000198 5F pop edi + 00000199 5D pop ebp + + 0000019A C3 ret + ; please don't remove this string ! + ; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary! + 0000019B 0D 0A 61 73 6D db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah + 36 38 36 20 77 + 69 74 68 20 6D + 61 73 6D 2C 20 + 6F 70 74 69 6D + 69 73 65 64 20 + 61 73 73 65 6D + 62 6C 79 20 63 + 6F 64 65 20 66 + 72 6F 6D 20 42 + 72 69 61 6E 20 + 52 61 69 74 65 + 72 2C 20 77 72 + 69 74 74 65 6E + 20 31 39 39 38 + 0D 0A + + + IFDEF NOUNDERLINE + ELSE + 000001E8 _longest_match endp + ENDIF + + IFDEF NOUNDERLINE + ELSE + 000001E8 _match_init proc near + 000001E8 C3 ret + 000001E9 _match_init endp + ENDIF + + + 000001E9 _TEXT ends + end + Microsoft (R) Macro Assembler Version 10.00.30319.01 04/13/12 13:33:40 +match686.asm Symbols 2 - 1 + + + + +Segments and Groups: + + N a m e Size Length Align Combine Class + +FLAT . . . . . . . . . . . . . . GROUP +_DATA . . . . . . . . . . . . . 32 Bit 00000000 Para Public 'DATA' +_TEXT . . . . . . . . . . . . . 32 Bit 000001E9 Para Public 'CODE' + + +Procedures, parameters, and locals: + + N a m e Type Value Attr + +_longest_match . . . . . . . . . P Near 00000000 _TEXT Length= 000001E8 Public + LastMatchGood . . . . . . . . L Near 00000025 _TEXT + LookaheadLess . . . . . . . . L Near 0000003D _TEXT + LimitPositive . . . . . . . . L Near 0000006C _TEXT + LookupLoop . . . . . . . . . . L Near 00000094 _TEXT + LoopEntry . . . . . . . . . . L Near 000000AE _TEXT + LoopCmps . . . . . . . . . . . L Near 000000E9 _TEXT + LeaveLoopCmps4 . . . . . . . . L Near 00000102 _TEXT + LeaveLoopCmps . . . . . . . . L Near 00000105 _TEXT + LenLower . . . . . . . . . . . L Near 00000112 _TEXT + LongerMatch . . . . . . . . . L Near 00000146 _TEXT + LenMaximum . . . . . . . . . . L Near 00000173 _TEXT + LeaveNow . . . . . . . . . . . L Near 00000182 _TEXT + LookaheadRet . . . . . . . . . L Near 00000193 _TEXT +_match_init . . . . . . . . . . P Near 000001E8 _TEXT Length= 00000001 Public + + +Symbols: + + N a m e Type Value Attr + +@CodeSize . . . . . . . . . . . Number 00000000h +@DataSize . . . . . . . . . . . Number 00000000h +@Interface . . . . . . . . . . . Number 00000000h +@Model . . . . . . . . . . . . . Number 00000007h +@code . . . . . . . . . . . . . Text _TEXT +@data . . . . . . . . . . . . . Text FLAT +@fardata? . . . . . . . . . . . Text FLAT +@fardata . . . . . . . . . . . . Text FLAT +@stack . . . . . . . . . . . . . Text FLAT +LocalVarsSize . . . . . . . . . Number 00000024h +MAX_MATCH_8_ . . . . . . . . . . Number 00000100h +MAX_MATCH . . . . . . . . . . . Number 00000102h +MIN_LOOKAHEAD . . . . . . . . . Number 00000106h +MIN_MATCH . . . . . . . . . . . Number 00000003h +NbStackAdd . . . . . . . . . . . Number 00000034h +NbStack . . . . . . . . . . . . Number 0000004Ch +adrret . . . . . . . . . . . . . Text dword ptr[esp+NbStack-8] +best_len . . . . . . . . . . . . Text dword ptr [esp+NbStack-36] +bestlen . . . . . . . . . . . . Text esp + 28 +chain_length . . . . . . . . . . Text dword ptr [esp+NbStack-28] +chainlenwmask . . . . . . . . . Text esp + 0 +cur_match . . . . . . . . . . . Text dword ptr[esp+NbStack-0] +curmatch . . . . . . . . . . . . Text esp + 60 +deflatestate . . . . . . . . . . Text esp + 56 +dep_chain_length . . . . . . . . Number 0000007Ch +dep_good_match . . . . . . . . . Number 0000008Ch +dep_lookahead . . . . . . . . . Number 00000074h +dep_match_start . . . . . . . . Number 00000070h +dep_nice_match . . . . . . . . . Number 00000090h +dep_prev_length . . . . . . . . Number 00000078h +dep_prev . . . . . . . . . . . . Number 00000040h +dep_strstart . . . . . . . . . . Number 0000006Ch +dep_w_mask . . . . . . . . . . . Number 00000034h +dep_w_size . . . . . . . . . . . Number 0000002Ch +dep_window . . . . . . . . . . . Number 00000038h +dsGoodMatch . . . . . . . . . . Number 0000008Ch +dsLookahead . . . . . . . . . . Number 00000074h +dsMatchLen . . . . . . . . . . . Number 00000060h +dsMatchStart . . . . . . . . . . Number 00000070h +dsMaxChainLen . . . . . . . . . Number 0000007Ch +dsNiceMatch . . . . . . . . . . Number 00000090h +dsPrevLen . . . . . . . . . . . Number 00000078h +dsPrevMatch . . . . . . . . . . Number 00000064h +dsPrev . . . . . . . . . . . . . Number 00000040h +dsStrStart . . . . . . . . . . . Number 0000006Ch +dsWMask . . . . . . . . . . . . Number 00000034h +dsWSize . . . . . . . . . . . . Number 0000002Ch +dsWindow . . . . . . . . . . . . Number 00000038h +limit . . . . . . . . . . . . . Text dword ptr [esp+NbStack-32] +match_start_ptr . . . . . . . . Text dword ptr [esp+NbStack-56] +match_start . . . . . . . . . . Text dword ptr [esp+NbStack-72] +nice_match . . . . . . . . . . . Text dword ptr [esp+NbStack-60] +nicematch . . . . . . . . . . . Text esp + 24 +prev . . . . . . . . . . . . . . Text dword ptr [esp+NbStack-44] +pushebp . . . . . . . . . . . . Text dword ptr[esp+NbStack-12] +pushebx . . . . . . . . . . . . Text dword ptr[esp+NbStack-24] +pushedi . . . . . . . . . . . . Text dword ptr[esp+NbStack-16] +pushesi . . . . . . . . . . . . Text dword ptr[esp+NbStack-20] +scan_start . . . . . . . . . . . Text word ptr [esp+NbStack-48] +scanalign . . . . . . . . . . . Text esp + 20 +scanend . . . . . . . . . . . . Text esp + 12 +scanstart . . . . . . . . . . . Text esp + 16 +scan . . . . . . . . . . . . . . Text esp + 32 +str_s . . . . . . . . . . . . . Text dword ptr[esp+NbStack-4] +strend . . . . . . . . . . . . . Text dword ptr [esp+NbStack-76] +windowbestlen . . . . . . . . . Text esp + 8 +windowlen . . . . . . . . . . . Text dword ptr [esp+NbStack-68] +window . . . . . . . . . . . . . Text esp + 4 +wmask . . . . . . . . . . . . . Text dword ptr [esp+NbStack-52] +zlib1222add . . . . . . . . . . Number 00000008h + + 0 Warnings + 0 Errors diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/readme.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/readme.txt new file mode 100644 index 00000000..3271f720 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/masmx86/readme.txt @@ -0,0 +1,27 @@ + +Summary +------- +This directory contains ASM implementations of the functions +longest_match() and inflate_fast(). + + +Use instructions +---------------- +Assemble using MASM, and copy the object files into the zlib source +directory, then run the appropriate makefile, as suggested below. You can +donwload MASM from here: + + http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64 + +You can also get objects files here: + + http://www.winimage.com/zLibDll/zlib124_masm_obj.zip + +Build instructions +------------------ +* With Microsoft C and MASM: +nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj" + +* With Borland C and TASM: +make -f win32/Makefile.bor LOCAL_ZLIB="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj" OBJPA="+match686c.obj+match686.obj+inffas32.obj" + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/Makefile b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/Makefile new file mode 100644 index 00000000..84eaad20 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/Makefile @@ -0,0 +1,25 @@ +CC=cc +CFLAGS=-O -I../.. + +UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a +ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a + +.c.o: + $(CC) -c $(CFLAGS) $*.c + +all: miniunz minizip + +miniunz: $(UNZ_OBJS) + $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS) + +minizip: $(ZIP_OBJS) + $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS) + +test: miniunz minizip + ./minizip test readme.txt + ./miniunz -l test.zip + mv readme.txt readme.old + ./miniunz test.zip + +clean: + /bin/rm -f *.o *~ minizip miniunz diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/Makefile.am b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/Makefile.am new file mode 100644 index 00000000..2ced9136 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/Makefile.am @@ -0,0 +1,38 @@ +lib_LTLIBRARIES = libminizip.la + +if COND_DEMOS +bin_PROGRAMS = miniunzip minizip +endif + +zlib_top_srcdir = $(top_srcdir)/../.. +zlib_top_builddir = $(top_builddir)/../.. + +AM_CPPFLAGS = -I$(zlib_top_srcdir) +AM_LDFLAGS = -L$(zlib_top_builddir) + +libminizip_la_SOURCES = \ + ioapi.c \ + mztools.c \ + unzip.c \ + zip.c + +libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz + +minizip_includedir = $(includedir)/minizip +minizip_include_HEADERS = \ + crypt.h \ + ioapi.h \ + mztools.h \ + unzip.h \ + zip.h + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = minizip.pc + +EXTRA_PROGRAMS = miniunzip minizip + +miniunzip_SOURCES = miniunz.c +miniunzip_LDADD = libminizip.la + +minizip_SOURCES = minizip.c +minizip_LDADD = libminizip.la -lz diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/MiniZip64_Changes.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/MiniZip64_Changes.txt new file mode 100644 index 00000000..13a1bd91 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/MiniZip64_Changes.txt @@ -0,0 +1,6 @@ + +MiniZip 1.1 was derrived from MiniZip at version 1.01f + +Change in 1.0 (Okt 2009) + - **TODO - Add history** + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/MiniZip64_info.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/MiniZip64_info.txt new file mode 100644 index 00000000..57d71524 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/MiniZip64_info.txt @@ -0,0 +1,74 @@ +MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson + +Introduction +--------------------- +MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html ) + +When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0. +All possible work was done for compatibility. + + +Background +--------------------- +When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64 +support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ ) + +That was used as a starting point. And after that ZIP64 support was added to zip.c +some refactoring and code cleanup was also done. + + +Changed from MiniZip 1.0 to MiniZip 1.1 +--------------------------------------- +* Added ZIP64 support for unzip ( by Even Rouault ) +* Added ZIP64 support for zip ( by Mathias Svensson ) +* Reverted some changed that Even Rouault did. +* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users. +* Added unzip patch for BZIP Compression method (patch create by Daniel Borca) +* Added BZIP Compress method for zip +* Did some refactoring and code cleanup + + +Credits + + Gilles Vollant - Original MiniZip author + Even Rouault - ZIP64 unzip Support + Daniel Borca - BZip Compression method support in unzip + Mathias Svensson - ZIP64 zip support + Mathias Svensson - BZip Compression method support in zip + + Resources + + ZipLayout http://result42.com/projects/ZipFileLayout + Command line tool for Windows that shows the layout and information of the headers in a zip archive. + Used when debugging and validating the creation of zip files using MiniZip64 + + + ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT + Zip File specification + + +Notes. + * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined. + +License +---------------------------------------------------------- + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +---------------------------------------------------------- + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/configure.ac b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/configure.ac new file mode 100644 index 00000000..53adbb89 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/configure.ac @@ -0,0 +1,22 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_INIT([minizip], [1.2.6], [bugzilla.redhat.com]) +AC_CONFIG_SRCDIR([minizip.c]) +AM_INIT_AUTOMAKE([foreign]) +LT_INIT + +AC_MSG_CHECKING([whether to build example programs]) +AC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs])) +AM_CONDITIONAL([COND_DEMOS], [test "$enable_demos" = yes]) +if test "$enable_demos" = yes +then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_SUBST([HAVE_UNISTD_H], [0]) +AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], []) +AC_CONFIG_FILES([Makefile minizip.pc]) +AC_OUTPUT diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/crypt.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/crypt.h new file mode 100644 index 00000000..a01d08d9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/crypt.h @@ -0,0 +1,131 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(const char* passwd, /* password string */ + unsigned char* buf, /* where to write header */ + int bufSize, + unsigned long* pkeys, + const unsigned long* pcrc_32_tab, + unsigned long crcForCrypting) +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/fmuExtract.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/fmuExtract.h new file mode 100644 index 00000000..9a6fac98 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/fmuExtract.h @@ -0,0 +1,28 @@ +/* ------------------------------------------------------------------------- + * Function for extracting FMU files + * Author: Teemu Lempinen + * Copyright 2012 Semantum Oy + * -------------------------------------------------------------------------*/ + +#ifndef fmuExtract_h +#define fmuExtract_h + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef EXTRACT_DLL + #define EXTRACT_API __declspec(dllexport) +#else + #define EXTRACT_API __declspec(dllimport) +#endif + +EXTRACT_API int unzipFMU(const char *zipFileName, const char*outPath); +EXTRACT_API int makedir(char *newdir); + +#ifdef __cplusplus +} +#endif + +#endif // fmuExtract_h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/ioapi.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/ioapi.c new file mode 100644 index 00000000..7f5c191b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/ioapi.c @@ -0,0 +1,247 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS))) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#if defined(__APPLE__) || defined(IOAPI_NO_64) +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == MAXU32) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = FOPEN_FUNC((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = FTELLO_FUNC((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/ioapi.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/ioapi.h new file mode 100644 index 00000000..8dcbdb06 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/ioapi.h @@ -0,0 +1,208 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif + +#endif + +#include +#include +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef __FreeBSD__ +#define fopen64 fopen +#define ftello64 ftello +#define fseeko64 fseeko +#endif +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + +/* Maximum unsigned 32-bit value used as placeholder for zip64 */ +#define MAXU32 0xffffffff + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/iowin32.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/iowin32.c new file mode 100644 index 00000000..6a2a883b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/iowin32.c @@ -0,0 +1,389 @@ +/* iowin32.c -- IO base function header for compress/uncompress .zip + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#include + +#include "zlib.h" +#include "ioapi.h" +#include "iowin32.h" + +#ifndef INVALID_HANDLE_VALUE +#define INVALID_HANDLE_VALUE (0xFFFFFFFF) +#endif + +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +voidpf ZCALLBACK win32_open_file_func OF((voidpf opaque, const char* filename, int mode)); +uLong ZCALLBACK win32_read_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +uLong ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +ZPOS64_T ZCALLBACK win32_tell64_file_func OF((voidpf opaque, voidpf stream)); +long ZCALLBACK win32_seek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +int ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream)); +int ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream)); + +typedef struct +{ + HANDLE hf; + int error; +} WIN32FILE_IOWIN; + + +static void win32_translate_open_mode(int mode, + DWORD* lpdwDesiredAccess, + DWORD* lpdwCreationDisposition, + DWORD* lpdwShareMode, + DWORD* lpdwFlagsAndAttributes) +{ + *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0; + + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + { + *lpdwDesiredAccess = GENERIC_READ; + *lpdwCreationDisposition = OPEN_EXISTING; + *lpdwShareMode = FILE_SHARE_READ; + } + else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + { + *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + *lpdwCreationDisposition = OPEN_EXISTING; + } + else if (mode & ZLIB_FILEFUNC_MODE_CREATE) + { + *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + *lpdwCreationDisposition = CREATE_ALWAYS; + } +} + +static voidpf win32_build_iowin(HANDLE hFile) +{ + voidpf ret=NULL; + + if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) + { + WIN32FILE_IOWIN w32fiow; + w32fiow.hf = hFile; + w32fiow.error = 0; + ret = malloc(sizeof(WIN32FILE_IOWIN)); + + if (ret==NULL) + CloseHandle(hFile); + else + *((WIN32FILE_IOWIN*)ret) = w32fiow; + } + return ret; +} + +voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); + + return win32_build_iowin(hFile); +} + + +voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); + + return win32_build_iowin(hFile); +} + + +voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); + + return win32_build_iowin(hFile); +} + + +voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); + + return win32_build_iowin(hFile); +} + + +uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size) +{ + uLong ret=0; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + + if (hFile != NULL) + { + if (!ReadFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + } + } + + return ret; +} + + +uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size) +{ + uLong ret=0; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + + if (hFile != NULL) + { + if (!WriteFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + } + } + + return ret; +} + +long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream) +{ + long ret=-1; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + if (hFile != NULL) + { + DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT); + if (dwSet == INVALID_SET_FILE_POINTER) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=(long)dwSet; + } + return ret; +} + +ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret= (ZPOS64_T)-1; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream)->hf; + + if (hFile) + { + LARGE_INTEGER li; + li.QuadPart = 0; + li.u.LowPart = SetFilePointer(hFile, li.u.LowPart, &li.u.HighPart, FILE_CURRENT); + if ( (li.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = (ZPOS64_T)-1; + } + else + ret=li.QuadPart; + } + return ret; +} + + +long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin) +{ + DWORD dwMoveMethod=0xFFFFFFFF; + HANDLE hFile = NULL; + + long ret=-1; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + dwMoveMethod = FILE_CURRENT; + break; + case ZLIB_FILEFUNC_SEEK_END : + dwMoveMethod = FILE_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + dwMoveMethod = FILE_BEGIN; + break; + default: return -1; + } + + if (hFile != NULL) + { + DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod); + if (dwSet == INVALID_SET_FILE_POINTER) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=0; + } + return ret; +} + +long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin) +{ + DWORD dwMoveMethod=0xFFFFFFFF; + HANDLE hFile = NULL; + long ret=-1; + + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream)->hf; + + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + dwMoveMethod = FILE_CURRENT; + break; + case ZLIB_FILEFUNC_SEEK_END : + dwMoveMethod = FILE_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + dwMoveMethod = FILE_BEGIN; + break; + default: return -1; + } + + if (hFile) + { + LARGE_INTEGER* li = (LARGE_INTEGER*)&offset; + DWORD dwSet = SetFilePointer(hFile, li->u.LowPart, &li->u.HighPart, dwMoveMethod); + if (dwSet == INVALID_SET_FILE_POINTER) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=0; + } + return ret; +} + +int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream) +{ + int ret=-1; + + if (stream!=NULL) + { + HANDLE hFile; + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + if (hFile != NULL) + { + CloseHandle(hFile); + ret=0; + } + free(stream); + } + return ret; +} + +int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream) +{ + int ret=-1; + if (stream!=NULL) + { + ret = ((WIN32FILE_IOWIN*)stream) -> error; + } + return ret; +} + +void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen_file = win32_open_file_func; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell_file = win32_tell_file_func; + pzlib_filefunc_def->zseek_file = win32_seek_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = win32_open64_file_func; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; + pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} + + +void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; + pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} + + +void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; + pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/iowin32.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/iowin32.h new file mode 100644 index 00000000..0ca0969a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/iowin32.h @@ -0,0 +1,28 @@ +/* iowin32.h -- IO base function header for compress/uncompress .zip + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); +void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def)); + +#ifdef __cplusplus +} +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/make_vms.com b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/make_vms.com new file mode 100644 index 00000000..9ac13a98 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/make_vms.com @@ -0,0 +1,25 @@ +$ if f$search("ioapi.h_orig") .eqs. "" then copy ioapi.h ioapi.h_orig +$ open/write zdef vmsdefs.h +$ copy sys$input: zdef +$ deck +#define unix +#define fill_zlib_filefunc64_32_def_from_filefunc32 fillzffunc64from +#define Write_Zip64EndOfCentralDirectoryLocator Write_Zip64EoDLocator +#define Write_Zip64EndOfCentralDirectoryRecord Write_Zip64EoDRecord +#define Write_EndOfCentralDirectoryRecord Write_EoDRecord +$ eod +$ close zdef +$ copy vmsdefs.h,ioapi.h_orig ioapi.h +$ cc/include=[--]/prefix=all ioapi.c +$ cc/include=[--]/prefix=all miniunz.c +$ cc/include=[--]/prefix=all unzip.c +$ cc/include=[--]/prefix=all minizip.c +$ cc/include=[--]/prefix=all zip.c +$ link miniunz,unzip,ioapi,[--]libz.olb/lib +$ link minizip,zip,ioapi,[--]libz.olb/lib +$ mcr []minizip test minizip_info.txt +$ mcr []miniunz -l test.zip +$ rename minizip_info.txt; minizip_info.txt_old +$ mcr []miniunz test.zip +$ delete test.zip;* +$exit diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/miniunz.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/miniunz.c new file mode 100644 index 00000000..9fefd186 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/miniunz.c @@ -0,0 +1,737 @@ +/* + miniunz.c + Version 1.1, February 14h, 2010 + sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) +*/ + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#ifdef __APPLE__ +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +# include +# include +#endif + + +#include "unzip.h" + +#define CASESENSITIVITY (0) +#define WRITEBUFFERSIZE (8192) +#define MAXFILENAME (256) + +#ifdef _WIN32 +#define USEWIN32IOAPI +#include "iowin32.h" +#endif +/* + mini unzip, demo of unzip package + + usage : + Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir] + + list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT + if it exists +*/ + + +/* change_file_date : change the date/time of a file + filename : the filename of the file where date/time must be modified + dosdate : the new date at the MSDos format (4 bytes) + tmu_date : the SAME new date at the tm_unz format */ +void change_file_date(filename,dosdate,tmu_date) + const char *filename; + uLong dosdate; + tm_unz tmu_date; +{ +#ifdef _WIN32 + HANDLE hFile; + FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; + + hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE, + 0,NULL,OPEN_EXISTING,0,NULL); + GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); + DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); + LocalFileTimeToFileTime(&ftLocal,&ftm); + SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); + CloseHandle(hFile); +#else +#ifdef unix || __APPLE__ + struct utimbuf ut; + struct tm newdate; + newdate.tm_sec = tmu_date.tm_sec; + newdate.tm_min=tmu_date.tm_min; + newdate.tm_hour=tmu_date.tm_hour; + newdate.tm_mday=tmu_date.tm_mday; + newdate.tm_mon=tmu_date.tm_mon; + if (tmu_date.tm_year > 1900) + newdate.tm_year=tmu_date.tm_year - 1900; + else + newdate.tm_year=tmu_date.tm_year ; + newdate.tm_isdst=-1; + + ut.actime=ut.modtime=mktime(&newdate); + utime(filename,&ut); +#endif +#endif +} + + +/* mymkdir and change_file_date are not 100 % portable + As I don't know well Unix, I wait feedback for the unix portion */ + +int mymkdir(dirname) + const char* dirname; +{ + int ret=0; +#ifdef _WIN32 + ret = _mkdir(dirname); +#elif unix + ret = mkdir (dirname,0775); +#elif __APPLE__ + ret = mkdir (dirname,0775); +#endif + return ret; +} + +int makedir (newdir) + char *newdir; +{ + char *buffer ; + char *p; + int len = (int)strlen(newdir); + + if (len <= 0) + return 0; + + buffer = (char*)malloc(len+1); + if (buffer==NULL) + { + printf("Error allocating memory\n"); + return UNZ_INTERNALERROR; + } + strcpy(buffer,newdir); + + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mymkdir(buffer) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mymkdir(buffer) == -1) && (errno == ENOENT)) + { + printf("couldn't create directory %s\n",buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + +void do_banner() +{ + printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n"); + printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); +} + +void do_help() +{ + printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \ + " -e Extract without pathname (junk paths)\n" \ + " -x Extract with pathname\n" \ + " -v list files\n" \ + " -l list files\n" \ + " -d directory to extract into\n" \ + " -o overwrite files without prompting\n" \ + " -p extract crypted file using password\n\n"); +} + +void Display64BitsSize(ZPOS64_T n, int size_char) +{ + /* to avoid compatibility problem , we do here the conversion */ + char number[21]; + int offset=19; + int pos_string = 19; + number[20]=0; + for (;;) { + number[offset]=(char)((n%10)+'0'); + if (number[offset] != '0') + pos_string=offset; + n/=10; + if (offset==0) + break; + offset--; + } + { + int size_display_string = 19-pos_string; + while (size_char > size_display_string) + { + size_char--; + printf(" "); + } + } + + printf("%s",&number[pos_string]); +} + +int do_list(uf) + unzFile uf; +{ + uLong i; + unz_global_info64 gi; + int err; + + err = unzGetGlobalInfo64(uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + printf(" Length Method Size Ratio Date Time CRC-32 Name\n"); + printf(" ------ ------ ---- ----- ---- ---- ------ ----\n"); + for (i=0;i0) + ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size); + + /* display a '*' if the file is crypted */ + if ((file_info.flag & 1) != 0) + charCrypt='*'; + + if (file_info.compression_method==0) + string_method="Stored"; + else + if (file_info.compression_method==Z_DEFLATED) + { + uInt iLevel=(uInt)((file_info.flag & 0x6)/2); + if (iLevel==0) + string_method="Defl:N"; + else if (iLevel==1) + string_method="Defl:X"; + else if ((iLevel==2) || (iLevel==3)) + string_method="Defl:F"; /* 2:fast , 3 : extra fast*/ + } + else + if (file_info.compression_method==Z_BZIP2ED) + { + string_method="BZip2 "; + } + else + string_method="Unkn. "; + + Display64BitsSize(file_info.uncompressed_size,7); + printf(" %6s%c",string_method,charCrypt); + Display64BitsSize(file_info.compressed_size,7); + printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n", + ratio, + (uLong)file_info.tmu_date.tm_mon + 1, + (uLong)file_info.tmu_date.tm_mday, + (uLong)file_info.tmu_date.tm_year % 100, + (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min, + (uLong)file_info.crc,filename_inzip); + if ((i+1)='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N') && (rep!='A')); + } + + if (rep == 'N') + skip = 1; + + if (rep == 'A') + *popt_overwrite=1; + } + + if ((skip==0) && (err==UNZ_OK)) + { + fout=FOPEN_FUNC(write_filename,"wb"); + /* some zipfile don't contain directory alone before file */ + if ((fout==NULL) && ((*popt_extract_without_path)==0) && + (filename_withoutpath!=(char*)filename_inzip)) + { + char c=*(filename_withoutpath-1); + *(filename_withoutpath-1)='\0'; + makedir(write_filename); + *(filename_withoutpath-1)=c; + fout=FOPEN_FUNC(write_filename,"wb"); + } + + if (fout==NULL) + { + printf("error opening %s\n",write_filename); + } + } + + if (fout!=NULL) + { + printf(" extracting: %s\n",write_filename); + + do + { + err = unzReadCurrentFile(uf,buf,size_buf); + if (err<0) + { + printf("error %d with zipfile in unzReadCurrentFile\n",err); + break; + } + if (err>0) + if (fwrite(buf,err,1,fout)!=1) + { + printf("error in writing extracted file\n"); + err=UNZ_ERRNO; + break; + } + } + while (err>0); + if (fout) + fclose(fout); + + if (err==0) + change_file_date(write_filename,file_info.dosDate, + file_info.tmu_date); + } + + if (err==UNZ_OK) + { + err = unzCloseCurrentFile (uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzCloseCurrentFile\n",err); + } + } + else + unzCloseCurrentFile(uf); /* don't lose the error */ + } + + free(buf); + return err; +} + + +int do_extract(uf,opt_extract_without_path,opt_overwrite,password) + unzFile uf; + int opt_extract_without_path; + int opt_overwrite; + const char* password; +{ + uLong i; + unz_global_info64 gi; + int err; + FILE* fout=NULL; + + err = unzGetGlobalInfo64(uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + + for (i=0;i +#include +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +# include +# include +# include +# include +#endif + +#include "zip.h" + +#ifdef _WIN32 + #define USEWIN32IOAPI + #include "iowin32.h" +#endif + + + +#define WRITEBUFFERSIZE (16384) +#define MAXFILENAME (256) + +#ifdef _WIN32 +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret = 0; + { + FILETIME ftLocal; + HANDLE hFind; + WIN32_FIND_DATAA ff32; + + hFind = FindFirstFileA(f,&ff32); + if (hFind != INVALID_HANDLE_VALUE) + { + FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); + FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); + FindClose(hFind); + ret = 1; + } + } + return ret; +} +#else +#ifdef unix || __APPLE__ +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret=0; + struct stat s; /* results of stat() */ + struct tm* filedate; + time_t tm_t=0; + + if (strcmp(f,"-")!=0) + { + char name[MAXFILENAME+1]; + int len = strlen(f); + if (len > MAXFILENAME) + len = MAXFILENAME; + + strncpy(name, f,MAXFILENAME-1); + /* strncpy doesnt append the trailing NULL, of the string is too long. */ + name[ MAXFILENAME ] = '\0'; + + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (stat(name,&s)==0) + { + tm_t = s.st_mtime; + ret = 1; + } + } + filedate = localtime(&tm_t); + + tmzip->tm_sec = filedate->tm_sec; + tmzip->tm_min = filedate->tm_min; + tmzip->tm_hour = filedate->tm_hour; + tmzip->tm_mday = filedate->tm_mday; + tmzip->tm_mon = filedate->tm_mon ; + tmzip->tm_year = filedate->tm_year; + + return ret; +} +#else +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + return 0; +} +#endif +#endif + + + + +int check_exist_file(filename) + const char* filename; +{ + FILE* ftestexist; + int ret = 1; + ftestexist = FOPEN_FUNC(filename,"rb"); + if (ftestexist==NULL) + ret = 0; + else + fclose(ftestexist); + return ret; +} + +void do_banner() +{ + printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n"); + printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n"); +} + +void do_help() +{ + printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \ + " -o Overwrite existing file.zip\n" \ + " -a Append to existing file.zip\n" \ + " -0 Store only\n" \ + " -1 Compress faster\n" \ + " -9 Compress better\n\n" \ + " -j exclude path. store only the file name.\n\n"); +} + +/* calculate the CRC32 of a file, + because to encrypt a file, we need known the CRC32 of the file before */ +int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc) +{ + unsigned long calculate_crc=0; + int err=ZIP_OK; + FILE * fin = FOPEN_FUNC(filenameinzip,"rb"); + + unsigned long size_read = 0; + unsigned long total_read = 0; + if (fin==NULL) + { + err = ZIP_ERRNO; + } + + if (err == ZIP_OK) + do + { + err = ZIP_OK; + size_read = (int)fread(buf,1,size_buf,fin); + if (size_read < size_buf) + if (feof(fin)==0) + { + printf("error in reading %s\n",filenameinzip); + err = ZIP_ERRNO; + } + + if (size_read>0) + calculate_crc = crc32(calculate_crc,buf,size_read); + total_read += size_read; + + } while ((err == ZIP_OK) && (size_read>0)); + + if (fin) + fclose(fin); + + *result_crc=calculate_crc; + printf("file %s crc %lx\n", filenameinzip, calculate_crc); + return err; +} + +int isLargeFile(const char* filename) +{ + int largeFile = 0; + ZPOS64_T pos = 0; + FILE* pFile = FOPEN_FUNC(filename, "rb"); + + if(pFile != NULL) + { + int n = FSEEKO_FUNC(pFile, 0, SEEK_END); + pos = FTELLO_FUNC(pFile); + + printf("File : %s is %lld bytes\n", filename, pos); + + if(pos >= 0xffffffff) + largeFile = 1; + + fclose(pFile); + } + + return largeFile; +} + +int main(argc,argv) + int argc; + char *argv[]; +{ + int i; + int opt_overwrite=0; + int opt_compress_level=Z_DEFAULT_COMPRESSION; + int opt_exclude_path=0; + int zipfilenamearg = 0; + char filename_try[MAXFILENAME+16]; + int zipok; + int err=0; + int size_buf=0; + void* buf=NULL; + const char* password=NULL; + + + do_banner(); + if (argc==1) + { + do_help(); + return 0; + } + else + { + for (i=1;i='0') && (c<='9')) + opt_compress_level = c-'0'; + if ((c=='j') || (c=='J')) + opt_exclude_path = 1; + + if (((c=='p') || (c=='P')) && (i+1='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N') && (rep!='A')); + if (rep=='N') + zipok = 0; + if (rep=='A') + opt_overwrite = 2; + } + } + + if (zipok==1) + { + zipFile zf; + int errclose; +# ifdef USEWIN32IOAPI + zlib_filefunc64_def ffunc; + fill_win32_filefunc64A(&ffunc); + zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc); +# else + zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0); +# endif + + if (zf == NULL) + { + printf("error opening %s\n",filename_try); + err= ZIP_ERRNO; + } + else + printf("creating %s\n",filename_try); + + for (i=zipfilenamearg+1;(i='0') || (argv[i][1]<='9'))) && + (strlen(argv[i]) == 2))) + { + FILE * fin; + int size_read; + const char* filenameinzip = argv[i]; + const char *savefilenameinzip; + zip_fileinfo zi; + unsigned long crcFile=0; + int zip64 = 0; + + zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = + zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; + zi.dosDate = 0; + zi.internal_fa = 0; + zi.external_fa = 0; + filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); + +/* + err = zipOpenNewFileInZip(zf,filenameinzip,&zi, + NULL,0,NULL,0,NULL / * comment * /, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level); +*/ + if ((password != NULL) && (err==ZIP_OK)) + err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); + + zip64 = isLargeFile(filenameinzip); + + /* The path name saved, should not include a leading slash. */ + /*if it did, windows/xp and dynazip couldn't read the zip file. */ + savefilenameinzip = filenameinzip; + while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' ) + { + savefilenameinzip++; + } + + /*should the zip file contain any path at all?*/ + if( opt_exclude_path ) + { + const char *tmpptr; + const char *lastslash = 0; + for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++) + { + if( *tmpptr == '\\' || *tmpptr == '/') + { + lastslash = tmpptr; + } + } + if( lastslash != NULL ) + { + savefilenameinzip = lastslash+1; // base filename follows last slash. + } + } + + /**/ + err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi, + NULL,0,NULL,0,NULL /* comment*/, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level,0, + /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + password,crcFile, zip64); + + if (err != ZIP_OK) + printf("error in opening %s in zipfile\n",filenameinzip); + else + { + fin = FOPEN_FUNC(filenameinzip,"rb"); + if (fin==NULL) + { + err=ZIP_ERRNO; + printf("error in opening %s for reading\n",filenameinzip); + } + } + + if (err == ZIP_OK) + do + { + err = ZIP_OK; + size_read = (int)fread(buf,1,size_buf,fin); + if (size_read < size_buf) + if (feof(fin)==0) + { + printf("error in reading %s\n",filenameinzip); + err = ZIP_ERRNO; + } + + if (size_read>0) + { + err = zipWriteInFileInZip (zf,buf,size_read); + if (err<0) + { + printf("error in writing %s in the zipfile\n", + filenameinzip); + } + + } + } while ((err == ZIP_OK) && (size_read>0)); + + if (fin) + fclose(fin); + + if (err<0) + err=ZIP_ERRNO; + else + { + err = zipCloseFileInZip(zf); + if (err!=ZIP_OK) + printf("error in closing %s in the zipfile\n", + filenameinzip); + } + } + } + errclose = zipClose(zf,NULL); + if (errclose != ZIP_OK) + printf("error in closing %s\n",filename_try); + } + else + { + do_help(); + } + + free(buf); + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/minizip.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/minizip.h new file mode 100644 index 00000000..725bbba1 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/minizip.h @@ -0,0 +1,6 @@ +#ifndef ABC_DLL // abc.dll source code will define this macro before including this header +#define ABC_API __declspec( dllimport ) +#else +#define ABC_API __declspec( dllexport ) +#endif +class ABC_API CAbc {…}; \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/minizip.pc.in b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/minizip.pc.in new file mode 100644 index 00000000..69b5b7fd --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/minizip.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/minizip + +Name: minizip +Description: Minizip zip file manipulation library +Requires: +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lminizip +Libs.private: -lz +Cflags: -I${includedir} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/mztools.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/mztools.c new file mode 100644 index 00000000..96891c2e --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/mztools.c @@ -0,0 +1,291 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +/* Code */ +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#define READ_8(adr) ((unsigned char)*(adr)) +#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) +#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) + +#define WRITE_8(buff, n) do { \ + *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ +} while(0) +#define WRITE_16(buff, n) do { \ + WRITE_8((unsigned char*)(buff), n); \ + WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ +} while(0) +#define WRITE_32(buff, n) do { \ + WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ + WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ +} while(0) + +extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) +const char* file; +const char* fileOut; +const char* fileOutTmp; +uLong* nRecovered; +uLong* bytesRecovered; +{ + int err = Z_OK; + FILE* fpZip = fopen(file, "rb"); + FILE* fpOut = fopen(fileOut, "wb"); + FILE* fpOutCD = fopen(fileOutTmp, "wb"); + if (fpZip != NULL && fpOut != NULL) { + int entries = 0; + uLong totalBytes = 0; + char header[30]; + char filename[1024]; + char extra[1024]; + int offset = 0; + int offsetCD = 0; + while ( fread(header, 1, 30, fpZip) == 30 ) { + int currentOffset = offset; + + /* File entry */ + if (READ_32(header) == 0x04034b50) { + unsigned int version = READ_16(header + 4); + unsigned int gpflag = READ_16(header + 6); + unsigned int method = READ_16(header + 8); + unsigned int filetime = READ_16(header + 10); + unsigned int filedate = READ_16(header + 12); + unsigned int crc = READ_32(header + 14); /* crc */ + unsigned int cpsize = READ_32(header + 18); /* compressed size */ + unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ + unsigned int fnsize = READ_16(header + 26); /* file name length */ + unsigned int extsize = READ_16(header + 28); /* extra field length */ + filename[0] = extra[0] = '\0'; + + /* Header */ + if (fwrite(header, 1, 30, fpOut) == 30) { + offset += 30; + } else { + err = Z_ERRNO; + break; + } + + /* Filename */ + if (fnsize > 0) { + if (fnsize < sizeof(filename)) { + if (fread(filename, 1, fnsize, fpZip) == fnsize) { + if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { + offset += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (extsize < sizeof(extra)) { + if (fread(extra, 1, extsize, fpZip) == extsize) { + if (fwrite(extra, 1, extsize, fpOut) == extsize) { + offset += extsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } + + /* Data */ + { + int dataSize = cpsize; + if (dataSize == 0) { + dataSize = uncpsize; + } + if (dataSize > 0) { + char* data = malloc(dataSize); + if (data != NULL) { + if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { + if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { + offset += dataSize; + totalBytes += dataSize; + } else { + err = Z_ERRNO; + } + } else { + err = Z_ERRNO; + } + free(data); + if (err != Z_OK) { + break; + } + } else { + err = Z_MEM_ERROR; + break; + } + } + } + + /* Central directory entry */ + { + char header[46]; + char* comment = ""; + int comsize = (int) strlen(comment); + WRITE_32(header, 0x02014b50); + WRITE_16(header + 4, version); + WRITE_16(header + 6, version); + WRITE_16(header + 8, gpflag); + WRITE_16(header + 10, method); + WRITE_16(header + 12, filetime); + WRITE_16(header + 14, filedate); + WRITE_32(header + 16, crc); + WRITE_32(header + 20, cpsize); + WRITE_32(header + 24, uncpsize); + WRITE_16(header + 28, fnsize); + WRITE_16(header + 30, extsize); + WRITE_16(header + 32, comsize); + WRITE_16(header + 34, 0); /* disk # */ + WRITE_16(header + 36, 0); /* int attrb */ + WRITE_32(header + 38, 0); /* ext attrb */ + WRITE_32(header + 42, currentOffset); + /* Header */ + if (fwrite(header, 1, 46, fpOutCD) == 46) { + offsetCD += 46; + + /* Filename */ + if (fnsize > 0) { + if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { + offsetCD += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { + offsetCD += extsize; + } else { + err = Z_ERRNO; + break; + } + } + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { + offsetCD += comsize; + } else { + err = Z_ERRNO; + break; + } + } + + + } else { + err = Z_ERRNO; + break; + } + } + + /* Success */ + entries++; + + } else { + break; + } + } + + /* Final central directory */ + { + int entriesZip = entries; + char header[22]; + char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; + int comsize = (int) strlen(comment); + if (entriesZip > 0xffff) { + entriesZip = 0xffff; + } + WRITE_32(header, 0x06054b50); + WRITE_16(header + 4, 0); /* disk # */ + WRITE_16(header + 6, 0); /* disk # */ + WRITE_16(header + 8, entriesZip); /* hack */ + WRITE_16(header + 10, entriesZip); /* hack */ + WRITE_32(header + 12, offsetCD); /* size of CD */ + WRITE_32(header + 16, offset); /* offset to CD */ + WRITE_16(header + 20, comsize); /* comment */ + + /* Header */ + if (fwrite(header, 1, 22, fpOutCD) == 22) { + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { + err = Z_ERRNO; + } + } + + } else { + err = Z_ERRNO; + } + } + + /* Final merge (file + central directory) */ + fclose(fpOutCD); + if (err == Z_OK) { + fpOutCD = fopen(fileOutTmp, "rb"); + if (fpOutCD != NULL) { + int nRead; + char buffer[8192]; + while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { + if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { + err = Z_ERRNO; + break; + } + } + fclose(fpOutCD); + } + } + + /* Close */ + fclose(fpZip); + fclose(fpOut); + + /* Wipe temporary file */ + (void)remove(fileOutTmp); + + /* Number of recovered entries */ + if (err == Z_OK) { + if (nRecovered != NULL) { + *nRecovered = entries; + } + if (bytesRecovered != NULL) { + *bytesRecovered = totalBytes; + } + } + } else { + err = Z_STREAM_ERROR; + } + return err; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/mztools.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/mztools.h new file mode 100644 index 00000000..a49a426e --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/mztools.h @@ -0,0 +1,37 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +#ifndef _zip_tools_H +#define _zip_tools_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#include "unzip.h" + +/* Repair a ZIP file (missing central directory) + file: file to recover + fileOut: output file after recovery + fileOutTmp: temporary file name used for recovery +*/ +extern int ZEXPORT unzRepair(const char* file, + const char* fileOut, + const char* fileOutTmp, + uLong* nRecovered, + uLong* bytesRecovered); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/unzip.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/unzip.c new file mode 100644 index 00000000..affad4bf --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/unzip.c @@ -0,0 +1,2125 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unz64local_getByte OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unz64local_getShort OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX)); + + +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) +{ + ZPOS64_T x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<24; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<32; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<40; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<48; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<56; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) + +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); + +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return 0; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + if (uL != 0x06064b50) + return 0; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal (const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) +{ + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unz64local_GetCurrentFileInfoInternal (unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; + + if(file_info.uncompressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == MAXU32) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == MAXU32) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if ((err==UNZ_OK) && (pfile_info != NULL)) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date, + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (unzFile file) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, + int* level, int raw, const char* password) +{ + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->read_buffer == NULL) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +{ + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) +{ + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset (unzFile file) +{ + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +{ + return unzSetOffset64(file,pos); +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/unzip.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/unzip.h new file mode 100644 index 00000000..3183968b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); + +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); + +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/zip.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/zip.c new file mode 100644 index 00000000..1b99580e --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/zip.c @@ -0,0 +1,2007 @@ +/* zip.c -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + Oct-2009 - Mathias Svensson - Remove old C style function prototypes + Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives + Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. + Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data + It is used when recreting zip archive with RAW when deleting items from a zip. + ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. + Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + +*/ + + +#include +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (64*1024) //(16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + + +// NOT sure that this work on ALL platform +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x6064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + ZPOS64_T pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralExtra; + uLong size_centralheader; /* size of the central header for cur file */ + uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; + int encrypt; + int zip64; /* Add ZIP64 extened information in the extra field */ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; +#ifndef NOCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; + int crypt_header_size; +#endif +} curfile64_info; + +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile64_info ci; /* info on the file curretly writing */ + + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T add_position_when_writting_offset; + ZPOS64_T number_entry; + +#ifndef NO_ADDFILEINEXISTINGZIP + char *globalcomment; +#endif + +} zip64_internal; + + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(linkedlist_datablock_internal* ldi) +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(linkedlist_data* ll) +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(linkedlist_data* ll) +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + + +/****************************************************************************/ + +#ifndef NO_ADDFILEINEXISTINGZIP +/* =========================================================================== + Inputs a long in LSB order to the given file + nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) +*/ + +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +{ + unsigned char buf[8]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } + + if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } +} + +/****************************************************************************/ + + +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) +{ + uLong year = (uLong)ptm->tm_year; + if (year>=1980) + year-=1980; + else if (year>=80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); + +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return ZIP_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); + + +local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) +{ + ZPOS64_T x; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<24; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<32; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<40; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<48; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<56; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + + return err; +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* +Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before +the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + { + // Signature "0x07064b50" Zip64 end of central directory locater + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + } + + if (uPosFound!=0) + break; + } + + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) + return 0; + + /* total number of disks */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto Zip64 end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' + return 0; + + return relativeOffset; +} + +int LoadCentralDirectoryRecord(zip64_internal* pziinit) +{ + int err=ZIP_OK; + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory */ + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry; + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + uLong VersionMadeBy; + uLong VersionNeeded; + uLong size_comment; + + int hasZIP64Record = 0; + + // check first if we find a ZIP64 record + central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); + if(central_pos > 0) + { + hasZIP64Record = 1; + } + else if(central_pos == 0) + { + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); + } + +/* disable to allow appending to empty ZIP archive + if (central_pos==0) + err=ZIP_ERRNO; +*/ + + if(hasZIP64Record) + { + ZPOS64_T sizeEndOfCentralDirectory; + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* size of zip64 end of central directory record */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version made by */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version needed to extract */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + // TODO.. + // read the comment from the standard central header. + size_comment = 0; + } + else + { + // Read End of central Directory info + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + number_entry = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry = uL; + + /* total number of entries in the central dir */ + number_entry_CD = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry_CD = uL; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + size_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + size_central_dir = uL; + + /* offset of start of central directory with respect to the starting disk number */ + offset_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + offset_central_dir = uL; + + + /* zipfile global comment length */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) + err=ZIP_ERRNO; + } + + if ((central_posz_filefunc, pziinit->filestream); + return ZIP_ERRNO; + } + + if (size_comment>0) + { + pziinit->globalcomment = (char*)ALLOC(size_comment+1); + if (pziinit->globalcomment) + { + size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); + pziinit->globalcomment[size_comment]=0; + } + } + + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); + pziinit->add_position_when_writting_offset = byte_before_the_zipfile; + + { + ZPOS64_T size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + while ((size_central_dir_to_read>0) && (err==ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); + + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + pziinit->begin_pos = byte_before_the_zipfile; + pziinit->number_entry = number_entry_CD; + + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + return err; +} + + +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + + +/************************************************************/ +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +{ + zip64_internal ziinit; + zip64_internal* zi; + int err=ZIP_OK; + + ziinit.z_filefunc.zseek32_file = NULL; + ziinit.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); + else + ziinit.z_filefunc = *pzlib_filefunc64_32_def; + + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) + return NULL; + + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + + + + zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); + if (zi==NULL) + { + ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); + return NULL; + } + + /* now we add file in a zipfile */ +# ifndef NO_ADDFILEINEXISTINGZIP + ziinit.globalcomment = NULL; + if (append == APPEND_STATUS_ADDINZIP) + { + // Read and Cache Central Directory Records + err = LoadCentralDirectoryRecord(&ziinit); + } + + if (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { +# ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } +} + +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +{ + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +{ + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + + + +extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +{ + return zipOpen3((const void*)pathname,append,NULL,NULL); +} + +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +{ + return zipOpen3(pathname,append,NULL,NULL); +} + +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +{ + /* write the local header */ + int err; + uInt size_filename = (uInt)strlen(filename); + uInt size_extrafield = size_extrafield_local; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); + + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); + + // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ + } + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); + + if(zi->ci.zip64) + { + size_extrafield += 20; + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); + + if ((err==ZIP_OK) && (size_filename > 0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) + err = ZIP_ERRNO; + } + + if ((err==ZIP_OK) && (size_extrafield_local > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) + err = ZIP_ERRNO; + } + + + if ((err==ZIP_OK) && (zi->ci.zip64)) + { + // write the Zip64 extended info + short HeaderID = 1; + short DataSize = 16; + ZPOS64_T CompressedSize = 0; + ZPOS64_T UncompressedSize = 0; + + // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); + } + + return err; +} + +/* + NOTE. + When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped + before calling this function it can be done with zipRemoveExtraInfoBlock + + It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize + unnecessary allocations. + */ +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) +{ + zip64_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + +# ifdef NOCRYPT + (crcForCrypting); + if (password != NULL) + return ZIP_PARAMERROR; +# endif + + if (file == NULL) + return ZIP_PARAMERROR; + +#ifdef HAVE_BZIP2 + if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) + return ZIP_PARAMERROR; +#else + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; +#endif + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); + + size_filename = (uInt)strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + } + + zi->ci.flag = flagBase; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if ((level==2)) + zi->ci.flag |= 4; + if ((level==1)) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; + zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data + + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + + zi->ci.size_centralExtra = size_extrafield_global; + zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + if(zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + zi->ci.zip64 = zip64; + zi->ci.totalCompressedData = 0; + zi->ci.totalUncompressedData = 0; + zi->ci.pos_zip64extrainfo = 0; + + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + +#ifdef HAVE_BZIP2 + zi->ci.bstream.avail_in = (uInt)0; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + zi->ci.bstream.total_in_hi32 = 0; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_out_hi32 = 0; + zi->ci.bstream.total_out_lo32 = 0; +#endif + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; + +#ifdef HAVE_BZIP2 + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +#else + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +#endif + { + if(zi->ci.method == Z_DEFLATED) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + if (windowBits>0) + windowBits = -windowBits; + + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + + if (err==Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } + else if(zi->ci.method == Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + // Init BZip stuff here + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; + + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); + if(err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; +#endif + } + + } + +# ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +local int zip64FlushWriteBuffer(zip64_internal* zi) +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { +#ifndef NOCRYPT + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +#endif + } + + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED) + { + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; + } + else +#endif + { + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; + } + + + zi->ci.pos_in_buffered_data = 0; + + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +{ + zip64_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + { + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; + + while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) + { + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + + + if(err != BZ_RUN_OK) + break; + + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; +// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; + } + } + + if(err == BZ_RUN_OK) + err = ZIP_OK; + } + else +#endif + { + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + if(uTotalOutBefore > zi->ci.stream.total_out) + { + int bBreak = 0; + bBreak++; + } + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + }// while(...) + } + + return err; +} + +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +{ + return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); +} + +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +{ + zip64_internal* zi; + ZPOS64_T compressed_size; + uLong invalidValue = 0xffffffff; + short datasize = 0; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { +#ifdef HAVE_BZIP2 + err = BZ_FINISH_OK; + while (err==BZ_FINISH_OK) + { + uLong uTotalOutBefore; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.bstream.total_out_lo32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if(err == BZ_STREAM_END) + err = Z_STREAM_END; + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); + } + + if(err == BZ_FINISH_OK) + err = ZIP_OK; +#endif + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + { + if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) + err = ZIP_ERRNO; + } + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } +#ifdef HAVE_BZIP2 + else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err==ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } +#endif + + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = zi->ci.totalUncompressedData; + } + compressed_size = zi->ci.totalCompressedData; + +# ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +# endif + + // update Current Item crc and sizes, + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { + /*version Made by*/ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); + /*version needed*/ + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); + + } + + zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + + + if(compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ + + /// set internal file attributes field + if (zi->ci.stream.data_type == Z_ASCII) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); + + if(uncompressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + + // Add ZIP64 extra info field for uncompressed size + if(uncompressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for compressed size + if(compressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for relative offset to local file header of current file + if(zi->ci.pos_local_header >= 0xffffffff) + datasize += 8; + + if(datasize > 0) + { + char* p = NULL; + + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + { + // we can not write more data to the buffer that we have room for. + return ZIP_BADZIPFILE; + } + + p = zi->ci.central_header + zi->ci.size_centralheader; + + // Add Extra Information Header for 'ZIP64 information' + zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); // DataSize + p += 2; + + if(uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } + + if(compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } + + if(zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } + + // Update how much extra free space we got in the memory buffer + // and increase the centralheader size so the new ZIP64 fields are included + // ( 4 below is the size of HeaderID and DataSize field ) + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; + + // Update the extra info size field + zi->ci.size_centralExtra += datasize + 4; + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); + } + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); + + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + // Update the LocalFileHeader with the new values. + + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + + if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff ) + { + if(zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + else + err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal + } + else + { + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + } + + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipCloseFileInZip (zipFile file) +{ + return zipCloseFileInZipRaw (file,0,0); +} + +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) +{ + int err = ZIP_OK; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); + + /*num disks*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + /*relative offset*/ + if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); + + /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); + + return err; +} + +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + uLong Zip64DataSize = 44; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? + + if (err==ZIP_OK) /* version made by */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* version needed */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); + } + return err; +} +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + /*signature*/ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + { + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + } + + if (err==ZIP_OK) /* total number of entries in the central dir */ + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + { + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); + } + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); + } + + return err; +} + +int Write_GlobalComment(zip64_internal* zi, const char* global_comment) +{ + int err = ZIP_OK; + uInt size_global_comment = 0; + + if(global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + + if (err == ZIP_OK && size_global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + } + return err; +} + +extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +{ + zip64_internal* zi; + int err = 0; + uLong size_centraldir = 0; + ZPOS64_T centraldir_pos_inzip; + ZPOS64_T pos; + + if (file == NULL) + return ZIP_PARAMERROR; + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + +#ifndef NO_ADDFILEINEXISTINGZIP + if (global_comment==NULL) + global_comment = zi->globalcomment; +#endif + + centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + err = ZIP_ERRNO; + } + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_linkedlist(&(zi->central_dir)); + + pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) + { + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + } + + if (err==ZIP_OK) + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + if(err == ZIP_OK) + err = Write_GlobalComment(zi, global_comment); + + if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(zi->globalcomment); +#endif + TRYFREE(zi); + + return err; +} + +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) +{ + char* p = pData; + int size = 0; + char* pNewHeader; + char* pTmp; + short header; + short dataSize; + + int retVal = ZIP_OK; + + if(pData == NULL || *dataLen < 4) + return ZIP_PARAMERROR; + + pNewHeader = (char*)ALLOC(*dataLen); + pTmp = pNewHeader; + + while(p < (pData + *dataLen)) + { + header = *(short*)p; + dataSize = *(((short*)p)+1); + + if( header == sHeader ) // Header found. + { + p += dataSize + 4; // skip it. do not copy to temp buffer + } + else + { + // Extra Info block should not be removed, So copy it to the temp buffer. + memcpy(pTmp, p, dataSize + 4); + p += dataSize + 4; + size += dataSize + 4; + } + + } + + if(size < *dataLen) + { + // clean old extra info block. + memset(pData,0, *dataLen); + + // copy the new extra info block over the old + if(size > 0) + memcpy(pData, pNewHeader, size); + + // set the new extra info size + *dataLen = size; + + retVal = ZIP_OK; + } + else + retVal = ZIP_ERRNO; + + TRYFREE(pNewHeader); + + return retVal; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/zip.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/zip.h new file mode 100644 index 00000000..8aaebb62 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/minizip/zip.h @@ -0,0 +1,362 @@ +/* zip.h -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------- + + Changes + + See header of zip.h + +*/ + +#ifndef _zip12_H +#define _zip12_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#define HAVE_BZIP2 + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) + +#ifndef DEF_MEM_LEVEL +# if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +# else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +# endif +#endif +/* default memLevel */ + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +typedef const char* zipcharpc; + + +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. +*/ + +/* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte +*/ + +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); + +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); + +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64)); + +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + zip64 is set to 1 if a zip64 extended information block should be added to the local file header. + this MUST be '1' if the uncompressed size is >= 0xffffffff. + +*/ + + +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); + + +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64)); +/* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting)); + +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64 + )); + +/* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCrypting : crc of file to compress (needed for crypting) + */ + +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase + )); + + +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64 + )); +/* + Same than zipOpenNewFileInZip4, except + versionMadeBy : value for Version made by field + flag : value for flag field (compression level info will be added) + */ + + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); + +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32)); + +/* + Close the current file in the zipfile, for file opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + + +extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +/* + zipRemoveExtraInfoBlock - Added by Mathias Svensson + + Remove extra information block from a extra information data for the local file header or central directory header + + It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. + + 0x0001 is the signature header for the ZIP64 extra information blocks + + usage. + Remove ZIP64 Extra information from a central director extra field data + zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); + + Remove ZIP64 Extra information from a Local File Header extra field data + zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip64_H */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/example.pas b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/example.pas new file mode 100644 index 00000000..5518b36a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/example.pas @@ -0,0 +1,599 @@ +(* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Pascal translation + * Copyright (C) 1998 by Jacques Nomssi Nzali. + * For conditions of distribution and use, see copyright notice in readme.txt + * + * Adaptation to the zlibpas interface + * Copyright (C) 2003 by Cosmin Truta. + * For conditions of distribution and use, see copyright notice in readme.txt + *) + +program example; + +{$DEFINE TEST_COMPRESS} +{DO NOT $DEFINE TEST_GZIO} +{$DEFINE TEST_DEFLATE} +{$DEFINE TEST_INFLATE} +{$DEFINE TEST_FLUSH} +{$DEFINE TEST_SYNC} +{$DEFINE TEST_DICT} + +uses SysUtils, zlibpas; + +const TESTFILE = 'foo.gz'; + +(* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + *) +const hello: PChar = 'hello, hello!'; + +const dictionary: PChar = 'hello'; + +var dictId: LongInt; (* Adler32 value of the dictionary *) + +procedure CHECK_ERR(err: Integer; msg: String); +begin + if err <> Z_OK then + begin + WriteLn(msg, ' error: ', err); + Halt(1); + end; +end; + +procedure EXIT_ERR(const msg: String); +begin + WriteLn('Error: ', msg); + Halt(1); +end; + +(* =========================================================================== + * Test compress and uncompress + *) +{$IFDEF TEST_COMPRESS} +procedure test_compress(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var err: Integer; + len: LongInt; +begin + len := StrLen(hello)+1; + + err := compress(compr, comprLen, hello, len); + CHECK_ERR(err, 'compress'); + + StrCopy(PChar(uncompr), 'garbage'); + + err := uncompress(uncompr, uncomprLen, compr, comprLen); + CHECK_ERR(err, 'uncompress'); + + if StrComp(PChar(uncompr), hello) <> 0 then + EXIT_ERR('bad uncompress') + else + WriteLn('uncompress(): ', PChar(uncompr)); +end; +{$ENDIF} + +(* =========================================================================== + * Test read/write of .gz files + *) +{$IFDEF TEST_GZIO} +procedure test_gzio(const fname: PChar; (* compressed file name *) + uncompr: Pointer; + uncomprLen: LongInt); +var err: Integer; + len: Integer; + zfile: gzFile; + pos: LongInt; +begin + len := StrLen(hello)+1; + + zfile := gzopen(fname, 'wb'); + if zfile = NIL then + begin + WriteLn('gzopen error'); + Halt(1); + end; + gzputc(zfile, 'h'); + if gzputs(zfile, 'ello') <> 4 then + begin + WriteLn('gzputs err: ', gzerror(zfile, err)); + Halt(1); + end; + {$IFDEF GZ_FORMAT_STRING} + if gzprintf(zfile, ', %s!', 'hello') <> 8 then + begin + WriteLn('gzprintf err: ', gzerror(zfile, err)); + Halt(1); + end; + {$ELSE} + if gzputs(zfile, ', hello!') <> 8 then + begin + WriteLn('gzputs err: ', gzerror(zfile, err)); + Halt(1); + end; + {$ENDIF} + gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *) + gzclose(zfile); + + zfile := gzopen(fname, 'rb'); + if zfile = NIL then + begin + WriteLn('gzopen error'); + Halt(1); + end; + + StrCopy(PChar(uncompr), 'garbage'); + + if gzread(zfile, uncompr, uncomprLen) <> len then + begin + WriteLn('gzread err: ', gzerror(zfile, err)); + Halt(1); + end; + if StrComp(PChar(uncompr), hello) <> 0 then + begin + WriteLn('bad gzread: ', PChar(uncompr)); + Halt(1); + end + else + WriteLn('gzread(): ', PChar(uncompr)); + + pos := gzseek(zfile, -8, SEEK_CUR); + if (pos <> 6) or (gztell(zfile) <> pos) then + begin + WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile)); + Halt(1); + end; + + if gzgetc(zfile) <> ' ' then + begin + WriteLn('gzgetc error'); + Halt(1); + end; + + if gzungetc(' ', zfile) <> ' ' then + begin + WriteLn('gzungetc error'); + Halt(1); + end; + + gzgets(zfile, PChar(uncompr), uncomprLen); + uncomprLen := StrLen(PChar(uncompr)); + if uncomprLen <> 7 then (* " hello!" *) + begin + WriteLn('gzgets err after gzseek: ', gzerror(zfile, err)); + Halt(1); + end; + if StrComp(PChar(uncompr), hello + 6) <> 0 then + begin + WriteLn('bad gzgets after gzseek'); + Halt(1); + end + else + WriteLn('gzgets() after gzseek: ', PChar(uncompr)); + + gzclose(zfile); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with small buffers + *) +{$IFDEF TEST_DEFLATE} +procedure test_deflate(compr: Pointer; comprLen: LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; + len: LongInt; +begin + len := StrLen(hello)+1; + + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, 'deflateInit'); + + c_stream.next_in := hello; + c_stream.next_out := compr; + + while (c_stream.total_in <> len) and + (c_stream.total_out < comprLen) do + begin + c_stream.avail_out := 1; { force small buffers } + c_stream.avail_in := 1; + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + end; + + (* Finish the stream, still forcing small buffers: *) + while TRUE do + begin + c_stream.avail_out := 1; + err := deflate(c_stream, Z_FINISH); + if err = Z_STREAM_END then + break; + CHECK_ERR(err, 'deflate'); + end; + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); +end; +{$ENDIF} + +(* =========================================================================== + * Test inflate with small buffers + *) +{$IFDEF TEST_INFLATE} +procedure test_inflate(compr: Pointer; comprLen : LongInt; + uncompr: Pointer; uncomprLen : LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := 0; + d_stream.next_out := uncompr; + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + while (d_stream.total_out < uncomprLen) and + (d_stream.total_in < comprLen) do + begin + d_stream.avail_out := 1; (* force small buffers *) + d_stream.avail_in := 1; + err := inflate(d_stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + CHECK_ERR(err, 'inflate'); + end; + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + if StrComp(PChar(uncompr), hello) <> 0 then + EXIT_ERR('bad inflate') + else + WriteLn('inflate(): ', PChar(uncompr)); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with large buffers and dynamic change of compression level + *) +{$IFDEF TEST_DEFLATE} +procedure test_large_deflate(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; +begin + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_BEST_SPEED); + CHECK_ERR(err, 'deflateInit'); + + c_stream.next_out := compr; + c_stream.avail_out := Integer(comprLen); + + (* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + *) + c_stream.next_in := uncompr; + c_stream.avail_in := Integer(uncomprLen); + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + if c_stream.avail_in <> 0 then + EXIT_ERR('deflate not greedy'); + + (* Feed in already compressed data and switch to no compression: *) + deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in := compr; + c_stream.avail_in := Integer(comprLen div 2); + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + + (* Switch back to compressing mode: *) + deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in := uncompr; + c_stream.avail_in := Integer(uncomprLen); + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + + err := deflate(c_stream, Z_FINISH); + if err <> Z_STREAM_END then + EXIT_ERR('deflate should report Z_STREAM_END'); + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); +end; +{$ENDIF} + +(* =========================================================================== + * Test inflate with large buffers + *) +{$IFDEF TEST_INFLATE} +procedure test_large_inflate(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := Integer(comprLen); + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + while TRUE do + begin + d_stream.next_out := uncompr; (* discard the output *) + d_stream.avail_out := Integer(uncomprLen); + err := inflate(d_stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + CHECK_ERR(err, 'large inflate'); + end; + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then + begin + WriteLn('bad large inflate: ', d_stream.total_out); + Halt(1); + end + else + WriteLn('large_inflate(): OK'); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with full flush + *) +{$IFDEF TEST_FLUSH} +procedure test_flush(compr: Pointer; var comprLen : LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; + len: Integer; +begin + len := StrLen(hello)+1; + + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, 'deflateInit'); + + c_stream.next_in := hello; + c_stream.next_out := compr; + c_stream.avail_in := 3; + c_stream.avail_out := Integer(comprLen); + err := deflate(c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, 'deflate'); + + Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *) + c_stream.avail_in := len - 3; + + err := deflate(c_stream, Z_FINISH); + if err <> Z_STREAM_END then + CHECK_ERR(err, 'deflate'); + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); + + comprLen := c_stream.total_out; +end; +{$ENDIF} + +(* =========================================================================== + * Test inflateSync() + *) +{$IFDEF TEST_SYNC} +procedure test_sync(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen : LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := 2; (* just read the zlib header *) + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + d_stream.next_out := uncompr; + d_stream.avail_out := Integer(uncomprLen); + + inflate(d_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'inflate'); + + d_stream.avail_in := Integer(comprLen-2); (* read all compressed data *) + err := inflateSync(d_stream); (* but skip the damaged part *) + CHECK_ERR(err, 'inflateSync'); + + err := inflate(d_stream, Z_FINISH); + if err <> Z_DATA_ERROR then + EXIT_ERR('inflate should report DATA_ERROR'); + (* Because of incorrect adler32 *) + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + WriteLn('after inflateSync(): hel', PChar(uncompr)); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with preset dictionary + *) +{$IFDEF TEST_DICT} +procedure test_dict_deflate(compr: Pointer; comprLen: LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; +begin + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, 'deflateInit'); + + err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary)); + CHECK_ERR(err, 'deflateSetDictionary'); + + dictId := c_stream.adler; + c_stream.next_out := compr; + c_stream.avail_out := Integer(comprLen); + + c_stream.next_in := hello; + c_stream.avail_in := StrLen(hello)+1; + + err := deflate(c_stream, Z_FINISH); + if err <> Z_STREAM_END then + EXIT_ERR('deflate should report Z_STREAM_END'); + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); +end; +{$ENDIF} + +(* =========================================================================== + * Test inflate with a preset dictionary + *) +{$IFDEF TEST_DICT} +procedure test_dict_inflate(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := Integer(comprLen); + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + d_stream.next_out := uncompr; + d_stream.avail_out := Integer(uncomprLen); + + while TRUE do + begin + err := inflate(d_stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + if err = Z_NEED_DICT then + begin + if d_stream.adler <> dictId then + EXIT_ERR('unexpected dictionary'); + err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary)); + end; + CHECK_ERR(err, 'inflate with dict'); + end; + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + if StrComp(PChar(uncompr), hello) <> 0 then + EXIT_ERR('bad inflate with dict') + else + WriteLn('inflate with dictionary: ', PChar(uncompr)); +end; +{$ENDIF} + +var compr, uncompr: Pointer; + comprLen, uncomprLen: LongInt; + +begin + if zlibVersion^ <> ZLIB_VERSION[1] then + EXIT_ERR('Incompatible zlib version'); + + WriteLn('zlib version: ', zlibVersion); + WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags])); + + comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *) + uncomprLen := comprLen; + GetMem(compr, comprLen); + GetMem(uncompr, uncomprLen); + if (compr = NIL) or (uncompr = NIL) then + EXIT_ERR('Out of memory'); + (* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + *) + FillChar(compr^, comprLen, 0); + FillChar(uncompr^, uncomprLen, 0); + + {$IFDEF TEST_COMPRESS} + WriteLn('** Testing compress'); + test_compress(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_GZIO} + WriteLn('** Testing gzio'); + if ParamCount >= 1 then + test_gzio(ParamStr(1), uncompr, uncomprLen) + else + test_gzio(TESTFILE, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_DEFLATE} + WriteLn('** Testing deflate with small buffers'); + test_deflate(compr, comprLen); + {$ENDIF} + {$IFDEF TEST_INFLATE} + WriteLn('** Testing inflate with small buffers'); + test_inflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_DEFLATE} + WriteLn('** Testing deflate with large buffers'); + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + {$IFDEF TEST_INFLATE} + WriteLn('** Testing inflate with large buffers'); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_FLUSH} + WriteLn('** Testing deflate with full flush'); + test_flush(compr, comprLen); + {$ENDIF} + {$IFDEF TEST_SYNC} + WriteLn('** Testing inflateSync'); + test_sync(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + comprLen := uncomprLen; + + {$IFDEF TEST_DICT} + WriteLn('** Testing deflate and inflate with preset dictionary'); + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + FreeMem(compr, comprLen); + FreeMem(uncompr, uncomprLen); +end. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/readme.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/readme.txt new file mode 100644 index 00000000..60e87c8a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/readme.txt @@ -0,0 +1,76 @@ + +This directory contains a Pascal (Delphi, Kylix) interface to the +zlib data compression library. + + +Directory listing +================= + +zlibd32.mak makefile for Borland C++ +example.pas usage example of zlib +zlibpas.pas the Pascal interface to zlib +readme.txt this file + + +Compatibility notes +=================== + +- Although the name "zlib" would have been more normal for the + zlibpas unit, this name is already taken by Borland's ZLib unit. + This is somehow unfortunate, because that unit is not a genuine + interface to the full-fledged zlib functionality, but a suite of + class wrappers around zlib streams. Other essential features, + such as checksums, are missing. + It would have been more appropriate for that unit to have a name + like "ZStreams", or something similar. + +- The C and zlib-supplied types int, uInt, long, uLong, etc. are + translated directly into Pascal types of similar sizes (Integer, + LongInt, etc.), to avoid namespace pollution. In particular, + there is no conversion of unsigned int into a Pascal unsigned + integer. The Word type is non-portable and has the same size + (16 bits) both in a 16-bit and in a 32-bit environment, unlike + Integer. Even if there is a 32-bit Cardinal type, there is no + real need for unsigned int in zlib under a 32-bit environment. + +- Except for the callbacks, the zlib function interfaces are + assuming the calling convention normally used in Pascal + (__pascal for DOS and Windows16, __fastcall for Windows32). + Since the cdecl keyword is used, the old Turbo Pascal does + not work with this interface. + +- The gz* function interfaces are not translated, to avoid + interfacing problems with the C runtime library. Besides, + gzprintf(gzFile file, const char *format, ...) + cannot be translated into Pascal. + + +Legal issues +============ + +The zlibpas interface is: + Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler. + Copyright (C) 1998 by Bob Dellaca. + Copyright (C) 2003 by Cosmin Truta. + +The example program is: + Copyright (C) 1995-2003 by Jean-loup Gailly. + Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali. + Copyright (C) 2003 by Cosmin Truta. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/zlibd32.mak b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/zlibd32.mak new file mode 100644 index 00000000..9bb00b7c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/zlibd32.mak @@ -0,0 +1,99 @@ +# Makefile for zlib +# For use with Delphi and C++ Builder under Win32 +# Updated for zlib 1.2.x by Cosmin Truta + +# ------------ Borland C++ ------------ + +# This project uses the Delphi (fastcall/register) calling convention: +LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl + +CC = bcc32 +LD = bcc32 +AR = tlib +# do not use "-pr" in CFLAGS +CFLAGS = -a -d -k- -O2 $(LOC) +LDFLAGS = + + +# variables +ZLIB_LIB = zlib.lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# For the sake of the old Borland make, +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + + +# cleanup +clean: + -del *.obj + -del *.exe + -del *.lib + -del *.tds + -del zlib.bak + -del foo.gz + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/zlibpas.pas b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/zlibpas.pas new file mode 100644 index 00000000..5c9875c1 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/pascal/zlibpas.pas @@ -0,0 +1,276 @@ +(* zlibpas -- Pascal interface to the zlib data compression library + * + * Copyright (C) 2003 Cosmin Truta. + * Derived from original sources by Bob Dellaca. + * For conditions of distribution and use, see copyright notice in readme.txt + *) + +unit zlibpas; + +interface + +const + ZLIB_VERSION = '1.2.6'; + ZLIB_VERNUM = $1260; + +type + alloc_func = function(opaque: Pointer; items, size: Integer): Pointer; + cdecl; + free_func = procedure(opaque, address: Pointer); + cdecl; + + in_func = function(opaque: Pointer; var buf: PByte): Integer; + cdecl; + out_func = function(opaque: Pointer; buf: PByte; size: Integer): Integer; + cdecl; + + z_streamp = ^z_stream; + z_stream = packed record + next_in: PChar; (* next input byte *) + avail_in: Integer; (* number of bytes available at next_in *) + total_in: LongInt; (* total nb of input bytes read so far *) + + next_out: PChar; (* next output byte should be put there *) + avail_out: Integer; (* remaining free space at next_out *) + total_out: LongInt; (* total nb of bytes output so far *) + + msg: PChar; (* last error message, NULL if no error *) + state: Pointer; (* not visible by applications *) + + zalloc: alloc_func; (* used to allocate the internal state *) + zfree: free_func; (* used to free the internal state *) + opaque: Pointer; (* private data object passed to zalloc and zfree *) + + data_type: Integer; (* best guess about the data type: ascii or binary *) + adler: LongInt; (* adler32 value of the uncompressed data *) + reserved: LongInt; (* reserved for future use *) + end; + + gz_headerp = ^gz_header; + gz_header = packed record + text: Integer; (* true if compressed data believed to be text *) + time: LongInt; (* modification time *) + xflags: Integer; (* extra flags (not used when writing a gzip file) *) + os: Integer; (* operating system *) + extra: PChar; (* pointer to extra field or Z_NULL if none *) + extra_len: Integer; (* extra field length (valid if extra != Z_NULL) *) + extra_max: Integer; (* space at extra (only when reading header) *) + name: PChar; (* pointer to zero-terminated file name or Z_NULL *) + name_max: Integer; (* space at name (only when reading header) *) + comment: PChar; (* pointer to zero-terminated comment or Z_NULL *) + comm_max: Integer; (* space at comment (only when reading header) *) + hcrc: Integer; (* true if there was or will be a header crc *) + done: Integer; (* true when done reading gzip header *) + end; + +(* constants *) +const + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + Z_BLOCK = 5; + Z_TREES = 6; + + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = -1; + Z_STREAM_ERROR = -2; + Z_DATA_ERROR = -3; + Z_MEM_ERROR = -4; + Z_BUF_ERROR = -5; + Z_VERSION_ERROR = -6; + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = -1; + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_RLE = 3; + Z_FIXED = 4; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_TEXT = 1; + Z_ASCII = 1; + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + +(* basic functions *) +function zlibVersion: PChar; +function deflateInit(var strm: z_stream; level: Integer): Integer; +function deflate(var strm: z_stream; flush: Integer): Integer; +function deflateEnd(var strm: z_stream): Integer; +function inflateInit(var strm: z_stream): Integer; +function inflate(var strm: z_stream; flush: Integer): Integer; +function inflateEnd(var strm: z_stream): Integer; + +(* advanced functions *) +function deflateInit2(var strm: z_stream; level, method, windowBits, + memLevel, strategy: Integer): Integer; +function deflateSetDictionary(var strm: z_stream; const dictionary: PChar; + dictLength: Integer): Integer; +function deflateCopy(var dest, source: z_stream): Integer; +function deflateReset(var strm: z_stream): Integer; +function deflateParams(var strm: z_stream; level, strategy: Integer): Integer; +function deflateTune(var strm: z_stream; good_length, max_lazy, nice_length, max_chain: Integer): Integer; +function deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt; +function deflatePending(var strm: z_stream; var pending: Integer; var bits: Integer): Integer; +function deflatePrime(var strm: z_stream; bits, value: Integer): Integer; +function deflateSetHeader(var strm: z_stream; head: gz_header): Integer; +function inflateInit2(var strm: z_stream; windowBits: Integer): Integer; +function inflateSetDictionary(var strm: z_stream; const dictionary: PChar; + dictLength: Integer): Integer; +function inflateSync(var strm: z_stream): Integer; +function inflateCopy(var dest, source: z_stream): Integer; +function inflateReset(var strm: z_stream): Integer; +function inflateReset2(var strm: z_stream; windowBits: Integer): Integer; +function inflatePrime(var strm: z_stream; bits, value: Integer): Integer; +function inflateMark(var strm: z_stream): LongInt; +function inflateGetHeader(var strm: z_stream; var head: gz_header): Integer; +function inflateBackInit(var strm: z_stream; + windowBits: Integer; window: PChar): Integer; +function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer; + out_fn: out_func; out_desc: Pointer): Integer; +function inflateBackEnd(var strm: z_stream): Integer; +function zlibCompileFlags: LongInt; + +(* utility functions *) +function compress(dest: PChar; var destLen: LongInt; + const source: PChar; sourceLen: LongInt): Integer; +function compress2(dest: PChar; var destLen: LongInt; + const source: PChar; sourceLen: LongInt; + level: Integer): Integer; +function compressBound(sourceLen: LongInt): LongInt; +function uncompress(dest: PChar; var destLen: LongInt; + const source: PChar; sourceLen: LongInt): Integer; + +(* checksum functions *) +function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt; +function adler32_combine(adler1, adler2, len2: LongInt): LongInt; +function crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt; +function crc32_combine(crc1, crc2, len2: LongInt): LongInt; + +(* various hacks, don't look :) *) +function deflateInit_(var strm: z_stream; level: Integer; + const version: PChar; stream_size: Integer): Integer; +function inflateInit_(var strm: z_stream; const version: PChar; + stream_size: Integer): Integer; +function deflateInit2_(var strm: z_stream; + level, method, windowBits, memLevel, strategy: Integer; + const version: PChar; stream_size: Integer): Integer; +function inflateInit2_(var strm: z_stream; windowBits: Integer; + const version: PChar; stream_size: Integer): Integer; +function inflateBackInit_(var strm: z_stream; + windowBits: Integer; window: PChar; + const version: PChar; stream_size: Integer): Integer; + + +implementation + +{$L adler32.obj} +{$L compress.obj} +{$L crc32.obj} +{$L deflate.obj} +{$L infback.obj} +{$L inffast.obj} +{$L inflate.obj} +{$L inftrees.obj} +{$L trees.obj} +{$L uncompr.obj} +{$L zutil.obj} + +function adler32; external; +function adler32_combine; external; +function compress; external; +function compress2; external; +function compressBound; external; +function crc32; external; +function crc32_combine; external; +function deflate; external; +function deflateBound; external; +function deflateCopy; external; +function deflateEnd; external; +function deflateInit_; external; +function deflateInit2_; external; +function deflateParams; external; +function deflatePending; external; +function deflatePrime; external; +function deflateReset; external; +function deflateSetDictionary; external; +function deflateSetHeader; external; +function deflateTune; external; +function inflate; external; +function inflateBack; external; +function inflateBackEnd; external; +function inflateBackInit_; external; +function inflateCopy; external; +function inflateEnd; external; +function inflateGetHeader; external; +function inflateInit_; external; +function inflateInit2_; external; +function inflateMark; external; +function inflatePrime; external; +function inflateReset; external; +function inflateReset2; external; +function inflateSetDictionary; external; +function inflateSync; external; +function uncompress; external; +function zlibCompileFlags; external; +function zlibVersion; external; + +function deflateInit(var strm: z_stream; level: Integer): Integer; +begin + Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream)); +end; + +function deflateInit2(var strm: z_stream; level, method, windowBits, memLevel, + strategy: Integer): Integer; +begin + Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit(var strm: z_stream): Integer; +begin + Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit2(var strm: z_stream; windowBits: Integer): Integer; +begin + Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateBackInit(var strm: z_stream; + windowBits: Integer; window: PChar): Integer; +begin + Result := inflateBackInit_(strm, windowBits, window, + ZLIB_VERSION, sizeof(z_stream)); +end; + +function _malloc(Size: Integer): Pointer; cdecl; +begin + GetMem(Result, Size); +end; + +procedure _free(Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; +begin + FillChar(P^, count, B); +end; + +procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; +begin + Move(source^, dest^, count); +end; + +end. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/Makefile b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/Makefile new file mode 100644 index 00000000..0e2594c8 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/Makefile @@ -0,0 +1,42 @@ +CFLAGS=-O + +puff: puff.o pufftest.o + +puff.o: puff.h + +pufftest.o: puff.h + +test: puff + puff zeros.raw + +puft: puff.c puff.h pufftest.o + cc -fprofile-arcs -ftest-coverage -o puft puff.c pufftest.o + +# puff full coverage test (should say 100%) +cov: puft + @rm -f *.gcov *.gcda + @puft -w zeros.raw 2>&1 | cat > /dev/null + @echo '04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '00 00 00 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 254 + @echo '00 01 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '01 01 00 fe ff 0a' | xxd -r -p | puft -f 2>&1 | cat > /dev/null + @echo '02 7e ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246 + @echo '02' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2 + @echo '04 80 49 92 24 49 92 24 71 ff ff 93 11 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 249 + @echo '04 c0 81 08 00 00 00 00 20 7f eb 0b 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246 + @echo '0b 00 00' | xxd -r -p | puft -f 2>&1 | cat > /dev/null + @echo '1a 07' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246 + @echo '0c c0 81 00 00 00 00 00 90 ff 6b 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 245 + @puft -f zeros.raw 2>&1 | cat > /dev/null + @echo 'fc 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 253 + @echo '04 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 252 + @echo '04 00 24 49' | xxd -r -p | puft 2> /dev/null || test $$? -eq 251 + @echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 84' | xxd -r -p | puft 2> /dev/null || test $$? -eq 248 + @echo '04 00 24 e9 ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 250 + @echo '04 00 24 e9 ff 6d' | xxd -r -p | puft 2> /dev/null || test $$? -eq 247 + @gcov -n puff.c + +clean: + rm -f puff puft *.o *.gc* diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/README b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/README new file mode 100644 index 00000000..bbc4cb59 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/README @@ -0,0 +1,63 @@ +Puff -- A Simple Inflate +3 Mar 2003 +Mark Adler +madler@alumni.caltech.edu + +What this is -- + +puff.c provides the routine puff() to decompress the deflate data format. It +does so more slowly than zlib, but the code is about one-fifth the size of the +inflate code in zlib, and written to be very easy to read. + +Why I wrote this -- + +puff.c was written to document the deflate format unambiguously, by virtue of +being working C code. It is meant to supplement RFC 1951, which formally +describes the deflate format. I have received many questions on details of the +deflate format, and I hope that reading this code will answer those questions. +puff.c is heavily commented with details of the deflate format, especially +those little nooks and cranies of the format that might not be obvious from a +specification. + +puff.c may also be useful in applications where code size or memory usage is a +very limited resource, and speed is not as important. + +How to use it -- + +Well, most likely you should just be reading puff.c and using zlib for actual +applications, but if you must ... + +Include puff.h in your code, which provides this prototype: + +int puff(unsigned char *dest, /* pointer to destination pointer */ + unsigned long *destlen, /* amount of output space */ + unsigned char *source, /* pointer to source data pointer */ + unsigned long *sourcelen); /* amount of input available */ + +Then you can call puff() to decompress a deflate stream that is in memory in +its entirety at source, to a sufficiently sized block of memory for the +decompressed data at dest. puff() is the only external symbol in puff.c The +only C library functions that puff.c needs are setjmp() and longjmp(), which +are used to simplify error checking in the code to improve readabilty. puff.c +does no memory allocation, and uses less than 2K bytes off of the stack. + +If destlen is not enough space for the uncompressed data, then inflate will +return an error without writing more than destlen bytes. Note that this means +that in order to decompress the deflate data successfully, you need to know +the size of the uncompressed data ahead of time. + +If needed, puff() can determine the size of the uncompressed data with no +output space. This is done by passing dest equal to (unsigned char *)0. Then +the initial value of *destlen is ignored and *destlen is set to the length of +the uncompressed data. So if the size of the uncompressed data is not known, +then two passes of puff() can be used--first to determine the size, and second +to do the actual inflation after allocating the appropriate memory. Not +pretty, but it works. (This is one of the reasons you should be using zlib.) + +The deflate format is self-terminating. If the deflate stream does not end +in *sourcelen bytes, puff() will return an error without reading at or past +endsource. + +On return, *sourcelen is updated to the amount of input data consumed, and +*destlen is updated to the size of the uncompressed data. See the comments +in puff.c for the possible return codes for puff(). diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/puff.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/puff.c new file mode 100644 index 00000000..df8470c9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/puff.c @@ -0,0 +1,837 @@ +/* + * puff.c + * Copyright (C) 2002-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in puff.h + * version 2.2, 25 Apr 2010 + * + * puff.c is a simple inflate written to be an unambiguous way to specify the + * deflate format. It is not written for speed but rather simplicity. As a + * side benefit, this code might actually be useful when small code is more + * important than speed, such as bootstrap applications. For typical deflate + * data, zlib's inflate() is about four times as fast as puff(). zlib's + * inflate compiles to around 20K on my machine, whereas puff.c compiles to + * around 4K on my machine (a PowerPC using GNU cc). If the faster decode() + * function here is used, then puff() is only twice as slow as zlib's + * inflate(). + * + * All dynamically allocated memory comes from the stack. The stack required + * is less than 2K bytes. This code is compatible with 16-bit int's and + * assumes that long's are at least 32 bits. puff.c uses the short data type, + * assumed to be 16 bits, for arrays in order to to conserve memory. The code + * works whether integers are stored big endian or little endian. + * + * In the comments below are "Format notes" that describe the inflate process + * and document some of the less obvious aspects of the format. This source + * code is meant to supplement RFC 1951, which formally describes the deflate + * format: + * + * http://www.zlib.org/rfc-deflate.html + */ + +/* + * Change history: + * + * 1.0 10 Feb 2002 - First version + * 1.1 17 Feb 2002 - Clarifications of some comments and notes + * - Update puff() dest and source pointers on negative + * errors to facilitate debugging deflators + * - Remove longest from struct huffman -- not needed + * - Simplify offs[] index in construct() + * - Add input size and checking, using longjmp() to + * maintain easy readability + * - Use short data type for large arrays + * - Use pointers instead of long to specify source and + * destination sizes to avoid arbitrary 4 GB limits + * 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!), + * but leave simple version for readabilty + * - Make sure invalid distances detected if pointers + * are 16 bits + * - Fix fixed codes table error + * - Provide a scanning mode for determining size of + * uncompressed data + * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly] + * - Add a puff.h file for the interface + * - Add braces in puff() for else do [Gailly] + * - Use indexes instead of pointers for readability + * 1.4 31 Mar 2002 - Simplify construct() code set check + * - Fix some comments + * - Add FIXLCODES #define + * 1.5 6 Apr 2002 - Minor comment fixes + * 1.6 7 Aug 2002 - Minor format changes + * 1.7 3 Mar 2003 - Added test code for distribution + * - Added zlib-like license + * 1.8 9 Jan 2004 - Added some comments on no distance codes case + * 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland] + * - Catch missing end-of-block symbol error + * 2.0 25 Jul 2008 - Add #define to permit distance too far back + * - Add option in TEST code for puff to write the data + * - Add option in TEST code to skip input bytes + * - Allow TEST code to read from piped stdin + * 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers + * - Avoid unsigned comparisons for even happier compilers + * 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer] + * - Add const where appropriate [Oberhumer] + * - Split if's and ?'s for coverage testing + * - Break out test code to separate file + * - Move NIL to puff.h + * - Allow incomplete code only if single code length is 1 + * - Add full code coverage test to Makefile + */ + +#include /* for setjmp(), longjmp(), and jmp_buf */ +#include "puff.h" /* prototype for puff() */ + +#define local static /* for local function definitions */ + +/* + * Maximums for allocations and loops. It is not useful to change these -- + * they are fixed by the deflate format. + */ +#define MAXBITS 15 /* maximum bits in a code */ +#define MAXLCODES 286 /* maximum number of literal/length codes */ +#define MAXDCODES 30 /* maximum number of distance codes */ +#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */ +#define FIXLCODES 288 /* number of fixed literal/length codes */ + +/* input and output state */ +struct state { + /* output state */ + unsigned char *out; /* output buffer */ + unsigned long outlen; /* available space at out */ + unsigned long outcnt; /* bytes written to out so far */ + + /* input state */ + const unsigned char *in; /* input buffer */ + unsigned long inlen; /* available input at in */ + unsigned long incnt; /* bytes read so far */ + int bitbuf; /* bit buffer */ + int bitcnt; /* number of bits in bit buffer */ + + /* input limit error return state for bits() and decode() */ + jmp_buf env; +}; + +/* + * Return need bits from the input stream. This always leaves less than + * eight bits in the buffer. bits() works properly for need == 0. + * + * Format notes: + * + * - Bits are stored in bytes from the least significant bit to the most + * significant bit. Therefore bits are dropped from the bottom of the bit + * buffer, using shift right, and new bytes are appended to the top of the + * bit buffer, using shift left. + */ +local int bits(struct state *s, int need) +{ + long val; /* bit accumulator (can use up to 20 bits) */ + + /* load at least need bits into val */ + val = s->bitbuf; + while (s->bitcnt < need) { + if (s->incnt == s->inlen) + longjmp(s->env, 1); /* out of input */ + val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */ + s->bitcnt += 8; + } + + /* drop need bits and update buffer, always zero to seven bits left */ + s->bitbuf = (int)(val >> need); + s->bitcnt -= need; + + /* return need bits, zeroing the bits above that */ + return (int)(val & ((1L << need) - 1)); +} + +/* + * Process a stored block. + * + * Format notes: + * + * - After the two-bit stored block type (00), the stored block length and + * stored bytes are byte-aligned for fast copying. Therefore any leftover + * bits in the byte that has the last bit of the type, as many as seven, are + * discarded. The value of the discarded bits are not defined and should not + * be checked against any expectation. + * + * - The second inverted copy of the stored block length does not have to be + * checked, but it's probably a good idea to do so anyway. + * + * - A stored block can have zero length. This is sometimes used to byte-align + * subsets of the compressed data for random access or partial recovery. + */ +local int stored(struct state *s) +{ + unsigned len; /* length of stored block */ + + /* discard leftover bits from current byte (assumes s->bitcnt < 8) */ + s->bitbuf = 0; + s->bitcnt = 0; + + /* get length and check against its one's complement */ + if (s->incnt + 4 > s->inlen) + return 2; /* not enough input */ + len = s->in[s->incnt++]; + len |= s->in[s->incnt++] << 8; + if (s->in[s->incnt++] != (~len & 0xff) || + s->in[s->incnt++] != ((~len >> 8) & 0xff)) + return -2; /* didn't match complement! */ + + /* copy len bytes from in to out */ + if (s->incnt + len > s->inlen) + return 2; /* not enough input */ + if (s->out != NIL) { + if (s->outcnt + len > s->outlen) + return 1; /* not enough output space */ + while (len--) + s->out[s->outcnt++] = s->in[s->incnt++]; + } + else { /* just scanning */ + s->outcnt += len; + s->incnt += len; + } + + /* done with a valid stored block */ + return 0; +} + +/* + * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of + * each length, which for a canonical code are stepped through in order. + * symbol[] are the symbol values in canonical order, where the number of + * entries is the sum of the counts in count[]. The decoding process can be + * seen in the function decode() below. + */ +struct huffman { + short *count; /* number of symbols of each length */ + short *symbol; /* canonically ordered symbols */ +}; + +/* + * Decode a code from the stream s using huffman table h. Return the symbol or + * a negative value if there is an error. If all of the lengths are zero, i.e. + * an empty code, or if the code is incomplete and an invalid code is received, + * then -10 is returned after reading MAXBITS bits. + * + * Format notes: + * + * - The codes as stored in the compressed data are bit-reversed relative to + * a simple integer ordering of codes of the same lengths. Hence below the + * bits are pulled from the compressed data one at a time and used to + * build the code value reversed from what is in the stream in order to + * permit simple integer comparisons for decoding. A table-based decoding + * scheme (as used in zlib) does not need to do this reversal. + * + * - The first code for the shortest length is all zeros. Subsequent codes of + * the same length are simply integer increments of the previous code. When + * moving up a length, a zero bit is appended to the code. For a complete + * code, the last code of the longest length will be all ones. + * + * - Incomplete codes are handled by this decoder, since they are permitted + * in the deflate format. See the format notes for fixed() and dynamic(). + */ +#ifdef SLOW +local int decode(struct state *s, const struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + + code = first = index = 0; + for (len = 1; len <= MAXBITS; len++) { + code |= bits(s, 1); /* get next bit */ + count = h->count[len]; + if (code - count < first) /* if length len, return symbol */ + return h->symbol[index + (code - first)]; + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + } + return -10; /* ran out of codes */ +} + +/* + * A faster version of decode() for real applications of this code. It's not + * as readable, but it makes puff() twice as fast. And it only makes the code + * a few percent larger. + */ +#else /* !SLOW */ +local int decode(struct state *s, const struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + int bitbuf; /* bits from stream */ + int left; /* bits left in next or left to process */ + short *next; /* next number of codes */ + + bitbuf = s->bitbuf; + left = s->bitcnt; + code = first = index = 0; + len = 1; + next = h->count + 1; + while (1) { + while (left--) { + code |= bitbuf & 1; + bitbuf >>= 1; + count = *next++; + if (code - count < first) { /* if length len, return symbol */ + s->bitbuf = bitbuf; + s->bitcnt = (s->bitcnt - len) & 7; + return h->symbol[index + (code - first)]; + } + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + len++; + } + left = (MAXBITS+1) - len; + if (left == 0) + break; + if (s->incnt == s->inlen) + longjmp(s->env, 1); /* out of input */ + bitbuf = s->in[s->incnt++]; + if (left > 8) + left = 8; + } + return -10; /* ran out of codes */ +} +#endif /* SLOW */ + +/* + * Given the list of code lengths length[0..n-1] representing a canonical + * Huffman code for n symbols, construct the tables required to decode those + * codes. Those tables are the number of codes of each length, and the symbols + * sorted by length, retaining their original order within each length. The + * return value is zero for a complete code set, negative for an over- + * subscribed code set, and positive for an incomplete code set. The tables + * can be used if the return value is zero or positive, but they cannot be used + * if the return value is negative. If the return value is zero, it is not + * possible for decode() using that table to return an error--any stream of + * enough bits will resolve to a symbol. If the return value is positive, then + * it is possible for decode() using that table to return an error for received + * codes past the end of the incomplete lengths. + * + * Not used by decode(), but used for error checking, h->count[0] is the number + * of the n symbols not in the code. So n - h->count[0] is the number of + * codes. This is useful for checking for incomplete codes that have more than + * one symbol, which is an error in a dynamic block. + * + * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS + * This is assured by the construction of the length arrays in dynamic() and + * fixed() and is not verified by construct(). + * + * Format notes: + * + * - Permitted and expected examples of incomplete codes are one of the fixed + * codes and any code with a single symbol which in deflate is coded as one + * bit instead of zero bits. See the format notes for fixed() and dynamic(). + * + * - Within a given code length, the symbols are kept in ascending order for + * the code bits definition. + */ +local int construct(struct huffman *h, const short *length, int n) +{ + int symbol; /* current symbol when stepping through length[] */ + int len; /* current length when stepping through h->count[] */ + int left; /* number of possible codes left of current length */ + short offs[MAXBITS+1]; /* offsets in symbol table for each length */ + + /* count number of codes of each length */ + for (len = 0; len <= MAXBITS; len++) + h->count[len] = 0; + for (symbol = 0; symbol < n; symbol++) + (h->count[length[symbol]])++; /* assumes lengths are within bounds */ + if (h->count[0] == n) /* no codes! */ + return 0; /* complete, but decode() will fail */ + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; /* one possible code of zero length */ + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; /* one more bit, double codes left */ + left -= h->count[len]; /* deduct count from possible codes */ + if (left < 0) + return left; /* over-subscribed--return negative */ + } /* left > 0 means incomplete */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + h->count[len]; + + /* + * put symbols in table sorted by length, by symbol order within each + * length + */ + for (symbol = 0; symbol < n; symbol++) + if (length[symbol] != 0) + h->symbol[offs[length[symbol]]++] = symbol; + + /* return zero for complete set, positive for incomplete set */ + return left; +} + +/* + * Decode literal/length and distance codes until an end-of-block code. + * + * Format notes: + * + * - Compressed data that is after the block type if fixed or after the code + * description if dynamic is a combination of literals and length/distance + * pairs terminated by and end-of-block code. Literals are simply Huffman + * coded bytes. A length/distance pair is a coded length followed by a + * coded distance to represent a string that occurs earlier in the + * uncompressed data that occurs again at the current location. + * + * - Literals, lengths, and the end-of-block code are combined into a single + * code of up to 286 symbols. They are 256 literals (0..255), 29 length + * symbols (257..285), and the end-of-block symbol (256). + * + * - There are 256 possible lengths (3..258), and so 29 symbols are not enough + * to represent all of those. Lengths 3..10 and 258 are in fact represented + * by just a length symbol. Lengths 11..257 are represented as a symbol and + * some number of extra bits that are added as an integer to the base length + * of the length symbol. The number of extra bits is determined by the base + * length symbol. These are in the static arrays below, lens[] for the base + * lengths and lext[] for the corresponding number of extra bits. + * + * - The reason that 258 gets its own symbol is that the longest length is used + * often in highly redundant files. Note that 258 can also be coded as the + * base value 227 plus the maximum extra value of 31. While a good deflate + * should never do this, it is not an error, and should be decoded properly. + * + * - If a length is decoded, including its extra bits if any, then it is + * followed a distance code. There are up to 30 distance symbols. Again + * there are many more possible distances (1..32768), so extra bits are added + * to a base value represented by the symbol. The distances 1..4 get their + * own symbol, but the rest require extra bits. The base distances and + * corresponding number of extra bits are below in the static arrays dist[] + * and dext[]. + * + * - Literal bytes are simply written to the output. A length/distance pair is + * an instruction to copy previously uncompressed bytes to the output. The + * copy is from distance bytes back in the output stream, copying for length + * bytes. + * + * - Distances pointing before the beginning of the output data are not + * permitted. + * + * - Overlapped copies, where the length is greater than the distance, are + * allowed and common. For example, a distance of one and a length of 258 + * simply copies the last byte 258 times. A distance of four and a length of + * twelve copies the last four bytes three times. A simple forward copy + * ignoring whether the length is greater than the distance or not implements + * this correctly. You should not use memcpy() since its behavior is not + * defined for overlapped arrays. You should not use memmove() or bcopy() + * since though their behavior -is- defined for overlapping arrays, it is + * defined to do the wrong thing in this case. + */ +local int codes(struct state *s, + const struct huffman *lencode, + const struct huffman *distcode) +{ + int symbol; /* decoded symbol */ + int len; /* length for copy */ + unsigned dist; /* distance for copy */ + static const short lens[29] = { /* Size base for length codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; + static const short lext[29] = { /* Extra bits for length codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; + static const short dists[30] = { /* Offset base for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; + static const short dext[30] = { /* Extra bits for distance codes 0..29 */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + /* decode literals and length/distance pairs */ + do { + symbol = decode(s, lencode); + if (symbol < 0) + return symbol; /* invalid symbol */ + if (symbol < 256) { /* literal: symbol is the byte */ + /* write out the literal */ + if (s->out != NIL) { + if (s->outcnt == s->outlen) + return 1; + s->out[s->outcnt] = symbol; + } + s->outcnt++; + } + else if (symbol > 256) { /* length */ + /* get and compute length */ + symbol -= 257; + if (symbol >= 29) + return -10; /* invalid fixed code */ + len = lens[symbol] + bits(s, lext[symbol]); + + /* get and check distance */ + symbol = decode(s, distcode); + if (symbol < 0) + return symbol; /* invalid symbol */ + dist = dists[symbol] + bits(s, dext[symbol]); +#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (dist > s->outcnt) + return -11; /* distance too far back */ +#endif + + /* copy length bytes from distance bytes back */ + if (s->out != NIL) { + if (s->outcnt + len > s->outlen) + return 1; + while (len--) { + s->out[s->outcnt] = +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + dist > s->outcnt ? + 0 : +#endif + s->out[s->outcnt - dist]; + s->outcnt++; + } + } + else + s->outcnt += len; + } + } while (symbol != 256); /* end of block symbol */ + + /* done with a valid fixed or dynamic block */ + return 0; +} + +/* + * Process a fixed codes block. + * + * Format notes: + * + * - This block type can be useful for compressing small amounts of data for + * which the size of the code descriptions in a dynamic block exceeds the + * benefit of custom codes for that block. For fixed codes, no bits are + * spent on code descriptions. Instead the code lengths for literal/length + * codes and distance codes are fixed. The specific lengths for each symbol + * can be seen in the "for" loops below. + * + * - The literal/length code is complete, but has two symbols that are invalid + * and should result in an error if received. This cannot be implemented + * simply as an incomplete code since those two symbols are in the "middle" + * of the code. They are eight bits long and the longest literal/length\ + * code is nine bits. Therefore the code must be constructed with those + * symbols, and the invalid symbols must be detected after decoding. + * + * - The fixed distance codes also have two invalid symbols that should result + * in an error if received. Since all of the distance codes are the same + * length, this can be implemented as an incomplete code. Then the invalid + * codes are detected while decoding. + */ +local int fixed(struct state *s) +{ + static int virgin = 1; + static short lencnt[MAXBITS+1], lensym[FIXLCODES]; + static short distcnt[MAXBITS+1], distsym[MAXDCODES]; + static struct huffman lencode, distcode; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + int symbol; + short lengths[FIXLCODES]; + + /* construct lencode and distcode */ + lencode.count = lencnt; + lencode.symbol = lensym; + distcode.count = distcnt; + distcode.symbol = distsym; + + /* literal/length table */ + for (symbol = 0; symbol < 144; symbol++) + lengths[symbol] = 8; + for (; symbol < 256; symbol++) + lengths[symbol] = 9; + for (; symbol < 280; symbol++) + lengths[symbol] = 7; + for (; symbol < FIXLCODES; symbol++) + lengths[symbol] = 8; + construct(&lencode, lengths, FIXLCODES); + + /* distance table */ + for (symbol = 0; symbol < MAXDCODES; symbol++) + lengths[symbol] = 5; + construct(&distcode, lengths, MAXDCODES); + + /* do this just once */ + virgin = 0; + } + + /* decode data until end-of-block code */ + return codes(s, &lencode, &distcode); +} + +/* + * Process a dynamic codes block. + * + * Format notes: + * + * - A dynamic block starts with a description of the literal/length and + * distance codes for that block. New dynamic blocks allow the compressor to + * rapidly adapt to changing data with new codes optimized for that data. + * + * - The codes used by the deflate format are "canonical", which means that + * the actual bits of the codes are generated in an unambiguous way simply + * from the number of bits in each code. Therefore the code descriptions + * are simply a list of code lengths for each symbol. + * + * - The code lengths are stored in order for the symbols, so lengths are + * provided for each of the literal/length symbols, and for each of the + * distance symbols. + * + * - If a symbol is not used in the block, this is represented by a zero as + * as the code length. This does not mean a zero-length code, but rather + * that no code should be created for this symbol. There is no way in the + * deflate format to represent a zero-length code. + * + * - The maximum number of bits in a code is 15, so the possible lengths for + * any code are 1..15. + * + * - The fact that a length of zero is not permitted for a code has an + * interesting consequence. Normally if only one symbol is used for a given + * code, then in fact that code could be represented with zero bits. However + * in deflate, that code has to be at least one bit. So for example, if + * only a single distance base symbol appears in a block, then it will be + * represented by a single code of length one, in particular one 0 bit. This + * is an incomplete code, since if a 1 bit is received, it has no meaning, + * and should result in an error. So incomplete distance codes of one symbol + * should be permitted, and the receipt of invalid codes should be handled. + * + * - It is also possible to have a single literal/length code, but that code + * must be the end-of-block code, since every dynamic block has one. This + * is not the most efficient way to create an empty block (an empty fixed + * block is fewer bits), but it is allowed by the format. So incomplete + * literal/length codes of one symbol should also be permitted. + * + * - If there are only literal codes and no lengths, then there are no distance + * codes. This is represented by one distance code with zero bits. + * + * - The list of up to 286 length/literal lengths and up to 30 distance lengths + * are themselves compressed using Huffman codes and run-length encoding. In + * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means + * that length, and the symbols 16, 17, and 18 are run-length instructions. + * Each of 16, 17, and 18 are follwed by extra bits to define the length of + * the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10 + * zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols + * are common, hence the special coding for zero lengths. + * + * - The symbols for 0..18 are Huffman coded, and so that code must be + * described first. This is simply a sequence of up to 19 three-bit values + * representing no code (0) or the code length for that symbol (1..7). + * + * - A dynamic block starts with three fixed-size counts from which is computed + * the number of literal/length code lengths, the number of distance code + * lengths, and the number of code length code lengths (ok, you come up with + * a better name!) in the code descriptions. For the literal/length and + * distance codes, lengths after those provided are considered zero, i.e. no + * code. The code length code lengths are received in a permuted order (see + * the order[] array below) to make a short code length code length list more + * likely. As it turns out, very short and very long codes are less likely + * to be seen in a dynamic code description, hence what may appear initially + * to be a peculiar ordering. + * + * - Given the number of literal/length code lengths (nlen) and distance code + * lengths (ndist), then they are treated as one long list of nlen + ndist + * code lengths. Therefore run-length coding can and often does cross the + * boundary between the two sets of lengths. + * + * - So to summarize, the code description at the start of a dynamic block is + * three counts for the number of code lengths for the literal/length codes, + * the distance codes, and the code length codes. This is followed by the + * code length code lengths, three bits each. This is used to construct the + * code length code which is used to read the remainder of the lengths. Then + * the literal/length code lengths and distance lengths are read as a single + * set of lengths using the code length codes. Codes are constructed from + * the resulting two sets of lengths, and then finally you can start + * decoding actual compressed data in the block. + * + * - For reference, a "typical" size for the code description in a dynamic + * block is around 80 bytes. + */ +local int dynamic(struct state *s) +{ + int nlen, ndist, ncode; /* number of lengths in descriptor */ + int index; /* index of lengths[] */ + int err; /* construct() return value */ + short lengths[MAXCODES]; /* descriptor code lengths */ + short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */ + short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */ + struct huffman lencode, distcode; /* length and distance codes */ + static const short order[19] = /* permutation of code length codes */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* construct lencode and distcode */ + lencode.count = lencnt; + lencode.symbol = lensym; + distcode.count = distcnt; + distcode.symbol = distsym; + + /* get number of lengths in each table, check lengths */ + nlen = bits(s, 5) + 257; + ndist = bits(s, 5) + 1; + ncode = bits(s, 4) + 4; + if (nlen > MAXLCODES || ndist > MAXDCODES) + return -3; /* bad counts */ + + /* read code length code lengths (really), missing lengths are zero */ + for (index = 0; index < ncode; index++) + lengths[order[index]] = bits(s, 3); + for (; index < 19; index++) + lengths[order[index]] = 0; + + /* build huffman table for code lengths codes (use lencode temporarily) */ + err = construct(&lencode, lengths, 19); + if (err != 0) /* require complete code set here */ + return -4; + + /* read length/literal and distance code length tables */ + index = 0; + while (index < nlen + ndist) { + int symbol; /* decoded value */ + int len; /* last length to repeat */ + + symbol = decode(s, &lencode); + if (symbol < 16) /* length in 0..15 */ + lengths[index++] = symbol; + else { /* repeat instruction */ + len = 0; /* assume repeating zeros */ + if (symbol == 16) { /* repeat last length 3..6 times */ + if (index == 0) + return -5; /* no last length! */ + len = lengths[index - 1]; /* last length */ + symbol = 3 + bits(s, 2); + } + else if (symbol == 17) /* repeat zero 3..10 times */ + symbol = 3 + bits(s, 3); + else /* == 18, repeat zero 11..138 times */ + symbol = 11 + bits(s, 7); + if (index + symbol > nlen + ndist) + return -6; /* too many lengths! */ + while (symbol--) /* repeat last or zero symbol times */ + lengths[index++] = len; + } + } + + /* check for end-of-block code -- there better be one! */ + if (lengths[256] == 0) + return -9; + + /* build huffman table for literal/length codes */ + err = construct(&lencode, lengths, nlen); + if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1])) + return -7; /* incomplete code ok only for single length 1 code */ + + /* build huffman table for distance codes */ + err = construct(&distcode, lengths + nlen, ndist); + if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1])) + return -8; /* incomplete code ok only for single length 1 code */ + + /* decode data until end-of-block code */ + return codes(s, &lencode, &distcode); +} + +/* + * Inflate source to dest. On return, destlen and sourcelen are updated to the + * size of the uncompressed data and the size of the deflate data respectively. + * On success, the return value of puff() is zero. If there is an error in the + * source data, i.e. it is not in the deflate format, then a negative value is + * returned. If there is not enough input available or there is not enough + * output space, then a positive error is returned. In that case, destlen and + * sourcelen are not updated to facilitate retrying from the beginning with the + * provision of more input data or more output space. In the case of invalid + * inflate data (a negative error), the dest and source pointers are updated to + * facilitate the debugging of deflators. + * + * puff() also has a mode to determine the size of the uncompressed output with + * no output written. For this dest must be (unsigned char *)0. In this case, + * the input value of *destlen is ignored, and on return *destlen is set to the + * size of the uncompressed output. + * + * The return codes are: + * + * 2: available inflate data did not terminate + * 1: output space exhausted before completing inflate + * 0: successful inflate + * -1: invalid block type (type == 3) + * -2: stored block length did not match one's complement + * -3: dynamic block code description: too many length or distance codes + * -4: dynamic block code description: code lengths codes incomplete + * -5: dynamic block code description: repeat lengths with no first length + * -6: dynamic block code description: repeat more than specified lengths + * -7: dynamic block code description: invalid literal/length code lengths + * -8: dynamic block code description: invalid distance code lengths + * -9: dynamic block code description: missing end-of-block code + * -10: invalid literal/length or distance code in fixed or dynamic block + * -11: distance is too far back in fixed or dynamic block + * + * Format notes: + * + * - Three bits are read for each block to determine the kind of block and + * whether or not it is the last block. Then the block is decoded and the + * process repeated if it was not the last block. + * + * - The leftover bits in the last byte of the deflate data after the last + * block (if it was a fixed or dynamic block) are undefined and have no + * expected values to check. + */ +int puff(unsigned char *dest, /* pointer to destination pointer */ + unsigned long *destlen, /* amount of output space */ + const unsigned char *source, /* pointer to source data pointer */ + unsigned long *sourcelen) /* amount of input available */ +{ + struct state s; /* input/output state */ + int last, type; /* block information */ + int err; /* return value */ + + /* initialize output state */ + s.out = dest; + s.outlen = *destlen; /* ignored if dest is NIL */ + s.outcnt = 0; + + /* initialize input state */ + s.in = source; + s.inlen = *sourcelen; + s.incnt = 0; + s.bitbuf = 0; + s.bitcnt = 0; + + /* return if bits() or decode() tries to read past available input */ + if (setjmp(s.env) != 0) /* if came back here via longjmp() */ + err = 2; /* then skip do-loop, return error */ + else { + /* process blocks until last block or error */ + do { + last = bits(&s, 1); /* one if last block */ + type = bits(&s, 2); /* block type 0..3 */ + err = type == 0 ? + stored(&s) : + (type == 1 ? + fixed(&s) : + (type == 2 ? + dynamic(&s) : + -1)); /* type == 3, invalid */ + if (err != 0) + break; /* return with error */ + } while (!last); + } + + /* update the lengths and return */ + if (err <= 0) { + *destlen = s.outcnt; + *sourcelen = s.incnt; + } + return err; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/puff.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/puff.h new file mode 100644 index 00000000..6a0080ae --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/puff.h @@ -0,0 +1,35 @@ +/* puff.h + Copyright (C) 2002-2010 Mark Adler, all rights reserved + version 2.2, 25 Apr 2010 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + + +/* + * See puff.c for purpose and usage. + */ +#ifndef NIL +# define NIL ((unsigned char *)0) /* for no output option */ +#endif + +int puff(unsigned char *dest, /* pointer to destination pointer */ + unsigned long *destlen, /* amount of output space */ + const unsigned char *source, /* pointer to source data pointer */ + unsigned long *sourcelen); /* amount of input available */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/pufftest.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/pufftest.c new file mode 100644 index 00000000..76e35f66 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/pufftest.c @@ -0,0 +1,165 @@ +/* + * pufftest.c + * Copyright (C) 2002-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in puff.h + * version 2.2, 25 Apr 2010 + */ + +/* Example of how to use puff(). + + Usage: puff [-w] [-f] [-nnn] file + ... | puff [-w] [-f] [-nnn] + + where file is the input file with deflate data, nnn is the number of bytes + of input to skip before inflating (e.g. to skip a zlib or gzip header), and + -w is used to write the decompressed data to stdout. -f is for coverage + testing, and causes pufftest to fail with not enough output space (-f does + a write like -w, so -w is not required). */ + +#include +#include +#include "puff.h" + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#define local static + +/* Return size times approximately the cube root of 2, keeping the result as 1, + 3, or 5 times a power of 2 -- the result is always > size, until the result + is the maximum value of an unsigned long, where it remains. This is useful + to keep reallocations less than ~33% over the actual data. */ +local size_t bythirds(size_t size) +{ + int n; + size_t m; + + m = size; + for (n = 0; m; n++) + m >>= 1; + if (n < 3) + return size + 1; + n -= 3; + m = size >> n; + m += m == 6 ? 2 : 1; + m <<= n; + return m > size ? m : (size_t)(-1); +} + +/* Read the input file *name, or stdin if name is NULL, into allocated memory. + Reallocate to larger buffers until the entire file is read in. Return a + pointer to the allocated data, or NULL if there was a memory allocation + failure. *len is the number of bytes of data read from the input file (even + if load() returns NULL). If the input file was empty or could not be opened + or read, *len is zero. */ +local void *load(const char *name, size_t *len) +{ + size_t size; + void *buf, *swap; + FILE *in; + + *len = 0; + buf = malloc(size = 4096); + if (buf == NULL) + return NULL; + in = name == NULL ? stdin : fopen(name, "rb"); + if (in != NULL) { + for (;;) { + *len += fread((char *)buf + *len, 1, size - *len, in); + if (*len < size) break; + size = bythirds(size); + if (size == *len || (swap = realloc(buf, size)) == NULL) { + free(buf); + buf = NULL; + break; + } + buf = swap; + } + fclose(in); + } + return buf; +} + +int main(int argc, char **argv) +{ + int ret, put = 0, fail = 0; + unsigned skip = 0; + char *arg, *name = NULL; + unsigned char *source = NULL, *dest; + size_t len = 0; + unsigned long sourcelen, destlen; + + /* process arguments */ + while (arg = *++argv, --argc) + if (arg[0] == '-') { + if (arg[1] == 'w' && arg[2] == 0) + put = 1; + else if (arg[1] == 'f' && arg[2] == 0) + fail = 1, put = 1; + else if (arg[1] >= '0' && arg[1] <= '9') + skip = (unsigned)atoi(arg + 1); + else { + fprintf(stderr, "invalid option %s\n", arg); + return 3; + } + } + else if (name != NULL) { + fprintf(stderr, "only one file name allowed\n"); + return 3; + } + else + name = arg; + source = load(name, &len); + if (source == NULL) { + fprintf(stderr, "memory allocation failure\n"); + return 4; + } + if (len == 0) { + fprintf(stderr, "could not read %s, or it was empty\n", + name == NULL ? "" : name); + free(source); + return 3; + } + if (skip >= len) { + fprintf(stderr, "skip request of %d leaves no input\n", skip); + free(source); + return 3; + } + + /* test inflate data with offset skip */ + len -= skip; + sourcelen = (unsigned long)len; + ret = puff(NIL, &destlen, source + skip, &sourcelen); + if (ret) + fprintf(stderr, "puff() failed with return code %d\n", ret); + else { + fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen); + if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n", + len - sourcelen); + } + + /* if requested, inflate again and write decompressd data to stdout */ + if (put && ret == 0) { + if (fail) + destlen >>= 1; + dest = malloc(destlen); + if (dest == NULL) { + fprintf(stderr, "memory allocation failure\n"); + free(source); + return 4; + } + puff(dest, &destlen, source + skip, &sourcelen); + SET_BINARY_MODE(stdout); + fwrite(dest, 1, destlen, stdout); + free(dest); + } + + /* clean up */ + free(source); + return ret; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/zeros.raw b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/zeros.raw new file mode 100644 index 00000000..0a90e76b Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/puff/zeros.raw differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/testzlib/testzlib.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/testzlib/testzlib.c new file mode 100644 index 00000000..135888eb --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/testzlib/testzlib.c @@ -0,0 +1,275 @@ +#include +#include +#include + +#include "zlib.h" + + +void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B) +{ + R->HighPart = A.HighPart - B.HighPart; + if (A.LowPart >= B.LowPart) + R->LowPart = A.LowPart - B.LowPart; + else + { + R->LowPart = A.LowPart - B.LowPart; + R->HighPart --; + } +} + +#ifdef _M_X64 +// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc +unsigned __int64 __rdtsc(void); +void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) +{ + // printf("rdtsc = %I64x\n",__rdtsc()); + pbeginTime64->QuadPart=__rdtsc(); +} + +LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER LIres; + unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart)); + LIres.QuadPart=res; + // printf("rdtsc = %I64x\n",__rdtsc()); + return LIres; +} +#else +#ifdef _M_IX86 +void myGetRDTSC32(LARGE_INTEGER * pbeginTime64) +{ + DWORD dwEdx,dwEax; + _asm + { + rdtsc + mov dwEax,eax + mov dwEdx,edx + } + pbeginTime64->LowPart=dwEax; + pbeginTime64->HighPart=dwEdx; +} + +void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) +{ + myGetRDTSC32(pbeginTime64); +} + +LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER LIres,endTime64; + myGetRDTSC32(&endTime64); + + LIres.LowPart=LIres.HighPart=0; + MyDoMinus64(&LIres,endTime64,beginTime64); + return LIres; +} +#else +void myGetRDTSC32(LARGE_INTEGER * pbeginTime64) +{ +} + +void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) +{ +} + +LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER lr; + lr.QuadPart=0; + return lr; +} +#endif +#endif + +void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf) +{ + if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64))) + { + pbeginTime64->LowPart = GetTickCount(); + pbeginTime64->HighPart = 0; + } +} + +DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER endTime64,ticksPerSecond,ticks; + DWORDLONG ticksShifted,tickSecShifted; + DWORD dwLog=16+0; + DWORD dwRet; + if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64))) + dwRet = (GetTickCount() - beginTime64.LowPart)*1; + else + { + MyDoMinus64(&ticks,endTime64,beginTime64); + QueryPerformanceFrequency(&ticksPerSecond); + + + { + ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog); + tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog); + + } + + dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted)); + dwRet *=1; + } + return dwRet; +} + +int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr) +{ + FILE* stream; + void* ptr; + int retVal=1; + stream=fopen(filename, "rb"); + if (stream==NULL) + return 0; + + fseek(stream,0,SEEK_END); + + *plFileSize=ftell(stream); + fseek(stream,0,SEEK_SET); + ptr=malloc((*plFileSize)+1); + if (ptr==NULL) + retVal=0; + else + { + if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize)) + retVal=0; + } + fclose(stream); + *pFilePtr=ptr; + return retVal; +} + +int main(int argc, char *argv[]) +{ + int BlockSizeCompress=0x8000; + int BlockSizeUncompress=0x8000; + int cprLevel=Z_DEFAULT_COMPRESSION ; + long lFileSize; + unsigned char* FilePtr; + long lBufferSizeCpr; + long lBufferSizeUncpr; + long lCompressedSize=0; + unsigned char* CprPtr; + unsigned char* UncprPtr; + long lSizeCpr,lSizeUncpr; + DWORD dwGetTick,dwMsecQP; + LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc; + + if (argc<=1) + { + printf("run TestZlib [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n"); + return 0; + } + + if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0) + { + printf("error reading %s\n",argv[1]); + return 1; + } + else printf("file %s read, %u bytes\n",argv[1],lFileSize); + + if (argc>=3) + BlockSizeCompress=atol(argv[2]); + + if (argc>=4) + BlockSizeUncompress=atol(argv[3]); + + if (argc>=5) + cprLevel=(int)atol(argv[4]); + + lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200; + lBufferSizeUncpr = lBufferSizeCpr; + + CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress); + + BeginCountPerfCounter(&li_qp,TRUE); + dwGetTick=GetTickCount(); + BeginCountRdtsc(&li_rdtsc); + { + z_stream zcpr; + int ret=Z_OK; + long lOrigToDo = lFileSize; + long lOrigDone = 0; + int step=0; + memset(&zcpr,0,sizeof(z_stream)); + deflateInit(&zcpr,cprLevel); + + zcpr.next_in = FilePtr; + zcpr.next_out = CprPtr; + + + do + { + long all_read_before = zcpr.total_in; + zcpr.avail_in = min(lOrigToDo,BlockSizeCompress); + zcpr.avail_out = BlockSizeCompress; + ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH); + lOrigDone += (zcpr.total_in-all_read_before); + lOrigToDo -= (zcpr.total_in-all_read_before); + step++; + } while (ret==Z_OK); + + lSizeCpr=zcpr.total_out; + deflateEnd(&zcpr); + dwGetTick=GetTickCount()-dwGetTick; + dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE); + dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE); + printf("total compress size = %u, in %u step\n",lSizeCpr,step); + printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.); + printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.); + printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart); + } + + CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr); + UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress); + + BeginCountPerfCounter(&li_qp,TRUE); + dwGetTick=GetTickCount(); + BeginCountRdtsc(&li_rdtsc); + { + z_stream zcpr; + int ret=Z_OK; + long lOrigToDo = lSizeCpr; + long lOrigDone = 0; + int step=0; + memset(&zcpr,0,sizeof(z_stream)); + inflateInit(&zcpr); + + zcpr.next_in = CprPtr; + zcpr.next_out = UncprPtr; + + + do + { + long all_read_before = zcpr.total_in; + zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress); + zcpr.avail_out = BlockSizeUncompress; + ret=inflate(&zcpr,Z_SYNC_FLUSH); + lOrigDone += (zcpr.total_in-all_read_before); + lOrigToDo -= (zcpr.total_in-all_read_before); + step++; + } while (ret==Z_OK); + + lSizeUncpr=zcpr.total_out; + inflateEnd(&zcpr); + dwGetTick=GetTickCount()-dwGetTick; + dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE); + dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE); + printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step); + printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.); + printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.); + printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart); + } + + if (lSizeUncpr==lFileSize) + { + if (memcmp(FilePtr,UncprPtr,lFileSize)==0) + printf("compare ok\n"); + + } + + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/testzlib/testzlib.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/testzlib/testzlib.txt new file mode 100644 index 00000000..62258f14 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/testzlib/testzlib.txt @@ -0,0 +1,10 @@ +To build testzLib with Visual Studio 2005: + +copy to a directory file from : +- root of zLib tree +- contrib/testzlib +- contrib/masmx86 +- contrib/masmx64 +- contrib/vstudio/vc7 + +and open testzlib8.sln \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/untgz/Makefile b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/untgz/Makefile new file mode 100644 index 00000000..b54266fb --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/untgz/Makefile @@ -0,0 +1,14 @@ +CC=cc +CFLAGS=-g + +untgz: untgz.o ../../libz.a + $(CC) $(CFLAGS) -o untgz untgz.o -L../.. -lz + +untgz.o: untgz.c ../../zlib.h + $(CC) $(CFLAGS) -c -I../.. untgz.c + +../../libz.a: + cd ../..; ./configure; make + +clean: + rm -f untgz untgz.o *~ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/untgz/Makefile.msc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/untgz/Makefile.msc new file mode 100644 index 00000000..77b86022 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/untgz/Makefile.msc @@ -0,0 +1,17 @@ +CC=cl +CFLAGS=-MD + +untgz.exe: untgz.obj ..\..\zlib.lib + $(CC) $(CFLAGS) untgz.obj ..\..\zlib.lib + +untgz.obj: untgz.c ..\..\zlib.h + $(CC) $(CFLAGS) -c -I..\.. untgz.c + +..\..\zlib.lib: + cd ..\.. + $(MAKE) -f win32\makefile.msc + cd contrib\untgz + +clean: + -del untgz.obj + -del untgz.exe diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/untgz/untgz.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/untgz/untgz.c new file mode 100644 index 00000000..2c391e59 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/untgz/untgz.c @@ -0,0 +1,674 @@ +/* + * untgz.c -- Display contents and extract files from a gzip'd TAR file + * + * written by Pedro A. Aranda Gutierrez + * adaptation to Unix by Jean-loup Gailly + * various fixes by Cosmin Truta + */ + +#include +#include +#include +#include +#include + +#include "zlib.h" + +#ifdef unix +# include +#else +# include +# include +#endif + +#ifdef WIN32 +#include +# ifndef F_OK +# define F_OK 0 +# endif +# define mkdir(dirname,mode) _mkdir(dirname) +# ifdef _MSC_VER +# define access(path,mode) _access(path,mode) +# define chmod(path,mode) _chmod(path,mode) +# define strdup(str) _strdup(str) +# endif +#else +# include +#endif + + +/* values used in typeflag field */ + +#define REGTYPE '0' /* regular file */ +#define AREGTYPE '\0' /* regular file */ +#define LNKTYPE '1' /* link */ +#define SYMTYPE '2' /* reserved */ +#define CHRTYPE '3' /* character special */ +#define BLKTYPE '4' /* block special */ +#define DIRTYPE '5' /* directory */ +#define FIFOTYPE '6' /* FIFO special */ +#define CONTTYPE '7' /* reserved */ + +/* GNU tar extensions */ + +#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */ +#define GNUTYPE_LONGLINK 'K' /* long link name */ +#define GNUTYPE_LONGNAME 'L' /* long file name */ +#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */ +#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */ +#define GNUTYPE_SPARSE 'S' /* sparse file */ +#define GNUTYPE_VOLHDR 'V' /* tape/volume header */ + + +/* tar header */ + +#define BLOCKSIZE 512 +#define SHORTNAMESIZE 100 + +struct tar_header +{ /* byte offset */ + char name[100]; /* 0 */ + char mode[8]; /* 100 */ + char uid[8]; /* 108 */ + char gid[8]; /* 116 */ + char size[12]; /* 124 */ + char mtime[12]; /* 136 */ + char chksum[8]; /* 148 */ + char typeflag; /* 156 */ + char linkname[100]; /* 157 */ + char magic[6]; /* 257 */ + char version[2]; /* 263 */ + char uname[32]; /* 265 */ + char gname[32]; /* 297 */ + char devmajor[8]; /* 329 */ + char devminor[8]; /* 337 */ + char prefix[155]; /* 345 */ + /* 500 */ +}; + +union tar_buffer +{ + char buffer[BLOCKSIZE]; + struct tar_header header; +}; + +struct attr_item +{ + struct attr_item *next; + char *fname; + int mode; + time_t time; +}; + +enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID }; + +char *TGZfname OF((const char *)); +void TGZnotfound OF((const char *)); + +int getoct OF((char *, int)); +char *strtime OF((time_t *)); +int setfiletime OF((char *, time_t)); +void push_attr OF((struct attr_item **, char *, int, time_t)); +void restore_attr OF((struct attr_item **)); + +int ExprMatch OF((char *, char *)); + +int makedir OF((char *)); +int matchname OF((int, int, char **, char *)); + +void error OF((const char *)); +int tar OF((gzFile, int, int, int, char **)); + +void help OF((int)); +int main OF((int, char **)); + +char *prog; + +const char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL }; + +/* return the file name of the TGZ archive */ +/* or NULL if it does not exist */ + +char *TGZfname (const char *arcname) +{ + static char buffer[1024]; + int origlen,i; + + strcpy(buffer,arcname); + origlen = strlen(buffer); + + for (i=0; TGZsuffix[i]; i++) + { + strcpy(buffer+origlen,TGZsuffix[i]); + if (access(buffer,F_OK) == 0) + return buffer; + } + return NULL; +} + + +/* error message for the filename */ + +void TGZnotfound (const char *arcname) +{ + int i; + + fprintf(stderr,"%s: Couldn't find ",prog); + for (i=0;TGZsuffix[i];i++) + fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n", + arcname, + TGZsuffix[i]); + exit(1); +} + + +/* convert octal digits to int */ +/* on error return -1 */ + +int getoct (char *p,int width) +{ + int result = 0; + char c; + + while (width--) + { + c = *p++; + if (c == 0) + break; + if (c == ' ') + continue; + if (c < '0' || c > '7') + return -1; + result = result * 8 + (c - '0'); + } + return result; +} + + +/* convert time_t to string */ +/* use the "YYYY/MM/DD hh:mm:ss" format */ + +char *strtime (time_t *t) +{ + struct tm *local; + static char result[32]; + + local = localtime(t); + sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d", + local->tm_year+1900, local->tm_mon+1, local->tm_mday, + local->tm_hour, local->tm_min, local->tm_sec); + return result; +} + + +/* set file time */ + +int setfiletime (char *fname,time_t ftime) +{ +#ifdef WIN32 + static int isWinNT = -1; + SYSTEMTIME st; + FILETIME locft, modft; + struct tm *loctm; + HANDLE hFile; + int result; + + loctm = localtime(&ftime); + if (loctm == NULL) + return -1; + + st.wYear = (WORD)loctm->tm_year + 1900; + st.wMonth = (WORD)loctm->tm_mon + 1; + st.wDayOfWeek = (WORD)loctm->tm_wday; + st.wDay = (WORD)loctm->tm_mday; + st.wHour = (WORD)loctm->tm_hour; + st.wMinute = (WORD)loctm->tm_min; + st.wSecond = (WORD)loctm->tm_sec; + st.wMilliseconds = 0; + if (!SystemTimeToFileTime(&st, &locft) || + !LocalFileTimeToFileTime(&locft, &modft)) + return -1; + + if (isWinNT < 0) + isWinNT = (GetVersion() < 0x80000000) ? 1 : 0; + hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0), + NULL); + if (hFile == INVALID_HANDLE_VALUE) + return -1; + result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1; + CloseHandle(hFile); + return result; +#else + struct utimbuf settime; + + settime.actime = settime.modtime = ftime; + return utime(fname,&settime); +#endif +} + + +/* push file attributes */ + +void push_attr(struct attr_item **list,char *fname,int mode,time_t time) +{ + struct attr_item *item; + + item = (struct attr_item *)malloc(sizeof(struct attr_item)); + if (item == NULL) + error("Out of memory"); + item->fname = strdup(fname); + item->mode = mode; + item->time = time; + item->next = *list; + *list = item; +} + + +/* restore file attributes */ + +void restore_attr(struct attr_item **list) +{ + struct attr_item *item, *prev; + + for (item = *list; item != NULL; ) + { + setfiletime(item->fname,item->time); + chmod(item->fname,item->mode); + prev = item; + item = item->next; + free(prev); + } + *list = NULL; +} + + +/* match regular expression */ + +#define ISSPECIAL(c) (((c) == '*') || ((c) == '/')) + +int ExprMatch (char *string,char *expr) +{ + while (1) + { + if (ISSPECIAL(*expr)) + { + if (*expr == '/') + { + if (*string != '\\' && *string != '/') + return 0; + string ++; expr++; + } + else if (*expr == '*') + { + if (*expr ++ == 0) + return 1; + while (*++string != *expr) + if (*string == 0) + return 0; + } + } + else + { + if (*string != *expr) + return 0; + if (*expr++ == 0) + return 1; + string++; + } + } +} + + +/* recursive mkdir */ +/* abort on ENOENT; ignore other errors like "directory already exists" */ +/* return 1 if OK */ +/* 0 on error */ + +int makedir (char *newdir) +{ + char *buffer = strdup(newdir); + char *p; + int len = strlen(buffer); + + if (len <= 0) { + free(buffer); + return 0; + } + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mkdir(buffer, 0755) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT)) + { + fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + + +int matchname (int arg,int argc,char **argv,char *fname) +{ + if (arg == argc) /* no arguments given (untgz tgzarchive) */ + return 1; + + while (arg < argc) + if (ExprMatch(fname,argv[arg++])) + return 1; + + return 0; /* ignore this for the moment being */ +} + + +/* tar file list or extract */ + +int tar (gzFile in,int action,int arg,int argc,char **argv) +{ + union tar_buffer buffer; + int len; + int err; + int getheader = 1; + int remaining = 0; + FILE *outfile = NULL; + char fname[BLOCKSIZE]; + int tarmode; + time_t tartime; + struct attr_item *attributes = NULL; + + if (action == TGZ_LIST) + printf(" date time size file\n" + " ---------- -------- --------- -------------------------------------\n"); + while (1) + { + len = gzread(in, &buffer, BLOCKSIZE); + if (len < 0) + error(gzerror(in, &err)); + /* + * Always expect complete blocks to process + * the tar information. + */ + if (len != BLOCKSIZE) + { + action = TGZ_INVALID; /* force error exit */ + remaining = 0; /* force I/O cleanup */ + } + + /* + * If we have to get a tar header + */ + if (getheader >= 1) + { + /* + * if we met the end of the tar + * or the end-of-tar block, + * we are done + */ + if (len == 0 || buffer.header.name[0] == 0) + break; + + tarmode = getoct(buffer.header.mode,8); + tartime = (time_t)getoct(buffer.header.mtime,12); + if (tarmode == -1 || tartime == (time_t)-1) + { + buffer.header.name[0] = 0; + action = TGZ_INVALID; + } + + if (getheader == 1) + { + strncpy(fname,buffer.header.name,SHORTNAMESIZE); + if (fname[SHORTNAMESIZE-1] != 0) + fname[SHORTNAMESIZE] = 0; + } + else + { + /* + * The file name is longer than SHORTNAMESIZE + */ + if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0) + error("bad long name"); + getheader = 1; + } + + /* + * Act according to the type flag + */ + switch (buffer.header.typeflag) + { + case DIRTYPE: + if (action == TGZ_LIST) + printf(" %s %s\n",strtime(&tartime),fname); + if (action == TGZ_EXTRACT) + { + makedir(fname); + push_attr(&attributes,fname,tarmode,tartime); + } + break; + case REGTYPE: + case AREGTYPE: + remaining = getoct(buffer.header.size,12); + if (remaining == -1) + { + action = TGZ_INVALID; + break; + } + if (action == TGZ_LIST) + printf(" %s %9d %s\n",strtime(&tartime),remaining,fname); + else if (action == TGZ_EXTRACT) + { + if (matchname(arg,argc,argv,fname)) + { + outfile = fopen(fname,"wb"); + if (outfile == NULL) { + /* try creating directory */ + char *p = strrchr(fname, '/'); + if (p != NULL) { + *p = '\0'; + makedir(fname); + *p = '/'; + outfile = fopen(fname,"wb"); + } + } + if (outfile != NULL) + printf("Extracting %s\n",fname); + else + fprintf(stderr, "%s: Couldn't create %s",prog,fname); + } + else + outfile = NULL; + } + getheader = 0; + break; + case GNUTYPE_LONGLINK: + case GNUTYPE_LONGNAME: + remaining = getoct(buffer.header.size,12); + if (remaining < 0 || remaining >= BLOCKSIZE) + { + action = TGZ_INVALID; + break; + } + len = gzread(in, fname, BLOCKSIZE); + if (len < 0) + error(gzerror(in, &err)); + if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining) + { + action = TGZ_INVALID; + break; + } + getheader = 2; + break; + default: + if (action == TGZ_LIST) + printf(" %s <---> %s\n",strtime(&tartime),fname); + break; + } + } + else + { + unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining; + + if (outfile != NULL) + { + if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) + { + fprintf(stderr, + "%s: Error writing %s -- skipping\n",prog,fname); + fclose(outfile); + outfile = NULL; + remove(fname); + } + } + remaining -= bytes; + } + + if (remaining == 0) + { + getheader = 1; + if (outfile != NULL) + { + fclose(outfile); + outfile = NULL; + if (action != TGZ_INVALID) + push_attr(&attributes,fname,tarmode,tartime); + } + } + + /* + * Abandon if errors are found + */ + if (action == TGZ_INVALID) + { + error("broken archive"); + break; + } + } + + /* + * Restore file modes and time stamps + */ + restore_attr(&attributes); + + if (gzclose(in) != Z_OK) + error("failed gzclose"); + + return 0; +} + + +/* ============================================================ */ + +void help(int exitval) +{ + printf("untgz version 0.2.1\n" + " using zlib version %s\n\n", + zlibVersion()); + printf("Usage: untgz file.tgz extract all files\n" + " untgz file.tgz fname ... extract selected files\n" + " untgz -l file.tgz list archive contents\n" + " untgz -h display this help\n"); + exit(exitval); +} + +void error(const char *msg) +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + + +/* ============================================================ */ + +#if defined(WIN32) && defined(__GNUC__) +int _CRT_glob = 0; /* disable argument globbing in MinGW */ +#endif + +int main(int argc,char **argv) +{ + int action = TGZ_EXTRACT; + int arg = 1; + char *TGZfile; + gzFile *f; + + prog = strrchr(argv[0],'\\'); + if (prog == NULL) + { + prog = strrchr(argv[0],'/'); + if (prog == NULL) + { + prog = strrchr(argv[0],':'); + if (prog == NULL) + prog = argv[0]; + else + prog++; + } + else + prog++; + } + else + prog++; + + if (argc == 1) + help(0); + + if (strcmp(argv[arg],"-l") == 0) + { + action = TGZ_LIST; + if (argc == ++arg) + help(0); + } + else if (strcmp(argv[arg],"-h") == 0) + { + help(0); + } + + if ((TGZfile = TGZfname(argv[arg])) == NULL) + TGZnotfound(argv[arg]); + + ++arg; + if ((action == TGZ_LIST) && (arg != argc)) + help(1); + +/* + * Process the TGZ file + */ + switch(action) + { + case TGZ_LIST: + case TGZ_EXTRACT: + f = gzopen(TGZfile,"rb"); + if (f == NULL) + { + fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile); + return 1; + } + exit(tar(f, action, arg, argc, argv)); + break; + + default: + error("Unknown option"); + exit(1); + } + + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/readme.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/readme.txt new file mode 100644 index 00000000..904888ba --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/readme.txt @@ -0,0 +1,60 @@ +Building instructions for the DLL versions of Zlib 1.2.4 +======================================================== + +This directory contains projects that build zlib and minizip using +Microsoft Visual C++ 9.0/10.0, and Visual C++ . + +You don't need to build these projects yourself. You can download the +binaries from: + http://www.winimage.com/zLibDll + +More information can be found at this site. + +first compile assembly code by running +bld_ml64.bat in contrib\masmx64 +bld_ml32.bat in contrib\masmx86 + + + + +Build instructions for Visual Studio 2008 (32 bits or 64 bits) +-------------------------------------------------------------- +- Uncompress current zlib, including all contrib/* files +- Open contrib\vstudio\vc9\zlibvc.sln with Microsoft Visual C++ 2008.0 +- Or run: vcbuild /rebuild contrib\vstudio\vc9\zlibvc.sln "Release|Win32" + +Build instructions for Visual Studio 2010 (32 bits or 64 bits) +-------------------------------------------------------------- +- Uncompress current zlib, including all contrib/* files +- Open contrib\vstudio\vc10\zlibvc.sln with Microsoft Visual C++ 2010.0 + + +Important +--------- +- To use zlibwapi.dll in your application, you must define the + macro ZLIB_WINAPI when compiling your application's source files. + + +Additional notes +---------------- +- This DLL, named zlibwapi.dll, is compatible to the old zlib.dll built + by Gilles Vollant from the zlib 1.1.x sources, and distributed at + http://www.winimage.com/zLibDll + It uses the WINAPI calling convention for the exported functions, and + includes the minizip functionality. If your application needs that + particular build of zlib.dll, you can rename zlibwapi.dll to zlib.dll. + +- The new DLL was renamed because there exist several incompatible + versions of zlib.dll on the Internet. + +- There is also an official DLL build of zlib, named zlib1.dll. This one + is exporting the functions using the CDECL convention. See the file + win32\DLL_FAQ.txt found in this zlib distribution. + +- There used to be a ZLIB_DLL macro in zlib 1.1.x, but now this symbol + has a slightly different effect. To avoid compatibility problems, do + not define it here. + + +Gilles Vollant +info@winimage.com diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/binaries/win32/FMITest.dll b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/binaries/win32/FMITest.dll new file mode 100644 index 00000000..34c4c132 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/binaries/win32/FMITest.dll differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/binaries/win32/FMITest.lib b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/binaries/win32/FMITest.lib new file mode 100644 index 00000000..cc21c8a8 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/binaries/win32/FMITest.lib differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/binaries/win32/libexpat-1.dll b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/binaries/win32/libexpat-1.dll new file mode 100644 index 00000000..ead838f9 Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/binaries/win32/libexpat-1.dll differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/miniunz.vcxproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/miniunz.vcxproj new file mode 100644 index 00000000..c34cd847 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/miniunz.vcxproj @@ -0,0 +1,317 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694382A} + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + $(SolutionDir)$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + true + false + $(SolutionDir)$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + false + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + true + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + true + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + false + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + $(ProjectDir)..\..\minizip;$(ProjectDir);$(IncludePath) + $(ProjectDir);$(LibraryPath) + $(ProjectDir);$(IncludePath) + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + EXTRACT_DLL;WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + Default + MultiThreadedDebug + false + NotUsing + $(IntDir) + Level3 + EditAndContinue + + + + + + + $(OutDir)zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + $(OutDir)miniunz.pdb + Console + false + + + MachineX86 + $(OutDir)miniunz.lib + true + $(OutDir)miniunz.map + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + EXTRACT_DLL;WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineIA64 + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/miniunz.vcxproj.filters b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/miniunz.vcxproj.filters new file mode 100644 index 00000000..f65bad9c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/miniunz.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {048af943-022b-4db6-beeb-a54c34774ee2} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {c1d600d2-888f-4aea-b73e-8b0dd9befa0c} + h;hpp;hxx;hm;inl;inc + + + {0844199a-966b-4f19-81db-1e0125e141b9} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/minizip.vcxproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/minizip.vcxproj new file mode 100644 index 00000000..917e1565 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/minizip.vcxproj @@ -0,0 +1,307 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B} + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + true + false + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + false + x64\$(Configuration)\ + x64\$(Configuration)\ + true + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + true + false + x64\$(Configuration)\ + x64\$(Configuration)\ + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + $(IntDir) + Level3 + EditAndContinue + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/minizip.vcxproj.filters b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/minizip.vcxproj.filters new file mode 100644 index 00000000..dd73cd31 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/minizip.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {c0419b40-bf50-40da-b153-ff74215b79de} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {bb87b070-735b-478e-92ce-7383abb2f36c} + h;hpp;hxx;hm;inl;inc + + + {f46ab6a6-548f-43cb-ae96-681abb5bd5db} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/modelDescription.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/modelDescription.xml new file mode 100644 index 00000000..4f29967e --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/modelDescription.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest.c new file mode 100644 index 00000000..7f8b8c03 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest.c @@ -0,0 +1,361 @@ +/* Simulation code for FMITest generated by the OpenModelica Compiler 1.8.1+ (r11690). */ + +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "simulation_runtime.h" +#include "omc_error.h" + +#include +#include + +#include "FMITest_functions.h" + +#include "_FMITest.h" +#include "FMITest_functions.c" +/* dummy VARINFO and FILEINFO */ +const FILE_INFO dummyFILE_INFO = {"",-1,-1,-1,-1,1}; +const VAR_INFO dummyVAR_INFO = {-1,"","",(FILE_INFO){"",-1,-1,-1,-1,1}}; +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _OMC_MEASURE_TIME +int measure_time_flag = 1; +#else +int measure_time_flag = 0; +#endif + +void setupDataStruc(DATA *data) +{ + ASSERT(data,"Error while initialize Data"); + data->modelData.modelName = "FMITest"; + data->modelData.modelFilePrefix = "FMITest"; + data->modelData.modelDir = ""; + data->modelData.modelGUID = "{2aa0bc83-3303-405c-9eaa-75319018664c}"; + + data->modelData.nStates = 1; + data->modelData.nVariablesReal = 2*1+1; + data->modelData.nVariablesInteger = 0; + data->modelData.nVariablesBoolean = 0; + data->modelData.nVariablesString = 0; + data->modelData.nParametersReal = 1; + data->modelData.nParametersInteger = 0; + data->modelData.nParametersBoolean = 0; + data->modelData.nParametersString = 0; + data->modelData.nInputVars = 0; + data->modelData.nOutputVars = 0; + data->modelData.nJacobians = 4; + data->modelData.nHelpVars = 0; + + data->modelData.nAliasReal = 1; + data->modelData.nAliasInteger = 0; + data->modelData.nAliasBoolean = 0; + data->modelData.nAliasString = 0; + + data->modelData.nZeroCrossings = 1; + data->modelData.nSamples = 0; + data->modelData.nInitEquations = 0; + data->modelData.nResiduals = 1; + data->modelData.nExtObjs = 0; + data->modelData.nFunctions = 0; + data->modelData.nEquations = 4; + + data->modelData.nDelayExpressions = 0; + +} + +void setupDataStruc2(DATA *data) +{ + const struct FUNCTION_INFO funcInfo[1] = {{-1,"",omc_dummyFileInfo}}; + memcpy(data->modelData.functionNames, &funcInfo, data->modelData.nFunctions*sizeof(FUNCTION_INFO)); + + const VAR_INFO** equationInfo_cref1 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref1[0] = &$Pvalve__varInfo; + const VAR_INFO** equationInfo_cref3 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref3[0] = &$P$DER$Pstock__varInfo; + const struct EQUATION_INFO equationInfo[4] = { + {1003,"SES_ALGORITHM 0", 0, NULL}, + {1004,"SES_SIMPLE_ASSIGN 1",1,equationInfo_cref1}, + {1005,"SES_ALGORITHM 2", 0, NULL}, + {1006,"SES_SIMPLE_ASSIGN 3",1,equationInfo_cref3} + }; + const int n_omc_equationInfo_reverse_prof_index = 0; + const int omc_equationInfo_reverse_prof_index[] = { + + }; + memcpy(data->modelData.equationInfo, &equationInfo, data->modelData.nEquations*sizeof(EQUATION_INFO)); + + data->modelData.nProfileBlocks = n_omc_equationInfo_reverse_prof_index; + data->modelData.equationInfo_reverse_prof_index = (int*) malloc(data->modelData.nProfileBlocks*sizeof(int)); + memcpy(data->modelData.equationInfo_reverse_prof_index, omc_equationInfo_reverse_prof_index, data->modelData.nProfileBlocks*sizeof(int)); +} + +/* Has to be performed after _init.xml file has been read */ +void callExternalObjectConstructors(DATA *data) +{ + state mem_state; + mem_state = get_memory_state(); + /* data->simulationInfo.extObjs = NULL; */ +} + +void callExternalObjectDestructors(DATA *data) +{ + if (data->simulationInfo.extObjs) { + free(data->simulationInfo.extObjs); + data->simulationInfo.extObjs = 0; + } +} + + +int input_function(DATA *data) +{ + return 0; +} + +int output_function(DATA *data) +{ + return 0; +} + +/* Initializes the raw time events of the simulation using the now + calcualted parameters. */ +void function_sampleInit(DATA *data) +{ +} + +int function_updateSample(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int function_storeDelayed(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundStartValues(DATA *data) +{ + + + DEBUG_INFO(LOG_INIT, "updating start-values:"); + + return 0; +} + +int initial_residual(DATA *data, double $P$_lambda, double* initialResiduals) +{ + int i = 0; + state mem_state; + + mem_state = get_memory_state(); + DEBUG_INFO(LOG_RES_INIT, "updating initial_residuals:"); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($Pstock - $P$START$Pstock)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stock - $_start(stock)) = %f", i, initialResiduals[i-1]); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundParameters(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_0(DATA *data) { + modelica_boolean tmp0; + modelica_boolean tmp1; + /*#modelicaLine [FMITest.mo:7:2-7:56]*/ + RELATIONTOZC(tmp0, $Pstock, 4.9999, 0,GreaterEq,>=); + RELATIONTOZC(tmp1, $Ppar, 0.0, -1,Greater,>); + $Pvalve = ((tmp0 && tmp1)?0.0:$Ppar); + /*#endModelicaLine*/ +} + + +void eqFunction_1(DATA *data) { + /*#modelicaLine [FMITest.mo:9:2-9:20]*/ + $P$DER$Pstock = $Pvalve; + /*#endModelicaLine*/ +} + +static void functionODE_system0(DATA *data,int omc_thread_number) +{ + eqFunction_0(data); + eqFunction_1(data); +} +static void (*functionODE_systems[1])(DATA *, int) = { + functionODE_system0 +}; + +void function_initMemoryState() +{ + push_memory_states(1); +} + +int functionODE(DATA *data) +{ + int id,th_id; + state mem_state; /* We need to have separate memory pools for separate systems... */ + mem_state = get_memory_state(); + for (id=0; id<1; id++) { + th_id = omp_get_thread_num(); + functionODE_systems[id](data,th_id); + } + restore_memory_state(mem_state); + + return 0; +} +#include +const char *_omc_force_solver=_OMC_FORCE_SOLVER; +const int inline_work_states_ndims=_OMC_SOLVER_WORK_STATES_NDIMS; +int functionODE_inline(DATA* data, double stepSize) +{ + return 0; +} + +/* for continuous time variables */ +int functionAlgebraics(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_2(DATA *data) { + modelica_boolean tmp2; + modelica_boolean tmp3; + /*#modelicaLine [FMITest.mo:7:2-7:56]*/ + SAVEZEROCROSS(tmp2, $Pstock, 4.9999, 0,GreaterEq,>=); + SAVEZEROCROSS(tmp3, $Ppar, 0.0, -1,Greater,>); + $Pvalve = ((tmp2 && tmp3)?0.0:$Ppar); + /*#endModelicaLine*/ +} + + +void eqFunction_3(DATA *data) { + /*#modelicaLine [FMITest.mo:9:2-9:20]*/ + $P$DER$Pstock = $Pvalve; + /*#endModelicaLine*/ +} + +int functionDAE(DATA *data, int *needToIterate) +{ + state mem_state; + *needToIterate = 0; + + mem_state = get_memory_state(); + eqFunction_2(data); + eqFunction_3(data); + restore_memory_state(mem_state); + + return 0; +} + +int function_onlyZeroCrossings(DATA *data, double *gout,double *t) +{ + state mem_state; + + mem_state = get_memory_state(); + ZEROCROSSING(0, GreaterEq($Pstock, 4.9999)); + restore_memory_state(mem_state); + + return 0; +} + +int checkForDiscreteChanges(DATA *data) +{ + int needToIterate = 0; + + + return needToIterate; +} + +/* function to check assert after a step is done */ +int checkForAsserts(DATA *data) +{ + + + return 0; +} + + int initialAnalyticJacobianA(DATA* data){ + return 1; + } + + int initialAnalyticJacobianB(DATA* data){ + return 1; + } + + int initialAnalyticJacobianC(DATA* data){ + return 1; + } + + int initialAnalyticJacobianD(DATA* data){ + return 1; + } + int functionJacA(DATA* data, double* jac){ + return 0; + } + + int functionJacB(DATA* data, double* jac){ + return 0; + } + + int functionJacC(DATA* data, double* jac){ + return 0; + } + + int functionJacD(DATA* data, double* jac){ + return 0; + } + +const char *linear_model_frame = + "model linear_FMITest\n parameter Integer n = 1; // states \n parameter Integer k = 0; // top-level inputs \n parameter Integer l = 0; // top-level outputs \n" + " parameter Real x0[1] = {%s};\n" + " parameter Real u0[0] = {%s};\n" + " parameter Real A[1,1] = [%s];\n" + " parameter Real B[1,0] = zeros(1,0);%s\n" + " parameter Real C[0,1] = zeros(0,1);%s\n" + " parameter Real D[0,0] = zeros(0,0);%s\n" + " Real x[1](start=x0);\n" + " input Real u[0];\n" + " output Real y[0];\n" + "\n Real x_Pstock = x[1];\n \n" + "equation\n der(x) = A * x + B * u;\n y = C * x + D * u;\nend linear_FMITest;\n" +; + +#ifdef __cplusplus +} +#endif + +/* forward the main in the simulation runtime */ +extern int _main_SimulationRuntime(int argc, char**argv, DATA *data); + +/* call the simulation runtime main from our main! */ +int main(int argc, char**argv) +{ + DATA data; + setupDataStruc(&data); + return _main_SimulationRuntime(argc, argv, &data); +} + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_FMU.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_FMU.c new file mode 100644 index 00000000..7f6ceabb --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_FMU.c @@ -0,0 +1,152 @@ + +// define class name and unique id +#define MODEL_IDENTIFIER FMITest +#define MODEL_GUID "{2aa0bc83-3303-405c-9eaa-75319018664c}" + +// include fmu header files, typedefs and macros +#include +#include +#include +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "omc_error.h" +#include "fmiModelTypes.h" +#include "fmiModelFunctions.h" +#include "FMITest_functions.h" +#include "initialization.h" +#include "events.h" +#include "fmu_model_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void setStartValues(ModelInstance *comp); +void setDefaultStartValues(ModelInstance *comp); +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo); +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value); +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value); +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value); +fmiString getString(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value); + +// define model size +#define NUMBER_OF_STATES 1 +#define NUMBER_OF_EVENT_INDICATORS 1 +#define NUMBER_OF_REALS 5 +#define NUMBER_OF_INTEGERS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_EXTERNALFUNCTIONS 0 + +// define variable data for model +#define $Pstock_ 0 +#define $P$DER$Pstock_ 1 +#define $Pvalve_ 2 +#define $Ppar_ 3 +#define $Pvalve2_ 4 + + +// define initial state vector as vector of value references +#define STATES { $Pstock_ } +#define STATESDERIVATIVES { $P$DER$Pstock_ } + + +// implementation of the Model Exchange functions +#include "fmu_model_interface.c" + +// Set values for all variables that define a start value +void setDefaultStartValues(ModelInstance *comp) { + +comp->fmuData->modelData.realVarsData[0].attribute.start = 0.0; +comp->fmuData->modelData.realParameterData[0].attribute.start = 4.0; +} +// Set values for all variables that define a start value +void setStartValues(ModelInstance *comp) { + + comp->fmuData->modelData.realVarsData[0].attribute.start = comp->fmuData->localData[0]->realVars[0]; + comp->fmuData->modelData.realVarsData[1].attribute.start = comp->fmuData->localData[0]->realVars[1]; + comp->fmuData->modelData.realVarsData[2].attribute.start = comp->fmuData->localData[0]->realVars[2]; +comp->fmuData->modelData.realParameterData[0].attribute.start = comp->fmuData->simulationInfo.realParameter[0]; +} +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $Pstock_ : return comp->fmuData->localData[0]->realVars[0]; break; + case $P$DER$Pstock_ : return comp->fmuData->localData[0]->realVars[1]; break; + case $Pvalve_ : return comp->fmuData->localData[0]->realVars[2]; break; + case $Ppar_ : return comp->fmuData->simulationInfo.realParameter[0]; break; + case $Pvalve2_ : return getReal(comp, $Pvalve_); break; + default: + return fmiError; + } +} + +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value) { + switch (vr) { + case $Pstock_ : comp->fmuData->localData[0]->realVars[0]=value; break; + case $P$DER$Pstock_ : comp->fmuData->localData[0]->realVars[1]=value; break; + case $Pvalve_ : comp->fmuData->localData[0]->realVars[2]=value; break; + case $Ppar_ : comp->fmuData->simulationInfo.realParameter[0]=value; break; + case $Pvalve2_ : return setReal(comp, $Pvalve_, value); break; + default: + return fmiError; + } + return fmiOK; +} + +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value) { + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} + +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value) { + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} + +fmiString getString(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} + +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value){ + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} + + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_functions.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_functions.c new file mode 100644 index 00000000..2d7eacf5 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_functions.c @@ -0,0 +1,16 @@ +#include "FMITest_functions.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define _OMC_LIT0_data "'p" +static const size_t _OMC_LIT0_strlen = 2; +static const char _OMC_LIT0[3] = _OMC_LIT0_data; +#define _OMC_LIT1_data "'p/s" +static const size_t _OMC_LIT1_strlen = 4; +static const char _OMC_LIT1[5] = _OMC_LIT1_data; + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_functions.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_functions.h new file mode 100644 index 00000000..66c8a413 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_functions.h @@ -0,0 +1,17 @@ +#ifndef FMITest__H +#define FMITest__H +#define omp_get_thread_num() 0 +#include "modelica.h" +#include +#include +#include +#include "simulation_runtime.h" +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_records.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_records.c new file mode 100644 index 00000000..8b85f1d6 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/FMITest_records.c @@ -0,0 +1,3 @@ +/* Additional record code for FMITest generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#include "meta_modelica.h" + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/_FMITest.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/_FMITest.h new file mode 100644 index 00000000..67c6b940 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/sources/_FMITest.h @@ -0,0 +1,34 @@ +/* Simulation code for FMITest generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#define time data->localData[0]->timeValue + +/* States */ +#define _$Pstock(i) data->localData[i]->realVars[0] +#define $Pstock _$Pstock(0) +#define $P$PRE$Pstock data->simulationInfo.realVarsPre[0] +#define $P$START$Pstock data->modelData.realVarsData[0].attribute.start +#define $Pstock__varInfo data->modelData.realVarsData[0].info +/* StatesDerivatives */ +#define _$P$DER$Pstock(i) data->localData[i]->realVars[1] +#define $P$DER$Pstock _$P$DER$Pstock(0) +#define $P$PRE$P$DER$Pstock data->simulationInfo.realVarsPre[1] +#define $P$START$P$DER$Pstock data->modelData.realVarsData[1].attribute.start +#define $P$DER$Pstock__varInfo data->modelData.realVarsData[1].info +/* Algebraic Vars */ +#define _$Pvalve(i) data->localData[i]->realVars[2] +#define $Pvalve _$Pvalve(0) +#define $P$PRE$Pvalve data->simulationInfo.realVarsPre[2] +#define $P$START$Pvalve data->modelData.realVarsData[2].attribute.start +#define $Pvalve__varInfo data->modelData.realVarsData[2].info +/* Algebraic Parameter */ +#define $Ppar data->simulationInfo.realParameter[0] +#define $P$START$Ppar data->modelData.realParameterData[0].attribute.start +#define $Ppar__varInfo data->modelData.realParameterData[0].info +/* External Objects */ +/* Algebraic Integer Vars */ +/* Algebraic Integer Parameter */ +/* Algebraic Boolean Vars */ +/* Algebraic Boolean Parameters */ +/* Algebraic String Variables */ +/* Algebraic String Parameter */ +/* Jacobian Variables */ + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlib.vcxproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlib.vcxproj new file mode 100644 index 00000000..9088d176 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlib.vcxproj @@ -0,0 +1,420 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B} + testzlib + Win32Proj + + + + Application + MultiByte + true + + + Application + MultiByte + true + + + Application + MultiByte + + + Application + MultiByte + true + + + Application + MultiByte + true + + + Application + MultiByte + + + Application + true + + + Application + true + + + Application + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + true + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + true + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + EditAndContinue + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlib.vcxproj.filters b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlib.vcxproj.filters new file mode 100644 index 00000000..249daa89 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlib.vcxproj.filters @@ -0,0 +1,58 @@ + + + + + {c1f6a2e3-5da5-4955-8653-310d3efe05a9} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {c2aaffdc-2c95-4d6f-8466-4bec5890af2c} + h;hpp;hxx;hm;inl;inc + + + {c274fe07-05f2-461c-964b-f6341e4e7eb5} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlibdll.vcxproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlibdll.vcxproj new file mode 100644 index 00000000..2d628158 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlibdll.vcxproj @@ -0,0 +1,310 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694366A} + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + true + false + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + false + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + true + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + true + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + false + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + $(IntDir) + Level3 + EditAndContinue + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlibdll.vcxproj.filters b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlibdll.vcxproj.filters new file mode 100644 index 00000000..53a8693b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/testzlibdll.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {fa61a89f-93fc-4c89-b29e-36224b7592f4} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {d4b85da0-2ba2-4934-b57f-e2584e3848ee} + h;hpp;hxx;hm;inl;inc + + + {e573e075-00bd-4a7d-bd67-a8cc9bfc5aca} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlib.rc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlib.rc new file mode 100644 index 00000000..8f22fab9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1.2.6,1 + PRODUCTVERSION 1.2.6,1 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.6\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlib.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2012 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibstat.vcxproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibstat.vcxproj new file mode 100644 index 00000000..2682fca2 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibstat.vcxproj @@ -0,0 +1,457 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} + + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + + + MultiThreadedDebug + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibstat.vcxproj.filters b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibstat.vcxproj.filters new file mode 100644 index 00000000..c8c7f7ea --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibstat.vcxproj.filters @@ -0,0 +1,77 @@ + + + + + {174213f6-7f66-4ae8-a3a8-a1e0a1e6ffdd} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.def b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.def new file mode 100644 index 00000000..571b0a66 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.def @@ -0,0 +1,137 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.24 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + gzflags @162 + inflateResetKeep @163 + deflateResetKeep @164 diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.sln b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.sln new file mode 100644 index 00000000..6f6ffd5e --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.sln @@ -0,0 +1,135 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.vcxproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.vcxproj new file mode 100644 index 00000000..fd0f53f5 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.vcxproj @@ -0,0 +1,659 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {8FD826F8-3739-44E6-8CC8-997122E53B8D} + + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + $(SolutionDir)$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + true + false + $(SolutionDir)Release\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + $(SolutionDir)$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + true + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + true + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + + + MultiThreadedDebug + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.vcxproj.filters b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.vcxproj.filters new file mode 100644 index 00000000..180b71cd --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc10/zlibvc.vcxproj.filters @@ -0,0 +1,118 @@ + + + + + {07934a85-8b61-443d-a0ee-b2eedb74f3cd} + cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90 + + + {1d99675b-433d-4a21-9e50-ed4ab8b19762} + h;hpp;hxx;hm;inl;fi;fd + + + {431c0958-fa71-44d0-9084-2d19d100c0cc} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/miniunz.vcproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/miniunz.vcproj new file mode 100644 index 00000000..7da32b91 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/miniunz.vcproj @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/minizip.vcproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/minizip.vcproj new file mode 100644 index 00000000..e57e07d9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/minizip.vcproj @@ -0,0 +1,562 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/testzlib.vcproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/testzlib.vcproj new file mode 100644 index 00000000..9cb0bf87 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/testzlib.vcproj @@ -0,0 +1,852 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/testzlibdll.vcproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/testzlibdll.vcproj new file mode 100644 index 00000000..b1ddde05 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/testzlibdll.vcproj @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlib.rc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlib.rc new file mode 100644 index 00000000..8f22fab9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1.2.6,1 + PRODUCTVERSION 1.2.6,1 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.6\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlib.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2012 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibstat.vcproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibstat.vcproj new file mode 100644 index 00000000..61c76c7c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibstat.vcproj @@ -0,0 +1,835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibvc.def b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibvc.def new file mode 100644 index 00000000..571b0a66 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibvc.def @@ -0,0 +1,137 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.24 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + gzflags @162 + inflateResetKeep @163 + deflateResetKeep @164 diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibvc.sln b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibvc.sln new file mode 100644 index 00000000..b4829671 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibvc.sln @@ -0,0 +1,144 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestZlibDll", "testzlibdll.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibvc.vcproj b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibvc.vcproj new file mode 100644 index 00000000..c9a89471 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/contrib/vstudio/vc9/zlibvc.vcproj @@ -0,0 +1,1156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/crc32.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/crc32.c new file mode 100644 index 00000000..c12471e6 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/crc32.c @@ -0,0 +1,447 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR + typedef u4 crc_table_t; +# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else + typedef unsigned long crc_table_t; +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local crc_table_t FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const crc_table_t FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + crc_table_t c; + int n, k; + crc_table_t poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0; + for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) + poly |= (crc_table_t)1 << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (crc_table_t)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const crc_table_t FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const crc_table_t FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/crc32.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/crc32.h new file mode 100644 index 00000000..c3e7171c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const crc_table_t FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/deflate.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/deflate.c new file mode 100644 index 00000000..8bd480eb --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/deflate.c @@ -0,0 +1,1965 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.6 Copyright 1995-2012 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + unsigned char *next; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending (strm, pending, bits) + unsigned *pending; + int *bits; + z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + deflate_state *s; + int put; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if ((long)s->strstart > s->block_start) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/deflate.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/deflate.h new file mode 100644 index 00000000..fbac44d9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/deflate.h @@ -0,0 +1,346 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2012 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/algorithm.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/algorithm.txt new file mode 100644 index 00000000..c97f4950 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend too much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +http://tools.ietf.org/html/rfc1951 diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/rfc1950.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/rfc1950.txt new file mode 100644 index 00000000..ce6428a0 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/rfc1950.txt @@ -0,0 +1,619 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1950 Aladdin Enterprises +Category: Informational J-L. Gailly + Info-ZIP + May 1996 + + + ZLIB Compressed Data Format Specification version 3.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format. The + data can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a priori + bounded amount of intermediate storage. The format presently uses + the DEFLATE compression method but can be easily extended to use + other compression methods. It can be implemented readily in a manner + not covered by patents. This specification also defines the ADLER-32 + checksum (an extension and improvement of the Fletcher checksum), + used for detection of data corruption, and provides an algorithm for + computing it. + + + + +Deutsch & Gailly Informational [Page 1] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 3 + 2.1. Overall conventions ....................................... 3 + 2.2. Data format ............................................... 4 + 2.3. Compliance ................................................ 7 + 3. References ..................................................... 7 + 4. Source code .................................................... 8 + 5. Security Considerations ........................................ 8 + 6. Acknowledgements ............................................... 8 + 7. Authors' Addresses ............................................. 8 + 8. Appendix: Rationale ............................................ 9 + 9. Appendix: Sample code ..........................................10 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence can + be used in data communications or similar structures such as + Unix filters; + + * Can use a number of different compression methods; + + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely. + + The data format defined by this specification does not attempt to + allow random access to compressed data. + + + + + + + +Deutsch & Gailly Informational [Page 2] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into zlib format and/or decompress data from zlib + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compressed data format that can be + used for in-memory compression of a sequence of arbitrary bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below, for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + Version 3.1 was the first public release of this specification. + In version 3.2, some terminology was changed and the Adler-32 + sample code was rewritten for clarity. In version 3.3, the + support for a preset dictionary was introduced, and the + specification was converted to RFC style. + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + + + +Deutsch & Gailly Informational [Page 3] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the MOST-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00000010|00001000| + +--------+--------+ + ^ ^ + | | + | + less significant byte = 8 + + more significant byte = 2 x 256 + + 2.2. Data format + + A zlib stream has the following structure: + + 0 1 + +---+---+ + |CMF|FLG| (more-->) + +---+---+ + + + + + + + + +Deutsch & Gailly Informational [Page 4] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + (if FLG.FDICT set) + + 0 1 2 3 + +---+---+---+---+ + | DICTID | (more-->) + +---+---+---+---+ + + +=====================+---+---+---+---+ + |...compressed data...| ADLER32 | + +=====================+---+---+---+---+ + + Any data which may appear after ADLER32 are not part of the zlib + stream. + + CMF (Compression Method and flags) + This byte is divided into a 4-bit compression method and a 4- + bit information field depending on the compression method. + + bits 0 to 3 CM Compression method + bits 4 to 7 CINFO Compression info + + CM (Compression method) + This identifies the compression method used in the file. CM = 8 + denotes the "deflate" compression method with a window size up + to 32K. This is the method used by gzip and PNG (see + references [1] and [2] in Chapter 3, below, for the reference + documents). CM = 15 is reserved. It might be used in a future + version of this specification to indicate the presence of an + extra field before the compressed data. + + CINFO (Compression info) + For CM = 8, CINFO is the base-2 logarithm of the LZ77 window + size, minus eight (CINFO=7 indicates a 32K window size). Values + of CINFO above 7 are not allowed in this version of the + specification. CINFO is not defined in this specification for + CM not equal to 8. + + FLG (FLaGs) + This flag byte is divided as follows: + + bits 0 to 4 FCHECK (check bits for CMF and FLG) + bit 5 FDICT (preset dictionary) + bits 6 to 7 FLEVEL (compression level) + + The FCHECK value must be such that CMF and FLG, when viewed as + a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), + is a multiple of 31. + + + + +Deutsch & Gailly Informational [Page 5] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + FDICT (Preset dictionary) + If FDICT is set, a DICT dictionary identifier is present + immediately after the FLG byte. The dictionary is a sequence of + bytes which are initially fed to the compressor without + producing any compressed output. DICT is the Adler-32 checksum + of this sequence of bytes (see the definition of ADLER32 + below). The decompressor can use this identifier to determine + which dictionary has been used by the compressor. + + FLEVEL (Compression level) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + 0 - compressor used fastest algorithm + 1 - compressor used fast algorithm + 2 - compressor used default algorithm + 3 - compressor used maximum compression, slowest algorithm + + The information in FLEVEL is not needed for decompression; it + is there to indicate if recompression might be worthwhile. + + compressed data + For compression method 8, the compressed data is stored in the + deflate compressed data format as described in the document + "DEFLATE Compressed Data Format Specification" by L. Peter + Deutsch. (See reference [3] in Chapter 3, below) + + Other compressed data formats are not specified in this version + of the zlib specification. + + ADLER32 (Adler-32 checksum) + This contains a checksum value of the uncompressed data + (excluding any dictionary data) computed according to Adler-32 + algorithm. This algorithm is a 32-bit extension and improvement + of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 + standard. See references [4] and [5] in Chapter 3, below) + + Adler-32 is composed of two sums accumulated per byte: s1 is + the sum of all bytes, s2 is the sum of all s1 values. Both sums + are done modulo 65521. s1 is initialized to 1, s2 to zero. The + Adler-32 checksum is stored as s2*65536 + s1 in most- + significant-byte first (network) order. + + + + + + + + +Deutsch & Gailly Informational [Page 6] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 2.3. Compliance + + A compliant compressor must produce streams with correct CMF, FLG + and ADLER32, but need not support preset dictionaries. When the + zlib data format is used as part of another standard data format, + the compressor may use only preset dictionaries that are specified + by this other data format. If this other format does not use the + preset dictionary feature, the compressor must not set the FDICT + flag. + + A compliant decompressor must check CMF, FLG, and ADLER32, and + provide an error indication if any of these have incorrect values. + A compliant decompressor must give an error indication if CM is + not one of the values defined in this specification (only the + value 8 is permitted in this version), since another value could + indicate the presence of new features that would cause subsequent + data to be interpreted incorrectly. A compliant decompressor must + give an error indication if FDICT is set and DICTID is not the + identifier of a known preset dictionary. A decompressor may + ignore FLEVEL and still be compliant. When the zlib data format + is being used as a part of another standard format, a compliant + decompressor must support all the preset dictionaries specified by + the other format. When the other format does not use the preset + dictionary feature, a compliant decompressor must reject any + stream in which the FDICT flag is set. + +3. References + + [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", + available in ftp://ftp.uu.net/graphics/png/documents/ + + [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Fletcher, J. G., "An Arithmetic Checksum for Serial + Transmissions," IEEE Transactions on Communications, Vol. COM-30, + No. 1, January 1982, pp. 247-252. + + [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," + November, 1993, pp. 144, 145. (Available from + gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. + + + + + + + +Deutsch & Gailly Informational [Page 7] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +4. Source code + + Source code for a C language implementation of a "zlib" compliant + library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +5. Security Considerations + + A decoder that fails to check the ADLER32 checksum value may be + subject to undetected data corruption. + +6. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly and Mark Adler designed the zlib format and wrote + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +7. Authors' Addresses + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + + Jean-Loup Gailly + + EMail: + + Questions about the technical content of this specification can be + sent by email to + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + +Deutsch & Gailly Informational [Page 8] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +8. Appendix: Rationale + + 8.1. Preset dictionaries + + A preset dictionary is specially useful to compress short input + sequences. The compressor can take advantage of the dictionary + context to encode the input in a more compact manner. The + decompressor can be initialized with the appropriate context by + virtually decompressing a compressed version of the dictionary + without producing any output. However for certain compression + algorithms such as the deflate algorithm this operation can be + achieved without actually performing any decompression. + + The compressor and the decompressor must use exactly the same + dictionary. The dictionary may be fixed or may be chosen among a + certain number of predefined dictionaries, according to the kind + of input data. The decompressor can determine which dictionary has + been chosen by the compressor by checking the dictionary + identifier. This document does not specify the contents of + predefined dictionaries, since the optimal dictionaries are + application specific. Standard data formats using this feature of + the zlib specification must precisely define the allowed + dictionaries. + + 8.2. The Adler-32 algorithm + + The Adler-32 algorithm is much faster than the CRC32 algorithm yet + still provides an extremely low probability of undetected errors. + + The modulo on unsigned long accumulators can be delayed for 5552 + bytes, so the modulo operation time is negligible. If the bytes + are a, b, c, the second sum is 3a + 2b + c + 3, and so is position + and order sensitive, unlike the first sum, which is just a + checksum. That 65521 is prime is important to avoid a possible + large class of two-byte errors that leave the check unchanged. + (The Fletcher checksum uses 255, which is not prime and which also + makes the Fletcher check insensitive to single byte changes 0 <-> + 255.) + + The sum s1 is initialized to 1 instead of zero to make the length + of the sequence part of s2, so that the length does not have to be + checked separately. (Any sequence of zeroes has a Fletcher + checksum of zero.) + + + + + + + + +Deutsch & Gailly Informational [Page 9] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +9. Appendix: Sample code + + The following C code computes the Adler-32 checksum of a data buffer. + It is written for clarity, not for speed. The sample code is in the + ANSI C programming language. Non C users may find it easier to read + with these hints: + + & Bitwise AND operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero bit(s) + at the left. + << Bitwise left shift operator. Left shift inserts zero + bit(s) at the right. + ++ "n++" increments the variable n. + % modulo operator: a % b is the remainder of a divided by b. + + #define BASE 65521 /* largest prime smaller than 65536 */ + + /* + Update a running Adler-32 checksum with the bytes buf[0..len-1] + and return the updated checksum. The Adler-32 checksum should be + initialized to 1. + + Usage example: + + unsigned long adler = 1L; + + while (read_buffer(buffer, length) != EOF) { + adler = update_adler32(adler, buffer, length); + } + if (adler != original_adler) error(); + */ + unsigned long update_adler32(unsigned long adler, + unsigned char *buf, int len) + { + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int n; + + for (n = 0; n < len; n++) { + s1 = (s1 + buf[n]) % BASE; + s2 = (s2 + s1) % BASE; + } + return (s2 << 16) + s1; + } + + /* Return the adler32 of the bytes buf[0..len-1] */ + + + + +Deutsch & Gailly Informational [Page 10] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + unsigned long adler32(unsigned char *buf, int len) + { + return update_adler32(1L, buf, len); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch & Gailly Informational [Page 11] + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/rfc1951.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/rfc1951.txt new file mode 100644 index 00000000..403c8c72 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/rfc1951.txt @@ -0,0 +1,955 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1951 Aladdin Enterprises +Category: Informational May 1996 + + + DEFLATE Compressed Data Format Specification version 1.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that + compresses data using a combination of the LZ77 algorithm and Huffman + coding, with efficiency comparable to the best currently available + general-purpose compression methods. The data can be produced or + consumed, even for an arbitrarily long sequentially presented input + data stream, using only an a priori bounded amount of intermediate + storage. The format can be implemented readily in a manner not + covered by patents. + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 4 + 2. Compressed representation overview ............................. 4 + 3. Detailed specification ......................................... 5 + 3.1. Overall conventions ....................................... 5 + 3.1.1. Packing into bytes .................................. 5 + 3.2. Compressed block format ................................... 6 + 3.2.1. Synopsis of prefix and Huffman coding ............... 6 + 3.2.2. Use of Huffman coding in the "deflate" format ....... 7 + 3.2.3. Details of block format ............................. 9 + 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11 + 3.2.5. Compressed blocks (length and distance codes) ...... 11 + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12 + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13 + 3.3. Compliance ............................................... 14 + 4. Compression algorithm details ................................. 14 + 5. References .................................................... 16 + 6. Security Considerations ....................................... 16 + 7. Source code ................................................... 16 + 8. Acknowledgements .............................................. 16 + 9. Author's Address .............................................. 17 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence + can be used in data communications or similar structures + such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + + + +Deutsch Informational [Page 2] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + The data format defined by this specification does not attempt to: + + * Allow random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well + as the best currently available specialized algorithms. + + A simple counting argument shows that no lossless compression + algorithm can compress every possible input data set. For the + format defined here, the worst case expansion is 5 bytes per 32K- + byte block, i.e., a size increase of 0.015% for large data sets. + English text usually compresses by a factor of 2.5 to 3; + executable files usually compress somewhat less; graphical data + such as raster images may compress much more. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into "deflate" format and/or decompress data from + "deflate" format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. Familiarity with the technique of Huffman coding + is helpful but not required. + + 1.3. Scope + + The specification specifies a method for representing a sequence + of bytes as a (usually shorter) sequence of bits, and a method for + packing the latter bit sequence into bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + Byte: 8 bits stored or transmitted as a unit (same as an octet). + For this specification, a byte is exactly 8 bits, even on machines + + + +Deutsch Informational [Page 3] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + which store a character on a number of bits different from eight. + See below, for the numbering of bits within a byte. + + String: a sequence of arbitrary bytes. + + 1.6. Changes from previous versions + + There have been no technical changes to the deflate format since + version 1.1 of this specification. In version 1.2, some + terminology was changed. Version 1.3 is a conversion of the + specification to RFC style. + +2. Compressed representation overview + + A compressed data set consists of a series of blocks, corresponding + to successive blocks of input data. The block sizes are arbitrary, + except that non-compressible blocks are limited to 65,535 bytes. + + Each block is compressed using a combination of the LZ77 algorithm + and Huffman coding. The Huffman trees for each block are independent + of those for previous or subsequent blocks; the LZ77 algorithm may + use a reference to a duplicated string occurring in a previous block, + up to 32K input bytes before. + + Each block consists of two parts: a pair of Huffman code trees that + describe the representation of the compressed data part, and a + compressed data part. (The Huffman trees themselves are compressed + using Huffman encoding.) The compressed data consists of a series of + elements of two types: literal bytes (of strings that have not been + detected as duplicated within the previous 32K input bytes), and + pointers to duplicated strings, where a pointer is represented as a + pair . The representation used in the + "deflate" format limits distances to 32K bytes and lengths to 258 + bytes, but does not limit the size of a block, except for + uncompressible blocks, which are limited as noted above. + + Each type of value (literals, distances, and lengths) in the + compressed data is represented using a Huffman code, using one code + tree for literals and lengths and a separate code tree for distances. + The code trees for each block appear in a compact form just before + the compressed data for that block. + + + + + + + + + + +Deutsch Informational [Page 4] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +3. Detailed specification + + 3.1. Overall conventions In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + 3.1.1. Packing into bytes + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, + since the final data format described here is byte- rather than + + + +Deutsch Informational [Page 5] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + bit-oriented. However, we describe the compressed block format + in below, as a sequence of data elements of various bit + lengths, not a sequence of bytes. We must therefore specify + how to pack these data elements into bytes to form the final + compressed byte sequence: + + * Data elements are packed into bytes in order of + increasing bit number within the byte, i.e., starting + with the least-significant bit of the byte. + * Data elements other than Huffman codes are packed + starting with the least-significant bit of the data + element. + * Huffman codes are packed starting with the most- + significant bit of the code. + + In other words, if one were to print out the compressed data as + a sequence of bytes, starting with the first byte at the + *right* margin and proceeding to the *left*, with the most- + significant bit of each byte on the left as usual, one would be + able to parse the result from right to left, with fixed-width + elements in the correct MSB-to-LSB order and Huffman codes in + bit-reversed order (i.e., with the first bit of the code in the + relative LSB position). + + 3.2. Compressed block format + + 3.2.1. Synopsis of prefix and Huffman coding + + Prefix coding represents symbols from an a priori known + alphabet by bit sequences (codes), one code for each symbol, in + a manner such that different symbols may be represented by bit + sequences of different lengths, but a parser can always parse + an encoded string unambiguously symbol-by-symbol. + + We define a prefix code in terms of a binary tree in which the + two edges descending from each non-leaf node are labeled 0 and + 1 and in which the leaf nodes correspond one-for-one with (are + labeled with) the symbols of the alphabet; then the code for a + symbol is the sequence of 0's and 1's on the edges leading from + the root to the leaf labeled with that symbol. For example: + + + + + + + + + + + +Deutsch Informational [Page 6] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + /\ Symbol Code + 0 1 ------ ---- + / \ A 00 + /\ B B 1 + 0 1 C 011 + / \ D 010 + A /\ + 0 1 + / \ + D C + + A parser can decode the next symbol from an encoded input + stream by walking down the tree from the root, at each step + choosing the edge corresponding to the next input bit. + + Given an alphabet with known symbol frequencies, the Huffman + algorithm allows the construction of an optimal prefix code + (one which represents strings with those symbol frequencies + using the fewest bits of any possible prefix codes for that + alphabet). Such a code is called a Huffman code. (See + reference [1] in Chapter 5, references for additional + information on Huffman codes.) + + Note that in the "deflate" format, the Huffman codes for the + various alphabets must not exceed certain maximum code lengths. + This constraint complicates the algorithm for computing code + lengths from symbol frequencies. Again, see Chapter 5, + references for details. + + 3.2.2. Use of Huffman coding in the "deflate" format + + The Huffman codes used for each alphabet in the "deflate" + format have two additional rules: + + * All codes of a given bit length have lexicographically + consecutive values, in the same order as the symbols + they represent; + + * Shorter codes lexicographically precede longer codes. + + + + + + + + + + + + +Deutsch Informational [Page 7] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + We could recode the example above to follow this rule as + follows, assuming that the order of the alphabet is ABCD: + + Symbol Code + ------ ---- + A 10 + B 0 + C 110 + D 111 + + I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are + lexicographically consecutive. + + Given this rule, we can define the Huffman code for an alphabet + just by giving the bit lengths of the codes for each symbol of + the alphabet in order; this is sufficient to determine the + actual codes. In our example, the code is completely defined + by the sequence of bit lengths (2, 1, 3, 3). The following + algorithm generates the codes as integers, intended to be read + from most- to least-significant bit. The code lengths are + initially in tree[I].Len; the codes are produced in + tree[I].Code. + + 1) Count the number of codes for each code length. Let + bl_count[N] be the number of codes of length N, N >= 1. + + 2) Find the numerical value of the smallest code for each + code length: + + code = 0; + bl_count[0] = 0; + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = code; + } + + 3) Assign numerical values to all codes, using consecutive + values for all codes of the same length with the base + values determined at step 2. Codes that are never used + (which have a bit length of zero) must not be assigned a + value. + + for (n = 0; n <= max_code; n++) { + len = tree[n].Len; + if (len != 0) { + tree[n].Code = next_code[len]; + next_code[len]++; + } + + + +Deutsch Informational [Page 8] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + } + + Example: + + Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, + 3, 2, 4, 4). After step 1, we have: + + N bl_count[N] + - ----------- + 2 1 + 3 5 + 4 2 + + Step 2 computes the following next_code values: + + N next_code[N] + - ------------ + 1 0 + 2 0 + 3 2 + 4 14 + + Step 3 produces the following code values: + + Symbol Length Code + ------ ------ ---- + A 3 010 + B 3 011 + C 3 100 + D 3 101 + E 3 110 + F 2 00 + G 4 1110 + H 4 1111 + + 3.2.3. Details of block format + + Each block of compressed data begins with 3 header bits + containing the following data: + + first bit BFINAL + next 2 bits BTYPE + + Note that the header bits do not necessarily begin on a byte + boundary, since a block does not necessarily occupy an integral + number of bytes. + + + + + +Deutsch Informational [Page 9] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + BFINAL is set if and only if this is the last block of the data + set. + + BTYPE specifies how the data are compressed, as follows: + + 00 - no compression + 01 - compressed with fixed Huffman codes + 10 - compressed with dynamic Huffman codes + 11 - reserved (error) + + The only difference between the two compressed cases is how the + Huffman codes for the literal/length and distance alphabets are + defined. + + In all cases, the decoding algorithm for the actual data is as + follows: + + do + read block header from input stream. + if stored with no compression + skip any remaining bits in current partially + processed byte + read LEN and NLEN (see next section) + copy LEN bytes of data to output + otherwise + if compressed with dynamic Huffman codes + read representation of code trees (see + subsection below) + loop (until end of block code recognized) + decode literal/length value from input stream + if value < 256 + copy value (literal byte) to output stream + otherwise + if value = end of block (256) + break from loop + otherwise (value = 257..285) + decode distance from input stream + + move backwards distance bytes in the output + stream, and copy length bytes from this + position to the output stream. + end loop + while not last block + + Note that a duplicated string reference may refer to a string + in a previous block; i.e., the backward distance may cross one + or more block boundaries. However a distance cannot refer past + the beginning of the output stream. (An application using a + + + +Deutsch Informational [Page 10] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + preset dictionary might discard part of the output stream; a + distance can refer to that part of the output stream anyway) + Note also that the referenced string may overlap the current + position; for example, if the last 2 bytes decoded have values + X and Y, a string reference with + adds X,Y,X,Y,X to the output stream. + + We now specify each compression method in turn. + + 3.2.4. Non-compressed blocks (BTYPE=00) + + Any bits of input up to the next byte boundary are ignored. + The rest of the block consists of the following information: + + 0 1 2 3 4... + +---+---+---+---+================================+ + | LEN | NLEN |... LEN bytes of literal data...| + +---+---+---+---+================================+ + + LEN is the number of data bytes in the block. NLEN is the + one's complement of LEN. + + 3.2.5. Compressed blocks (length and distance codes) + + As noted above, encoded data blocks in the "deflate" format + consist of sequences of symbols drawn from three conceptually + distinct alphabets: either literal bytes, from the alphabet of + byte values (0..255), or pairs, + where the length is drawn from (3..258) and the distance is + drawn from (1..32,768). In fact, the literal and length + alphabets are merged into a single alphabet (0..285), where + values 0..255 represent literal bytes, the value 256 indicates + end-of-block, and values 257..285 represent length codes + (possibly in conjunction with extra bits following the symbol + code) as follows: + + + + + + + + + + + + + + + + +Deutsch Informational [Page 11] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + Extra Extra Extra + Code Bits Length(s) Code Bits Lengths Code Bits Length(s) + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 257 0 3 267 1 15,16 277 4 67-82 + 258 0 4 268 1 17,18 278 4 83-98 + 259 0 5 269 2 19-22 279 4 99-114 + 260 0 6 270 2 23-26 280 4 115-130 + 261 0 7 271 2 27-30 281 5 131-162 + 262 0 8 272 2 31-34 282 5 163-194 + 263 0 9 273 3 35-42 283 5 195-226 + 264 0 10 274 3 43-50 284 5 227-257 + 265 1 11,12 275 3 51-58 285 0 258 + 266 1 13,14 276 3 59-66 + + The extra bits should be interpreted as a machine integer + stored with the most-significant bit first, e.g., bits 1110 + represent the value 14. + + Extra Extra Extra + Code Bits Dist Code Bits Dist Code Bits Distance + ---- ---- ---- ---- ---- ------ ---- ---- -------- + 0 0 1 10 4 33-48 20 9 1025-1536 + 1 0 2 11 4 49-64 21 9 1537-2048 + 2 0 3 12 5 65-96 22 10 2049-3072 + 3 0 4 13 5 97-128 23 10 3073-4096 + 4 1 5,6 14 6 129-192 24 11 4097-6144 + 5 1 7,8 15 6 193-256 25 11 6145-8192 + 6 2 9-12 16 7 257-384 26 12 8193-12288 + 7 2 13-16 17 7 385-512 27 12 12289-16384 + 8 3 17-24 18 8 513-768 28 13 16385-24576 + 9 3 25-32 19 8 769-1024 29 13 24577-32768 + + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) + + The Huffman codes for the two alphabets are fixed, and are not + represented explicitly in the data. The Huffman code lengths + for the literal/length alphabet are: + + Lit Value Bits Codes + --------- ---- ----- + 0 - 143 8 00110000 through + 10111111 + 144 - 255 9 110010000 through + 111111111 + 256 - 279 7 0000000 through + 0010111 + 280 - 287 8 11000000 through + 11000111 + + + +Deutsch Informational [Page 12] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + The code lengths are sufficient to generate the actual codes, + as described above; we show the codes in the table for added + clarity. Literal/length values 286-287 will never actually + occur in the compressed data, but participate in the code + construction. + + Distance codes 0-31 are represented by (fixed-length) 5-bit + codes, with possible additional bits as shown in the table + shown in Paragraph 3.2.5, above. Note that distance codes 30- + 31 will never actually occur in the compressed data. + + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) + + The Huffman codes for the two alphabets appear in the block + immediately after the header bits and before the actual + compressed data, first the literal/length code and then the + distance code. Each code is defined by a sequence of code + lengths, as discussed in Paragraph 3.2.2, above. For even + greater compactness, the code length sequences themselves are + compressed using a Huffman code. The alphabet for code lengths + is as follows: + + 0 - 15: Represent code lengths of 0 - 15 + 16: Copy the previous code length 3 - 6 times. + The next 2 bits indicate repeat length + (0 = 3, ... , 3 = 6) + Example: Codes 8, 16 (+2 bits 11), + 16 (+2 bits 10) will expand to + 12 code lengths of 8 (1 + 6 + 5) + 17: Repeat a code length of 0 for 3 - 10 times. + (3 bits of length) + 18: Repeat a code length of 0 for 11 - 138 times + (7 bits of length) + + A code length of 0 indicates that the corresponding symbol in + the literal/length or distance alphabet will not occur in the + block, and should not participate in the Huffman code + construction algorithm given earlier. If only one distance + code is used, it is encoded using one bit, not zero bits; in + this case there is a single code length of one, with one unused + code. One distance code of zero bits means that there are no + distance codes used at all (the data is all literals). + + We can now define the format of the block: + + 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) + 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) + 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) + + + +Deutsch Informational [Page 13] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + (HCLEN + 4) x 3 bits: code lengths for the code length + alphabet given just above, in the order: 16, 17, 18, + 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + + These code lengths are interpreted as 3-bit integers + (0-7); as above, a code length of 0 means the + corresponding symbol (literal/length or distance code + length) is not used. + + HLIT + 257 code lengths for the literal/length alphabet, + encoded using the code length Huffman code + + HDIST + 1 code lengths for the distance alphabet, + encoded using the code length Huffman code + + The actual compressed data of the block, + encoded using the literal/length and distance Huffman + codes + + The literal/length symbol 256 (end of data), + encoded using the literal/length Huffman code + + The code length repeat codes can cross from HLIT + 257 to the + HDIST + 1 code lengths. In other words, all code lengths form + a single sequence of HLIT + HDIST + 258 values. + + 3.3. Compliance + + A compressor may limit further the ranges of values specified in + the previous section and still be compliant; for example, it may + limit the range of backward pointers to some value smaller than + 32K. Similarly, a compressor may limit the size of blocks so that + a compressible block fits in memory. + + A compliant decompressor must accept the full range of possible + values defined in the previous section, and must accept blocks of + arbitrary size. + +4. Compression algorithm details + + While it is the intent of this document to define the "deflate" + compressed data format without reference to any particular + compression algorithm, the format is related to the compressed + formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below); + since many variations of LZ77 are patented, it is strongly + recommended that the implementor of a compressor follow the general + algorithm presented here, which is known not to be patented per se. + The material in this section is not part of the definition of the + + + +Deutsch Informational [Page 14] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + specification per se, and a compressor need not follow it in order to + be compliant. + + The compressor terminates a block when it determines that starting a + new block with fresh trees would be useful, or when the block size + fills up the compressor's block buffer. + + The compressor uses a chained hash table to find duplicated strings, + using a hash function that operates on 3-byte sequences. At any + given point during compression, let XYZ be the next 3 input bytes to + be examined (not necessarily all different, of course). First, the + compressor examines the hash chain for XYZ. If the chain is empty, + the compressor simply writes out X as a literal byte and advances one + byte in the input. If the hash chain is not empty, indicating that + the sequence XYZ (or, if we are unlucky, some other 3 bytes with the + same hash function value) has occurred recently, the compressor + compares all strings on the XYZ hash chain with the actual input data + sequence starting at the current point, and selects the longest + match. + + The compressor searches the hash chains starting with the most recent + strings, to favor small distances and thus take advantage of the + Huffman encoding. The hash chains are singly linked. There are no + deletions from the hash chains; the algorithm simply discards matches + that are too old. To avoid a worst-case situation, very long hash + chains are arbitrarily truncated at a certain length, determined by a + run-time parameter. + + To improve overall compression, the compressor optionally defers the + selection of matches ("lazy matching"): after a match of length N has + been found, the compressor searches for a longer match starting at + the next input byte. If it finds a longer match, it truncates the + previous match to a length of one (thus producing a single literal + byte) and then emits the longer match. Otherwise, it emits the + original match, and, as described above, advances N bytes before + continuing. + + Run-time parameters also control this "lazy match" procedure. If + compression ratio is most important, the compressor attempts a + complete second search regardless of the length of the first match. + In the normal case, if the current match is "long enough", the + compressor reduces the search for a longer match, thus speeding up + the process. If speed is most important, the compressor inserts new + strings in the hash table only when no match was found, or when the + match is not "too long". This degrades the compression ratio but + saves time since there are both fewer insertions and fewer searches. + + + + + +Deutsch Informational [Page 15] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +5. References + + [1] Huffman, D. A., "A Method for the Construction of Minimum + Redundancy Codes", Proceedings of the Institute of Radio + Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. + + [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data + Compression", IEEE Transactions on Information Theory, Vol. 23, + No. 3, pp. 337-343. + + [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, + available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/ + + [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix + encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. + + [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes," + Comm. ACM, 33,4, April 1990, pp. 449-459. + +6. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data. See + reference [3], for example. + +7. Source code + + Source code for a C language implementation of a "deflate" compliant + compressor and decompressor is available within the zlib package at + ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +8. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Phil Katz designed the deflate format. Jean-Loup Gailly and Mark + Adler wrote the related software described in this specification. + Glenn Randers-Pehrson converted this document to RFC and HTML format. + + + +Deutsch Informational [Page 16] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +9. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch Informational [Page 17] + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/rfc1952.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/rfc1952.txt new file mode 100644 index 00000000..a8e51b45 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/rfc1952.txt @@ -0,0 +1,675 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1952 Aladdin Enterprises +Category: Informational May 1996 + + + GZIP file format specification version 4.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that is + compatible with the widely used GZIP utility. The format includes a + cyclic redundancy check value for detecting data corruption. The + format presently uses the DEFLATE method of compression but can be + easily extended to use other compression methods. The format can be + implemented readily in a manner not covered by patents. + + + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1952 GZIP File Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................. 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 4 + 2.1. Overall conventions ....................................... 4 + 2.2. File format ............................................... 5 + 2.3. Member format ............................................. 5 + 2.3.1. Member header and trailer ........................... 6 + 2.3.1.1. Extra field ................................... 8 + 2.3.1.2. Compliance .................................... 9 + 3. References .................................................. 9 + 4. Security Considerations .................................... 10 + 5. Acknowledgements ........................................... 10 + 6. Author's Address ........................................... 10 + 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11 + 8. Appendix: Sample CRC Code .................................. 11 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can compress or decompress a data stream (as opposed to a + randomly accessible file) to produce another data stream, + using only an a priori bounded amount of intermediate + storage, and hence can be used in data communications or + similar structures such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + + + +Deutsch Informational [Page 2] + +RFC 1952 GZIP File Format Specification May 1996 + + + The data format defined by this specification does not attempt to: + + * Provide random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well as + the best currently available specialized algorithms. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into gzip format and/or decompress data from gzip + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compression method and a file format + (the latter assuming only that a file can store a sequence of + arbitrary bytes). It does not specify any particular interface to + a file system or anything about character sets or encodings + (except for file names and comments, which are optional). + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any file that conforms to all the + specifications presented here; a compliant compressor must produce + files that conform to all the specifications presented here. The + material in the appendices is not part of the specification per se + and is not relevant to compliance. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + There have been no technical changes to the gzip format since + version 4.1 of this specification. In version 4.2, some + terminology was changed, and the sample CRC code was rewritten for + clarity and to eliminate the requirement for the caller to do pre- + and post-conditioning. Version 4.3 is a conversion of the + specification to RFC style. + + + +Deutsch Informational [Page 3] + +RFC 1952 GZIP File Format Specification May 1996 + + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, since + the data format described here is byte- rather than bit-oriented. + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + + +Deutsch Informational [Page 4] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.2. File format + + A gzip file consists of a series of "members" (compressed data + sets). The format of each member is specified in the following + section. The members simply appear one after another in the file, + with no additional information before, between, or after them. + + 2.3. Member format + + Each member has the following structure: + + +---+---+---+---+---+---+---+---+---+---+ + |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) + +---+---+---+---+---+---+---+---+---+---+ + + (if FLG.FEXTRA set) + + +---+---+=================================+ + | XLEN |...XLEN bytes of "extra field"...| (more-->) + +---+---+=================================+ + + (if FLG.FNAME set) + + +=========================================+ + |...original file name, zero-terminated...| (more-->) + +=========================================+ + + (if FLG.FCOMMENT set) + + +===================================+ + |...file comment, zero-terminated...| (more-->) + +===================================+ + + (if FLG.FHCRC set) + + +---+---+ + | CRC16 | + +---+---+ + + +=======================+ + |...compressed blocks...| (more-->) + +=======================+ + + 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | CRC32 | ISIZE | + +---+---+---+---+---+---+---+---+ + + + + +Deutsch Informational [Page 5] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.3.1. Member header and trailer + + ID1 (IDentification 1) + ID2 (IDentification 2) + These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139 + (0x8b, \213), to identify the file as being in gzip format. + + CM (Compression Method) + This identifies the compression method used in the file. CM + = 0-7 are reserved. CM = 8 denotes the "deflate" + compression method, which is the one customarily used by + gzip and which is documented elsewhere. + + FLG (FLaGs) + This flag byte is divided into individual bits as follows: + + bit 0 FTEXT + bit 1 FHCRC + bit 2 FEXTRA + bit 3 FNAME + bit 4 FCOMMENT + bit 5 reserved + bit 6 reserved + bit 7 reserved + + If FTEXT is set, the file is probably ASCII text. This is + an optional indication, which the compressor may set by + checking a small amount of the input data to see whether any + non-ASCII characters are present. In case of doubt, FTEXT + is cleared, indicating binary data. For systems which have + different file formats for ascii text and binary data, the + decompressor can use FTEXT to choose the appropriate format. + We deliberately do not specify the algorithm used to set + this bit, since a compressor always has the option of + leaving it cleared and a decompressor always has the option + of ignoring it and letting some other program handle issues + of data conversion. + + If FHCRC is set, a CRC16 for the gzip header is present, + immediately before the compressed data. The CRC16 consists + of the two least significant bytes of the CRC32 for all + bytes of the gzip header up to and not including the CRC16. + [The FHCRC bit was never set by versions of gzip up to + 1.2.4, even though it was documented with a different + meaning in gzip 1.2.4.] + + If FEXTRA is set, optional extra fields are present, as + described in a following section. + + + +Deutsch Informational [Page 6] + +RFC 1952 GZIP File Format Specification May 1996 + + + If FNAME is set, an original file name is present, + terminated by a zero byte. The name must consist of ISO + 8859-1 (LATIN-1) characters; on operating systems using + EBCDIC or any other character set for file names, the name + must be translated to the ISO LATIN-1 character set. This + is the original name of the file being compressed, with any + directory components removed, and, if the file being + compressed is on a file system with case insensitive names, + forced to lower case. There is no original file name if the + data was compressed from a source other than a named file; + for example, if the source was stdin on a Unix system, there + is no file name. + + If FCOMMENT is set, a zero-terminated file comment is + present. This comment is not interpreted; it is only + intended for human consumption. The comment must consist of + ISO 8859-1 (LATIN-1) characters. Line breaks should be + denoted by a single line feed character (10 decimal). + + Reserved FLG bits must be zero. + + MTIME (Modification TIME) + This gives the most recent modification time of the original + file being compressed. The time is in Unix format, i.e., + seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this + may cause problems for MS-DOS and other systems that use + local rather than Universal time.) If the compressed data + did not come from a file, MTIME is set to the time at which + compression started. MTIME = 0 means no time stamp is + available. + + XFL (eXtra FLags) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + XFL = 2 - compressor used maximum compression, + slowest algorithm + XFL = 4 - compressor used fastest algorithm + + OS (Operating System) + This identifies the type of file system on which compression + took place. This may be useful in determining end-of-line + convention for text files. The currently defined values are + as follows: + + + + + + +Deutsch Informational [Page 7] + +RFC 1952 GZIP File Format Specification May 1996 + + + 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) + 1 - Amiga + 2 - VMS (or OpenVMS) + 3 - Unix + 4 - VM/CMS + 5 - Atari TOS + 6 - HPFS filesystem (OS/2, NT) + 7 - Macintosh + 8 - Z-System + 9 - CP/M + 10 - TOPS-20 + 11 - NTFS filesystem (NT) + 12 - QDOS + 13 - Acorn RISCOS + 255 - unknown + + XLEN (eXtra LENgth) + If FLG.FEXTRA is set, this gives the length of the optional + extra field. See below for details. + + CRC32 (CRC-32) + This contains a Cyclic Redundancy Check value of the + uncompressed data computed according to CRC-32 algorithm + used in the ISO 3309 standard and in section 8.1.1.6.2 of + ITU-T recommendation V.42. (See http://www.iso.ch for + ordering ISO documents. See gopher://info.itu.ch for an + online version of ITU-T V.42.) + + ISIZE (Input SIZE) + This contains the size of the original (uncompressed) input + data modulo 2^32. + + 2.3.1.1. Extra field + + If the FLG.FEXTRA bit is set, an "extra field" is present in + the header, with total length XLEN bytes. It consists of a + series of subfields, each of the form: + + +---+---+---+---+==================================+ + |SI1|SI2| LEN |... LEN bytes of subfield data ...| + +---+---+---+---+==================================+ + + SI1 and SI2 provide a subfield ID, typically two ASCII letters + with some mnemonic value. Jean-Loup Gailly + is maintaining a registry of subfield + IDs; please send him any subfield ID you wish to use. Subfield + IDs with SI2 = 0 are reserved for future use. The following + IDs are currently defined: + + + +Deutsch Informational [Page 8] + +RFC 1952 GZIP File Format Specification May 1996 + + + SI1 SI2 Data + ---------- ---------- ---- + 0x41 ('A') 0x70 ('P') Apollo file type information + + LEN gives the length of the subfield data, excluding the 4 + initial bytes. + + 2.3.1.2. Compliance + + A compliant compressor must produce files with correct ID1, + ID2, CM, CRC32, and ISIZE, but may set all the other fields in + the fixed-length part of the header to default values (255 for + OS, 0 for all others). The compressor must set all reserved + bits to zero. + + A compliant decompressor must check ID1, ID2, and CM, and + provide an error indication if any of these have incorrect + values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC + at least so it can skip over the optional fields if they are + present. It need not examine any other part of the header or + trailer; in particular, a decompressor may ignore FTEXT and OS + and always produce binary output, and still be compliant. A + compliant decompressor must give an error indication if any + reserved bit is non-zero, since such a bit could indicate the + presence of a new field that would cause subsequent data to be + interpreted incorrectly. + +3. References + + [1] "Information Processing - 8-bit single-byte coded graphic + character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). + The ISO 8859-1 (Latin-1) character set is a superset of 7-bit + ASCII. Files defining this character set are available as + iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/ + + [2] ISO 3309 + + [3] ITU-T recommendation V.42 + + [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in + ftp://prep.ai.mit.edu/pub/gnu/ + + [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table + Look-Up", Communications of the ACM, 31(8), pp.1008-1013. + + + + +Deutsch Informational [Page 9] + +RFC 1952 GZIP File Format Specification May 1996 + + + [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, + pp.118-133. + + [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, + describing the CRC concept. + +4. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data, such as by + setting and checking the CRC-32 check value. + +5. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +6. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + +Deutsch Informational [Page 10] + +RFC 1952 GZIP File Format Specification May 1996 + + +7. Appendix: Jean-Loup Gailly's gzip utility + + The most widely used implementation of gzip compression, and the + original documentation on which this specification is based, were + created by Jean-Loup Gailly . Since this + implementation is a de facto standard, we mention some more of its + features here. Again, the material in this section is not part of + the specification per se, and implementations need not follow it to + be compliant. + + When compressing or decompressing a file, gzip preserves the + protection, ownership, and modification time attributes on the local + file system, since there is no provision for representing protection + attributes in the gzip file format itself. Since the file format + includes a modification time, the gzip decompressor provides a + command line switch that assigns the modification time from the file, + rather than the local modification time of the compressed input, to + the decompressed output. + +8. Appendix: Sample CRC Code + + The following sample code represents a practical implementation of + the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42 + for a formal specification.) + + The sample code is in the ANSI C programming language. Non C users + may find it easier to read with these hints: + + & Bitwise AND operator. + ^ Bitwise exclusive-OR operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero + bit(s) at the left. + ! Logical NOT operator. + ++ "n++" increments the variable n. + 0xNNN 0x introduces a hexadecimal (base 16) constant. + Suffix L indicates a long value (at least 32 bits). + + /* Table of CRCs of all 8-bit messages. */ + unsigned long crc_table[256]; + + /* Flag: has the table been computed? Initially false. */ + int crc_table_computed = 0; + + /* Make the table for a fast CRC. */ + void make_crc_table(void) + { + unsigned long c; + + + +Deutsch Informational [Page 11] + +RFC 1952 GZIP File Format Specification May 1996 + + + int n, k; + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) { + c = 0xedb88320L ^ (c >> 1); + } else { + c = c >> 1; + } + } + crc_table[n] = c; + } + crc_table_computed = 1; + } + + /* + Update a running crc with the bytes buf[0..len-1] and return + the updated crc. The crc should be initialized to zero. Pre- and + post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the caller. Usage example: + + unsigned long crc = 0L; + + while (read_buffer(buffer, length) != EOF) { + crc = update_crc(crc, buffer, length); + } + if (crc != original_crc) error(); + */ + unsigned long update_crc(unsigned long crc, + unsigned char *buf, int len) + { + unsigned long c = crc ^ 0xffffffffL; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c ^ 0xffffffffL; + } + + /* Return the CRC of the bytes buf[0..len-1]. */ + unsigned long crc(unsigned char *buf, int len) + { + return update_crc(0L, buf, len); + } + + + + +Deutsch Informational [Page 12] + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/txtvsbin.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/txtvsbin.txt new file mode 100644 index 00000000..3d0f0634 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/doc/txtvsbin.txt @@ -0,0 +1,107 @@ +A Fast Method for Identifying Plain Text Files +============================================== + + +Introduction +------------ + +Given a file coming from an unknown source, it is sometimes desirable +to find out whether the format of that file is plain text. Although +this may appear like a simple task, a fully accurate detection of the +file type requires heavy-duty semantic analysis on the file contents. +It is, however, possible to obtain satisfactory results by employing +various heuristics. + +Previous versions of PKZip and other zip-compatible compression tools +were using a crude detection scheme: if more than 80% (4/5) of the bytes +found in a certain buffer are within the range [7..127], the file is +labeled as plain text, otherwise it is labeled as binary. A prominent +limitation of this scheme is the restriction to Latin-based alphabets. +Other alphabets, like Greek, Cyrillic or Asian, make extensive use of +the bytes within the range [128..255], and texts using these alphabets +are most often misidentified by this scheme; in other words, the rate +of false negatives is sometimes too high, which means that the recall +is low. Another weakness of this scheme is a reduced precision, due to +the false positives that may occur when binary files containing large +amounts of textual characters are misidentified as plain text. + +In this article we propose a new, simple detection scheme that features +a much increased precision and a near-100% recall. This scheme is +designed to work on ASCII, Unicode and other ASCII-derived alphabets, +and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.) +and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings +(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however. + + +The Algorithm +------------- + +The algorithm works by dividing the set of bytecodes [0..255] into three +categories: +- The white list of textual bytecodes: + 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. +- The gray list of tolerated bytecodes: + 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). +- The black list of undesired, non-textual bytecodes: + 0 (NUL) to 6, 14 to 31. + +If a file contains at least one byte that belongs to the white list and +no byte that belongs to the black list, then the file is categorized as +plain text; otherwise, it is categorized as binary. (The boundary case, +when the file is empty, automatically falls into the latter category.) + + +Rationale +--------- + +The idea behind this algorithm relies on two observations. + +The first observation is that, although the full range of 7-bit codes +[0..127] is properly specified by the ASCII standard, most control +characters in the range [0..31] are not used in practice. The only +widely-used, almost universally-portable control codes are 9 (TAB), +10 (LF) and 13 (CR). There are a few more control codes that are +recognized on a reduced range of platforms and text viewers/editors: +7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these +codes are rarely (if ever) used alone, without being accompanied by +some printable text. Even the newer, portable text formats such as +XML avoid using control characters outside the list mentioned here. + +The second observation is that most of the binary files tend to contain +control characters, especially 0 (NUL). Even though the older text +detection schemes observe the presence of non-ASCII codes from the range +[128..255], the precision rarely has to suffer if this upper range is +labeled as textual, because the files that are genuinely binary tend to +contain both control characters and codes from the upper range. On the +other hand, the upper range needs to be labeled as textual, because it +is used by virtually all ASCII extensions. In particular, this range is +used for encoding non-Latin scripts. + +Since there is no counting involved, other than simply observing the +presence or the absence of some byte values, the algorithm produces +consistent results, regardless what alphabet encoding is being used. +(If counting were involved, it could be possible to obtain different +results on a text encoded, say, using ISO-8859-16 versus UTF-8.) + +There is an extra category of plain text files that are "polluted" with +one or more black-listed codes, either by mistake or by peculiar design +considerations. In such cases, a scheme that tolerates a small fraction +of black-listed codes would provide an increased recall (i.e. more true +positives). This, however, incurs a reduced precision overall, since +false positives are more likely to appear in binary files that contain +large chunks of textual data. Furthermore, "polluted" plain text should +be regarded as binary by general-purpose text detection schemes, because +general-purpose text processing algorithms might not be applicable. +Under this premise, it is safe to say that our detection method provides +a near-100% recall. + +Experiments have been run on many files coming from various platforms +and applications. We tried plain text files, system logs, source code, +formatted office documents, compiled object code, etc. The results +confirm the optimistic assumptions about the capabilities of this +algorithm. + + +-- +Cosmin Truta +Last updated: 2006-May-28 diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/README.examples b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/README.examples new file mode 100644 index 00000000..56a31714 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/README.examples @@ -0,0 +1,49 @@ +This directory contains examples of the use of zlib and other relevant +programs and documentation. + +enough.c + calculation and justification of ENOUGH parameter in inftrees.h + - calculates the maximum table space used in inflate tree + construction over all possible Huffman codes + +fitblk.c + compress just enough input to nearly fill a requested output size + - zlib isn't designed to do this, but fitblk does it anyway + +gun.c + uncompress a gzip file + - illustrates the use of inflateBack() for high speed file-to-file + decompression using call-back functions + - is approximately twice as fast as gzip -d + - also provides Unix uncompress functionality, again twice as fast + +gzappend.c + append to a gzip file + - illustrates the use of the Z_BLOCK flush parameter for inflate() + - illustrates the use of deflatePrime() to start at any bit + +gzjoin.c + join gzip files without recalculating the crc or recompressing + - illustrates the use of the Z_BLOCK flush parameter for inflate() + - illustrates the use of crc32_combine() + +gzlog.c +gzlog.h + efficiently and robustly maintain a message log file in gzip format + - illustrates use of raw deflate, Z_PARTIAL_FLUSH, deflatePrime(), + and deflateSetDictionary() + - illustrates use of a gzip header extra field + +zlib_how.html + painfully comprehensive description of zpipe.c (see below) + - describes in excruciating detail the use of deflate() and inflate() + +zpipe.c + reads and writes zlib streams from stdin to stdout + - illustrates the proper use of deflate() and inflate() + - deeply commented in zlib_how.html (see above) + +zran.c + index a zlib or gzip stream and randomly access it + - illustrates the use of Z_BLOCK, inflatePrime(), and + inflateSetDictionary() to provide random access diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/enough.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/enough.c new file mode 100644 index 00000000..c40410ba --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/enough.c @@ -0,0 +1,569 @@ +/* enough.c -- determine the maximum size of inflate's Huffman code tables over + * all possible valid and complete Huffman codes, subject to a length limit. + * Copyright (C) 2007, 2008 Mark Adler + * Version 1.3 17 February 2008 Mark Adler + */ + +/* Version history: + 1.0 3 Jan 2007 First version (derived from codecount.c version 1.4) + 1.1 4 Jan 2007 Use faster incremental table usage computation + Prune examine() search on previously visited states + 1.2 5 Jan 2007 Comments clean up + As inflate does, decrease root for short codes + Refuse cases where inflate would increase root + 1.3 17 Feb 2008 Add argument for initial root table size + Fix bug for initial root table size == max - 1 + Use a macro to compute the history index + */ + +/* + Examine all possible Huffman codes for a given number of symbols and a + maximum code length in bits to determine the maximum table size for zilb's + inflate. Only complete Huffman codes are counted. + + Two codes are considered distinct if the vectors of the number of codes per + length are not identical. So permutations of the symbol assignments result + in the same code for the counting, as do permutations of the assignments of + the bit values to the codes (i.e. only canonical codes are counted). + + We build a code from shorter to longer lengths, determining how many symbols + are coded at each length. At each step, we have how many symbols remain to + be coded, what the last code length used was, and how many bit patterns of + that length remain unused. Then we add one to the code length and double the + number of unused patterns to graduate to the next code length. We then + assign all portions of the remaining symbols to that code length that + preserve the properties of a correct and eventually complete code. Those + properties are: we cannot use more bit patterns than are available; and when + all the symbols are used, there are exactly zero possible bit patterns + remaining. + + The inflate Huffman decoding algorithm uses two-level lookup tables for + speed. There is a single first-level table to decode codes up to root bits + in length (root == 9 in the current inflate implementation). The table + has 1 << root entries and is indexed by the next root bits of input. Codes + shorter than root bits have replicated table entries, so that the correct + entry is pointed to regardless of the bits that follow the short code. If + the code is longer than root bits, then the table entry points to a second- + level table. The size of that table is determined by the longest code with + that root-bit prefix. If that longest code has length len, then the table + has size 1 << (len - root), to index the remaining bits in that set of + codes. Each subsequent root-bit prefix then has its own sub-table. The + total number of table entries required by the code is calculated + incrementally as the number of codes at each bit length is populated. When + all of the codes are shorter than root bits, then root is reduced to the + longest code length, resulting in a single, smaller, one-level table. + + The inflate algorithm also provides for small values of root (relative to + the log2 of the number of symbols), where the shortest code has more bits + than root. In that case, root is increased to the length of the shortest + code. This program, by design, does not handle that case, so it is verified + that the number of symbols is less than 2^(root + 1). + + In order to speed up the examination (by about ten orders of magnitude for + the default arguments), the intermediate states in the build-up of a code + are remembered and previously visited branches are pruned. The memory + required for this will increase rapidly with the total number of symbols and + the maximum code length in bits. However this is a very small price to pay + for the vast speedup. + + First, all of the possible Huffman codes are counted, and reachable + intermediate states are noted by a non-zero count in a saved-results array. + Second, the intermediate states that lead to (root + 1) bit or longer codes + are used to look at all sub-codes from those junctures for their inflate + memory usage. (The amount of memory used is not affected by the number of + codes of root bits or less in length.) Third, the visited states in the + construction of those sub-codes and the associated calculation of the table + size is recalled in order to avoid recalculating from the same juncture. + Beginning the code examination at (root + 1) bit codes, which is enabled by + identifying the reachable nodes, accounts for about six of the orders of + magnitude of improvement for the default arguments. About another four + orders of magnitude come from not revisiting previous states. Out of + approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes + need to be examined to cover all of the possible table memory usage cases + for the default arguments of 286 symbols limited to 15-bit codes. + + Note that an unsigned long long type is used for counting. It is quite easy + to exceed the capacity of an eight-byte integer with a large number of + symbols and a large maximum code length, so multiple-precision arithmetic + would need to replace the unsigned long long arithmetic in that case. This + program will abort if an overflow occurs. The big_t type identifies where + the counting takes place. + + An unsigned long long type is also used for calculating the number of + possible codes remaining at the maximum length. This limits the maximum + code length to the number of bits in a long long minus the number of bits + needed to represent the symbols in a flat code. The code_t type identifies + where the bit pattern counting takes place. + */ + +#include +#include +#include +#include + +#define local static + +/* special data types */ +typedef unsigned long long big_t; /* type for code counting */ +typedef unsigned long long code_t; /* type for bit pattern counting */ +struct tab { /* type for been here check */ + size_t len; /* length of bit vector in char's */ + char *vec; /* allocated bit vector */ +}; + +/* The array for saving results, num[], is indexed with this triplet: + + syms: number of symbols remaining to code + left: number of available bit patterns at length len + len: number of bits in the codes currently being assigned + + Those indices are constrained thusly when saving results: + + syms: 3..totsym (totsym == total symbols to code) + left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6) + len: 1..max - 1 (max == maximum code length in bits) + + syms == 2 is not saved since that immediately leads to a single code. left + must be even, since it represents the number of available bit patterns at + the current length, which is double the number at the previous length. + left ends at syms-1 since left == syms immediately results in a single code. + (left > sym is not allowed since that would result in an incomplete code.) + len is less than max, since the code completes immediately when len == max. + + The offset into the array is calculated for the three indices with the + first one (syms) being outermost, and the last one (len) being innermost. + We build the array with length max-1 lists for the len index, with syms-3 + of those for each symbol. There are totsym-2 of those, with each one + varying in length as a function of sym. See the calculation of index in + count() for the index, and the calculation of size in main() for the size + of the array. + + For the deflate example of 286 symbols limited to 15-bit codes, the array + has 284,284 entries, taking up 2.17 MB for an 8-byte big_t. More than + half of the space allocated for saved results is actually used -- not all + possible triplets are reached in the generation of valid Huffman codes. + */ + +/* The array for tracking visited states, done[], is itself indexed identically + to the num[] array as described above for the (syms, left, len) triplet. + Each element in the array is further indexed by the (mem, rem) doublet, + where mem is the amount of inflate table space used so far, and rem is the + remaining unused entries in the current inflate sub-table. Each indexed + element is simply one bit indicating whether the state has been visited or + not. Since the ranges for mem and rem are not known a priori, each bit + vector is of a variable size, and grows as needed to accommodate the visited + states. mem and rem are used to calculate a single index in a triangular + array. Since the range of mem is expected in the default case to be about + ten times larger than the range of rem, the array is skewed to reduce the + memory usage, with eight times the range for mem than for rem. See the + calculations for offset and bit in beenhere() for the details. + + For the deflate example of 286 symbols limited to 15-bit codes, the bit + vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[] + array itself. + */ + +/* Globals to avoid propagating constants or constant pointers recursively */ +local int max; /* maximum allowed bit length for the codes */ +local int root; /* size of base code table in bits */ +local int large; /* largest code table so far */ +local size_t size; /* number of elements in num and done */ +local int *code; /* number of symbols assigned to each bit length */ +local big_t *num; /* saved results array for code counting */ +local struct tab *done; /* states already evaluated array */ + +/* Index function for num[] and done[] */ +#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1) + +/* Free allocated space. Uses globals code, num, and done. */ +local void cleanup(void) +{ + size_t n; + + if (done != NULL) { + for (n = 0; n < size; n++) + if (done[n].len) + free(done[n].vec); + free(done); + } + if (num != NULL) + free(num); + if (code != NULL) + free(code); +} + +/* Return the number of possible Huffman codes using bit patterns of lengths + len through max inclusive, coding syms symbols, with left bit patterns of + length len unused -- return -1 if there is an overflow in the counting. + Keep a record of previous results in num to prevent repeating the same + calculation. Uses the globals max and num. */ +local big_t count(int syms, int len, int left) +{ + big_t sum; /* number of possible codes from this juncture */ + big_t got; /* value returned from count() */ + int least; /* least number of syms to use at this juncture */ + int most; /* most number of syms to use at this juncture */ + int use; /* number of bit patterns to use in next call */ + size_t index; /* index of this case in *num */ + + /* see if only one possible code */ + if (syms == left) + return 1; + + /* note and verify the expected state */ + assert(syms > left && left > 0 && len < max); + + /* see if we've done this one already */ + index = INDEX(syms, left, len); + got = num[index]; + if (got) + return got; /* we have -- return the saved result */ + + /* we need to use at least this many bit patterns so that the code won't be + incomplete at the next length (more bit patterns than symbols) */ + least = (left << 1) - syms; + if (least < 0) + least = 0; + + /* we can use at most this many bit patterns, lest there not be enough + available for the remaining symbols at the maximum length (if there were + no limit to the code length, this would become: most = left - 1) */ + most = (((code_t)left << (max - len)) - syms) / + (((code_t)1 << (max - len)) - 1); + + /* count all possible codes from this juncture and add them up */ + sum = 0; + for (use = least; use <= most; use++) { + got = count(syms - use, len + 1, (left - use) << 1); + sum += got; + if (got == -1 || sum < got) /* overflow */ + return -1; + } + + /* verify that all recursive calls are productive */ + assert(sum != 0); + + /* save the result and return it */ + num[index] = sum; + return sum; +} + +/* Return true if we've been here before, set to true if not. Set a bit in a + bit vector to indicate visiting this state. Each (syms,len,left) state + has a variable size bit vector indexed by (mem,rem). The bit vector is + lengthened if needed to allow setting the (mem,rem) bit. */ +local int beenhere(int syms, int len, int left, int mem, int rem) +{ + size_t index; /* index for this state's bit vector */ + size_t offset; /* offset in this state's bit vector */ + int bit; /* mask for this state's bit */ + size_t length; /* length of the bit vector in bytes */ + char *vector; /* new or enlarged bit vector */ + + /* point to vector for (syms,left,len), bit in vector for (mem,rem) */ + index = INDEX(syms, left, len); + mem -= 1 << root; + offset = (mem >> 3) + rem; + offset = ((offset * (offset + 1)) >> 1) + rem; + bit = 1 << (mem & 7); + + /* see if we've been here */ + length = done[index].len; + if (offset < length && (done[index].vec[offset] & bit) != 0) + return 1; /* done this! */ + + /* we haven't been here before -- set the bit to show we have now */ + + /* see if we need to lengthen the vector in order to set the bit */ + if (length <= offset) { + /* if we have one already, enlarge it, zero out the appended space */ + if (length) { + do { + length <<= 1; + } while (length <= offset); + vector = realloc(done[index].vec, length); + if (vector != NULL) + memset(vector + done[index].len, 0, length - done[index].len); + } + + /* otherwise we need to make a new vector and zero it out */ + else { + length = 1 << (len - root); + while (length <= offset) + length <<= 1; + vector = calloc(length, sizeof(char)); + } + + /* in either case, bail if we can't get the memory */ + if (vector == NULL) { + fputs("abort: unable to allocate enough memory\n", stderr); + cleanup(); + exit(1); + } + + /* install the new vector */ + done[index].len = length; + done[index].vec = vector; + } + + /* set the bit */ + done[index].vec[offset] |= bit; + return 0; +} + +/* Examine all possible codes from the given node (syms, len, left). Compute + the amount of memory required to build inflate's decoding tables, where the + number of code structures used so far is mem, and the number remaining in + the current sub-table is rem. Uses the globals max, code, root, large, and + done. */ +local void examine(int syms, int len, int left, int mem, int rem) +{ + int least; /* least number of syms to use at this juncture */ + int most; /* most number of syms to use at this juncture */ + int use; /* number of bit patterns to use in next call */ + + /* see if we have a complete code */ + if (syms == left) { + /* set the last code entry */ + code[len] = left; + + /* complete computation of memory used by this code */ + while (rem < left) { + left -= rem; + rem = 1 << (len - root); + mem += rem; + } + assert(rem == left); + + /* if this is a new maximum, show the entries used and the sub-code */ + if (mem > large) { + large = mem; + printf("max %d: ", mem); + for (use = root + 1; use <= max; use++) + if (code[use]) + printf("%d[%d] ", code[use], use); + putchar('\n'); + fflush(stdout); + } + + /* remove entries as we drop back down in the recursion */ + code[len] = 0; + return; + } + + /* prune the tree if we can */ + if (beenhere(syms, len, left, mem, rem)) + return; + + /* we need to use at least this many bit patterns so that the code won't be + incomplete at the next length (more bit patterns than symbols) */ + least = (left << 1) - syms; + if (least < 0) + least = 0; + + /* we can use at most this many bit patterns, lest there not be enough + available for the remaining symbols at the maximum length (if there were + no limit to the code length, this would become: most = left - 1) */ + most = (((code_t)left << (max - len)) - syms) / + (((code_t)1 << (max - len)) - 1); + + /* occupy least table spaces, creating new sub-tables as needed */ + use = least; + while (rem < use) { + use -= rem; + rem = 1 << (len - root); + mem += rem; + } + rem -= use; + + /* examine codes from here, updating table space as we go */ + for (use = least; use <= most; use++) { + code[len] = use; + examine(syms - use, len + 1, (left - use) << 1, + mem + (rem ? 1 << (len - root) : 0), rem << 1); + if (rem == 0) { + rem = 1 << (len - root); + mem += rem; + } + rem--; + } + + /* remove entries as we drop back down in the recursion */ + code[len] = 0; +} + +/* Look at all sub-codes starting with root + 1 bits. Look at only the valid + intermediate code states (syms, left, len). For each completed code, + calculate the amount of memory required by inflate to build the decoding + tables. Find the maximum amount of memory required and show the code that + requires that maximum. Uses the globals max, root, and num. */ +local void enough(int syms) +{ + int n; /* number of remaing symbols for this node */ + int left; /* number of unused bit patterns at this length */ + size_t index; /* index of this case in *num */ + + /* clear code */ + for (n = 0; n <= max; n++) + code[n] = 0; + + /* look at all (root + 1) bit and longer codes */ + large = 1 << root; /* base table */ + if (root < max) /* otherwise, there's only a base table */ + for (n = 3; n <= syms; n++) + for (left = 2; left < n; left += 2) + { + /* look at all reachable (root + 1) bit nodes, and the + resulting codes (complete at root + 2 or more) */ + index = INDEX(n, left, root + 1); + if (root + 1 < max && num[index]) /* reachable node */ + examine(n, root + 1, left, 1 << root, 0); + + /* also look at root bit codes with completions at root + 1 + bits (not saved in num, since complete), just in case */ + if (num[index - 1] && n <= left << 1) + examine((n - left) << 1, root + 1, (n - left) << 1, + 1 << root, 0); + } + + /* done */ + printf("done: maximum of %d table entries\n", large); +} + +/* + Examine and show the total number of possible Huffman codes for a given + maximum number of symbols, initial root table size, and maximum code length + in bits -- those are the command arguments in that order. The default + values are 286, 9, and 15 respectively, for the deflate literal/length code. + The possible codes are counted for each number of coded symbols from two to + the maximum. The counts for each of those and the total number of codes are + shown. The maximum number of inflate table entires is then calculated + across all possible codes. Each new maximum number of table entries and the + associated sub-code (starting at root + 1 == 10 bits) is shown. + + To count and examine Huffman codes that are not length-limited, provide a + maximum length equal to the number of symbols minus one. + + For the deflate literal/length code, use "enough". For the deflate distance + code, use "enough 30 6". + + This uses the %llu printf format to print big_t numbers, which assumes that + big_t is an unsigned long long. If the big_t type is changed (for example + to a multiple precision type), the method of printing will also need to be + updated. + */ +int main(int argc, char **argv) +{ + int syms; /* total number of symbols to code */ + int n; /* number of symbols to code for this run */ + big_t got; /* return value of count() */ + big_t sum; /* accumulated number of codes over n */ + + /* set up globals for cleanup() */ + code = NULL; + num = NULL; + done = NULL; + + /* get arguments -- default to the deflate literal/length code */ + syms = 286; + root = 9; + max = 15; + if (argc > 1) { + syms = atoi(argv[1]); + if (argc > 2) { + root = atoi(argv[2]); + if (argc > 3) + max = atoi(argv[3]); + } + } + if (argc > 4 || syms < 2 || root < 1 || max < 1) { + fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n", + stderr); + return 1; + } + + /* if not restricting the code length, the longest is syms - 1 */ + if (max > syms - 1) + max = syms - 1; + + /* determine the number of bits in a code_t */ + n = 0; + while (((code_t)1 << n) != 0) + n++; + + /* make sure that the calculation of most will not overflow */ + if (max > n || syms - 2 >= (((code_t)0 - 1) >> (max - 1))) { + fputs("abort: code length too long for internal types\n", stderr); + return 1; + } + + /* reject impossible code requests */ + if (syms - 1 > ((code_t)1 << max) - 1) { + fprintf(stderr, "%d symbols cannot be coded in %d bits\n", + syms, max); + return 1; + } + + /* allocate code vector */ + code = calloc(max + 1, sizeof(int)); + if (code == NULL) { + fputs("abort: unable to allocate enough memory\n", stderr); + return 1; + } + + /* determine size of saved results array, checking for overflows, + allocate and clear the array (set all to zero with calloc()) */ + if (syms == 2) /* iff max == 1 */ + num = NULL; /* won't be saving any results */ + else { + size = syms >> 1; + if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) || + (size *= n, size > ((size_t)0 - 1) / (n = max - 1)) || + (size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) || + (num = calloc(size, sizeof(big_t))) == NULL) { + fputs("abort: unable to allocate enough memory\n", stderr); + cleanup(); + return 1; + } + } + + /* count possible codes for all numbers of symbols, add up counts */ + sum = 0; + for (n = 2; n <= syms; n++) { + got = count(n, 1, 2); + sum += got; + if (got == -1 || sum < got) { /* overflow */ + fputs("abort: can't count that high!\n", stderr); + cleanup(); + return 1; + } + printf("%llu %d-codes\n", got, n); + } + printf("%llu total codes for 2 to %d symbols", sum, syms); + if (max < syms - 1) + printf(" (%d-bit length limit)\n", max); + else + puts(" (no length limit)"); + + /* allocate and clear done array for beenhere() */ + if (syms == 2) + done = NULL; + else if (size > ((size_t)0 - 1) / sizeof(struct tab) || + (done = calloc(size, sizeof(struct tab))) == NULL) { + fputs("abort: unable to allocate enough memory\n", stderr); + cleanup(); + return 1; + } + + /* find and show maximum inflate table usage */ + if (root > max) /* reduce root to max length */ + root = max; + if (syms < ((code_t)1 << (root + 1))) + enough(syms); + else + puts("cannot handle minimum code lengths > root"); + + /* done */ + cleanup(); + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/fitblk.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/fitblk.c new file mode 100644 index 00000000..c61de5c9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/fitblk.c @@ -0,0 +1,233 @@ +/* fitblk.c: example of fitting compressed output to a specified size + Not copyrighted -- provided to the public domain + Version 1.1 25 November 2004 Mark Adler */ + +/* Version history: + 1.0 24 Nov 2004 First version + 1.1 25 Nov 2004 Change deflateInit2() to deflateInit() + Use fixed-size, stack-allocated raw buffers + Simplify code moving compression to subroutines + Use assert() for internal errors + Add detailed description of approach + */ + +/* Approach to just fitting a requested compressed size: + + fitblk performs three compression passes on a portion of the input + data in order to determine how much of that input will compress to + nearly the requested output block size. The first pass generates + enough deflate blocks to produce output to fill the requested + output size plus a specfied excess amount (see the EXCESS define + below). The last deflate block may go quite a bit past that, but + is discarded. The second pass decompresses and recompresses just + the compressed data that fit in the requested plus excess sized + buffer. The deflate process is terminated after that amount of + input, which is less than the amount consumed on the first pass. + The last deflate block of the result will be of a comparable size + to the final product, so that the header for that deflate block and + the compression ratio for that block will be about the same as in + the final product. The third compression pass decompresses the + result of the second step, but only the compressed data up to the + requested size minus an amount to allow the compressed stream to + complete (see the MARGIN define below). That will result in a + final compressed stream whose length is less than or equal to the + requested size. Assuming sufficient input and a requested size + greater than a few hundred bytes, the shortfall will typically be + less than ten bytes. + + If the input is short enough that the first compression completes + before filling the requested output size, then that compressed + stream is return with no recompression. + + EXCESS is chosen to be just greater than the shortfall seen in a + two pass approach similar to the above. That shortfall is due to + the last deflate block compressing more efficiently with a smaller + header on the second pass. EXCESS is set to be large enough so + that there is enough uncompressed data for the second pass to fill + out the requested size, and small enough so that the final deflate + block of the second pass will be close in size to the final deflate + block of the third and final pass. MARGIN is chosen to be just + large enough to assure that the final compression has enough room + to complete in all cases. + */ + +#include +#include +#include +#include "zlib.h" + +#define local static + +/* print nastygram and leave */ +local void quit(char *why) +{ + fprintf(stderr, "fitblk abort: %s\n", why); + exit(1); +} + +#define RAWLEN 4096 /* intermediate uncompressed buffer size */ + +/* compress from file to def until provided buffer is full or end of + input reached; return last deflate() return value, or Z_ERRNO if + there was read error on the file */ +local int partcompress(FILE *in, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + def->avail_in = fread(raw, 1, RAWLEN, in); + if (ferror(in)) + return Z_ERRNO; + def->next_in = raw; + if (feof(in)) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (def->avail_out != 0 && flush == Z_NO_FLUSH); + return ret; +} + +/* recompress from inf's input to def's output; the input for inf and + the output for def are set in those structures before calling; + return last deflate() return value, or Z_MEM_ERROR if inflate() + was not able to allocate enough memory when it needed to */ +local int recompress(z_streamp inf, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + /* decompress */ + inf->avail_out = RAWLEN; + inf->next_out = raw; + ret = inflate(inf, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR && + ret != Z_NEED_DICT); + if (ret == Z_MEM_ERROR) + return ret; + + /* compress what was decompresed until done or no room */ + def->avail_in = RAWLEN - inf->avail_out; + def->next_in = raw; + if (inf->avail_out != 0) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (ret != Z_STREAM_END && def->avail_out != 0); + return ret; +} + +#define EXCESS 256 /* empirically determined stream overage */ +#define MARGIN 8 /* amount to back off for completion */ + +/* compress from stdin to fixed-size block on stdout */ +int main(int argc, char **argv) +{ + int ret; /* return code */ + unsigned size; /* requested fixed output block size */ + unsigned have; /* bytes written by deflate() call */ + unsigned char *blk; /* intermediate and final stream */ + unsigned char *tmp; /* close to desired size stream */ + z_stream def, inf; /* zlib deflate and inflate states */ + + /* get requested output size */ + if (argc != 2) + quit("need one argument: size of output block"); + ret = strtol(argv[1], argv + 1, 10); + if (argv[1][0] != 0) + quit("argument must be a number"); + if (ret < 8) /* 8 is minimum zlib stream size */ + quit("need positive size of 8 or greater"); + size = (unsigned)ret; + + /* allocate memory for buffers and compression engine */ + blk = malloc(size + EXCESS); + def.zalloc = Z_NULL; + def.zfree = Z_NULL; + def.opaque = Z_NULL; + ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); + if (ret != Z_OK || blk == NULL) + quit("out of memory"); + + /* compress from stdin until output full, or no more input */ + def.avail_out = size + EXCESS; + def.next_out = blk; + ret = partcompress(stdin, &def); + if (ret == Z_ERRNO) + quit("error reading input"); + + /* if it all fit, then size was undersubscribed -- done! */ + if (ret == Z_STREAM_END && def.avail_out >= EXCESS) { + /* write block to stdout */ + have = size + EXCESS - def.avail_out; + if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) + quit("error writing output"); + + /* clean up and print results to stderr */ + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (all input)\n", + size - have, size); + return 0; + } + + /* it didn't all fit -- set up for recompression */ + inf.zalloc = Z_NULL; + inf.zfree = Z_NULL; + inf.opaque = Z_NULL; + inf.avail_in = 0; + inf.next_in = Z_NULL; + ret = inflateInit(&inf); + tmp = malloc(size + EXCESS); + if (ret != Z_OK || tmp == NULL) + quit("out of memory"); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do first recompression close to the right amount */ + inf.avail_in = size + EXCESS; + inf.next_in = blk; + def.avail_out = size + EXCESS; + def.next_out = tmp; + ret = recompress(&inf, &def); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + + /* set up for next reocmpression */ + ret = inflateReset(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do second and final recompression (third compression) */ + inf.avail_in = size - MARGIN; /* assure stream will complete */ + inf.next_in = tmp; + def.avail_out = size; + def.next_out = blk; + ret = recompress(&inf, &def); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */ + + /* done -- write block to stdout */ + have = size - def.avail_out; + if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) + quit("error writing output"); + + /* clean up and print results to stderr */ + free(tmp); + ret = inflateEnd(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (%lu input)\n", + size - have, size, def.total_in); + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gun.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gun.c new file mode 100644 index 00000000..72b0882a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gun.c @@ -0,0 +1,701 @@ +/* gun.c -- simple gunzip to give an example of the use of inflateBack() + * Copyright (C) 2003, 2005, 2008, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + Version 1.6 17 January 2010 Mark Adler */ + +/* Version history: + 1.0 16 Feb 2003 First version for testing of inflateBack() + 1.1 21 Feb 2005 Decompress concatenated gzip streams + Remove use of "this" variable (C++ keyword) + Fix return value for in() + Improve allocation failure checking + Add typecasting for void * structures + Add -h option for command version and usage + Add a bunch of comments + 1.2 20 Mar 2005 Add Unix compress (LZW) decompression + Copy file attributes from input file to output file + 1.3 12 Jun 2005 Add casts for error messages [Oberhumer] + 1.4 8 Dec 2006 LZW decompression speed improvements + 1.5 9 Feb 2008 Avoid warning in latest version of gcc + 1.6 17 Jan 2010 Avoid signed/unsigned comparison warnings + */ + +/* + gun [ -t ] [ name ... ] + + decompresses the data in the named gzip files. If no arguments are given, + gun will decompress from stdin to stdout. The names must end in .gz, -gz, + .z, -z, _z, or .Z. The uncompressed data will be written to a file name + with the suffix stripped. On success, the original file is deleted. On + failure, the output file is deleted. For most failures, the command will + continue to process the remaining names on the command line. A memory + allocation failure will abort the command. If -t is specified, then the + listed files or stdin will be tested as gzip files for integrity (without + checking for a proper suffix), no output will be written, and no files + will be deleted. + + Like gzip, gun allows concatenated gzip streams and will decompress them, + writing all of the uncompressed data to the output. Unlike gzip, gun allows + an empty file on input, and will produce no error writing an empty output + file. + + gun will also decompress files made by Unix compress, which uses LZW + compression. These files are automatically detected by virtue of their + magic header bytes. Since the end of Unix compress stream is marked by the + end-of-file, they cannot be concantenated. If a Unix compress stream is + encountered in an input file, it is the last stream in that file. + + Like gunzip and uncompress, the file attributes of the orignal compressed + file are maintained in the final uncompressed file, to the extent that the + user permissions allow it. + + On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version + 1.2.4) is on the same file, when gun is linked with zlib 1.2.2. Also the + LZW decompression provided by gun is about twice as fast as the standard + Unix uncompress command. + */ + +/* external functions and related types and constants */ +#include /* fprintf() */ +#include /* malloc(), free() */ +#include /* strerror(), strcmp(), strlen(), memcpy() */ +#include /* errno */ +#include /* open() */ +#include /* read(), write(), close(), chown(), unlink() */ +#include +#include /* stat(), chmod() */ +#include /* utime() */ +#include "zlib.h" /* inflateBackInit(), inflateBack(), */ + /* inflateBackEnd(), crc32() */ + +/* function declaration */ +#define local static + +/* buffer constants */ +#define SIZE 32768U /* input and output buffer sizes */ +#define PIECE 16384 /* limits i/o chunks for 16-bit int case */ + +/* structure for infback() to pass to input function in() -- it maintains the + input file and a buffer of size SIZE */ +struct ind { + int infile; + unsigned char *inbuf; +}; + +/* Load input buffer, assumed to be empty, and return bytes loaded and a + pointer to them. read() is called until the buffer is full, or until it + returns end-of-file or error. Return 0 on error. */ +local unsigned in(void *in_desc, unsigned char **buf) +{ + int ret; + unsigned len; + unsigned char *next; + struct ind *me = (struct ind *)in_desc; + + next = me->inbuf; + *buf = next; + len = 0; + do { + ret = PIECE; + if ((unsigned)ret > SIZE - len) + ret = (int)(SIZE - len); + ret = (int)read(me->infile, next, ret); + if (ret == -1) { + len = 0; + break; + } + next += ret; + len += ret; + } while (ret != 0 && len < SIZE); + return len; +} + +/* structure for infback() to pass to output function out() -- it maintains the + output file, a running CRC-32 check on the output and the total number of + bytes output, both for checking against the gzip trailer. (The length in + the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and + the output is greater than 4 GB.) */ +struct outd { + int outfile; + int check; /* true if checking crc and total */ + unsigned long crc; + unsigned long total; +}; + +/* Write output buffer and update the CRC-32 and total bytes written. write() + is called until all of the output is written or an error is encountered. + On success out() returns 0. For a write failure, out() returns 1. If the + output file descriptor is -1, then nothing is written. + */ +local int out(void *out_desc, unsigned char *buf, unsigned len) +{ + int ret; + struct outd *me = (struct outd *)out_desc; + + if (me->check) { + me->crc = crc32(me->crc, buf, len); + me->total += len; + } + if (me->outfile != -1) + do { + ret = PIECE; + if ((unsigned)ret > len) + ret = (int)len; + ret = (int)write(me->outfile, buf, ret); + if (ret == -1) + return 1; + buf += ret; + len -= ret; + } while (len != 0); + return 0; +} + +/* next input byte macro for use inside lunpipe() and gunpipe() */ +#define NEXT() (have ? 0 : (have = in(indp, &next)), \ + last = have ? (have--, (int)(*next++)) : -1) + +/* memory for gunpipe() and lunpipe() -- + the first 256 entries of prefix[] and suffix[] are never used, could + have offset the index, but it's faster to waste the memory */ +unsigned char inbuf[SIZE]; /* input buffer */ +unsigned char outbuf[SIZE]; /* output buffer */ +unsigned short prefix[65536]; /* index to LZW prefix string */ +unsigned char suffix[65536]; /* one-character LZW suffix */ +unsigned char match[65280 + 2]; /* buffer for reversed match or gzip + 32K sliding window */ + +/* throw out what's left in the current bits byte buffer (this is a vestigial + aspect of the compressed data format derived from an implementation that + made use of a special VAX machine instruction!) */ +#define FLUSHCODE() \ + do { \ + left = 0; \ + rem = 0; \ + if (chunk > have) { \ + chunk -= have; \ + have = 0; \ + if (NEXT() == -1) \ + break; \ + chunk--; \ + if (chunk > have) { \ + chunk = have = 0; \ + break; \ + } \ + } \ + have -= chunk; \ + next += chunk; \ + chunk = 0; \ + } while (0) + +/* Decompress a compress (LZW) file from indp to outfile. The compress magic + header (two bytes) has already been read and verified. There are have bytes + of buffered input at next. strm is used for passing error information back + to gunpipe(). + + lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of + file, read error, or write error (a write error indicated by strm->next_in + not equal to Z_NULL), or Z_DATA_ERROR for invalid input. + */ +local int lunpipe(unsigned have, unsigned char *next, struct ind *indp, + int outfile, z_stream *strm) +{ + int last; /* last byte read by NEXT(), or -1 if EOF */ + unsigned chunk; /* bytes left in current chunk */ + int left; /* bits left in rem */ + unsigned rem; /* unused bits from input */ + int bits; /* current bits per code */ + unsigned code; /* code, table traversal index */ + unsigned mask; /* mask for current bits codes */ + int max; /* maximum bits per code for this stream */ + unsigned flags; /* compress flags, then block compress flag */ + unsigned end; /* last valid entry in prefix/suffix tables */ + unsigned temp; /* current code */ + unsigned prev; /* previous code */ + unsigned final; /* last character written for previous code */ + unsigned stack; /* next position for reversed string */ + unsigned outcnt; /* bytes in output buffer */ + struct outd outd; /* output structure */ + unsigned char *p; + + /* set up output */ + outd.outfile = outfile; + outd.check = 0; + + /* process remainder of compress header -- a flags byte */ + flags = NEXT(); + if (last == -1) + return Z_BUF_ERROR; + if (flags & 0x60) { + strm->msg = (char *)"unknown lzw flags set"; + return Z_DATA_ERROR; + } + max = flags & 0x1f; + if (max < 9 || max > 16) { + strm->msg = (char *)"lzw bits out of range"; + return Z_DATA_ERROR; + } + if (max == 9) /* 9 doesn't really mean 9 */ + max = 10; + flags &= 0x80; /* true if block compress */ + + /* clear table */ + bits = 9; + mask = 0x1ff; + end = flags ? 256 : 255; + + /* set up: get first 9-bit code, which is the first decompressed byte, but + don't create a table entry until the next code */ + if (NEXT() == -1) /* no compressed data is ok */ + return Z_OK; + final = prev = (unsigned)last; /* low 8 bits of code */ + if (NEXT() == -1) /* missing a bit */ + return Z_BUF_ERROR; + if (last & 1) { /* code must be < 256 */ + strm->msg = (char *)"invalid lzw code"; + return Z_DATA_ERROR; + } + rem = (unsigned)last >> 1; /* remaining 7 bits */ + left = 7; + chunk = bits - 2; /* 7 bytes left in this chunk */ + outbuf[0] = (unsigned char)final; /* write first decompressed byte */ + outcnt = 1; + + /* decode codes */ + stack = 0; + for (;;) { + /* if the table will be full after this, increment the code size */ + if (end >= mask && bits < max) { + FLUSHCODE(); + bits++; + mask <<= 1; + mask++; + } + + /* get a code of length bits */ + if (chunk == 0) /* decrement chunk modulo bits */ + chunk = bits; + code = rem; /* low bits of code */ + if (NEXT() == -1) { /* EOF is end of compressed data */ + /* write remaining buffered output */ + if (outcnt && out(&outd, outbuf, outcnt)) { + strm->next_in = outbuf; /* signal write error */ + return Z_BUF_ERROR; + } + return Z_OK; + } + code += (unsigned)last << left; /* middle (or high) bits of code */ + left += 8; + chunk--; + if (bits > left) { /* need more bits */ + if (NEXT() == -1) /* can't end in middle of code */ + return Z_BUF_ERROR; + code += (unsigned)last << left; /* high bits of code */ + left += 8; + chunk--; + } + code &= mask; /* mask to current code length */ + left -= bits; /* number of unused bits */ + rem = (unsigned)last >> (8 - left); /* unused bits from last byte */ + + /* process clear code (256) */ + if (code == 256 && flags) { + FLUSHCODE(); + bits = 9; /* initialize bits and mask */ + mask = 0x1ff; + end = 255; /* empty table */ + continue; /* get next code */ + } + + /* special code to reuse last match */ + temp = code; /* save the current code */ + if (code > end) { + /* Be picky on the allowed code here, and make sure that the code + we drop through (prev) will be a valid index so that random + input does not cause an exception. The code != end + 1 check is + empirically derived, and not checked in the original uncompress + code. If this ever causes a problem, that check could be safely + removed. Leaving this check in greatly improves gun's ability + to detect random or corrupted input after a compress header. + In any case, the prev > end check must be retained. */ + if (code != end + 1 || prev > end) { + strm->msg = (char *)"invalid lzw code"; + return Z_DATA_ERROR; + } + match[stack++] = (unsigned char)final; + code = prev; + } + + /* walk through linked list to generate output in reverse order */ + p = match + stack; + while (code >= 256) { + *p++ = suffix[code]; + code = prefix[code]; + } + stack = p - match; + match[stack++] = (unsigned char)code; + final = code; + + /* link new table entry */ + if (end < mask) { + end++; + prefix[end] = (unsigned short)prev; + suffix[end] = (unsigned char)final; + } + + /* set previous code for next iteration */ + prev = temp; + + /* write output in forward order */ + while (stack > SIZE - outcnt) { + while (outcnt < SIZE) + outbuf[outcnt++] = match[--stack]; + if (out(&outd, outbuf, outcnt)) { + strm->next_in = outbuf; /* signal write error */ + return Z_BUF_ERROR; + } + outcnt = 0; + } + p = match + stack; + do { + outbuf[outcnt++] = *--p; + } while (p > match); + stack = 0; + + /* loop for next code with final and prev as the last match, rem and + left provide the first 0..7 bits of the next code, end is the last + valid table entry */ + } +} + +/* Decompress a gzip file from infile to outfile. strm is assumed to have been + successfully initialized with inflateBackInit(). The input file may consist + of a series of gzip streams, in which case all of them will be decompressed + to the output file. If outfile is -1, then the gzip stream(s) integrity is + checked and nothing is written. + + The return value is a zlib error code: Z_MEM_ERROR if out of memory, + Z_DATA_ERROR if the header or the compressed data is invalid, or if the + trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends + prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip + stream) follows a valid gzip stream. + */ +local int gunpipe(z_stream *strm, int infile, int outfile) +{ + int ret, first, last; + unsigned have, flags, len; + unsigned char *next = NULL; + struct ind ind, *indp; + struct outd outd; + + /* setup input buffer */ + ind.infile = infile; + ind.inbuf = inbuf; + indp = &ind; + + /* decompress concatenated gzip streams */ + have = 0; /* no input data read in yet */ + first = 1; /* looking for first gzip header */ + strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */ + for (;;) { + /* look for the two magic header bytes for a gzip stream */ + if (NEXT() == -1) { + ret = Z_OK; + break; /* empty gzip stream is ok */ + } + if (last != 31 || (NEXT() != 139 && last != 157)) { + strm->msg = (char *)"incorrect header check"; + ret = first ? Z_DATA_ERROR : Z_ERRNO; + break; /* not a gzip or compress header */ + } + first = 0; /* next non-header is junk */ + + /* process a compress (LZW) file -- can't be concatenated after this */ + if (last == 157) { + ret = lunpipe(have, next, indp, outfile, strm); + break; + } + + /* process remainder of gzip header */ + ret = Z_BUF_ERROR; + if (NEXT() != 8) { /* only deflate method allowed */ + if (last == -1) break; + strm->msg = (char *)"unknown compression method"; + ret = Z_DATA_ERROR; + break; + } + flags = NEXT(); /* header flags */ + NEXT(); /* discard mod time, xflgs, os */ + NEXT(); + NEXT(); + NEXT(); + NEXT(); + NEXT(); + if (last == -1) break; + if (flags & 0xe0) { + strm->msg = (char *)"unknown header flags set"; + ret = Z_DATA_ERROR; + break; + } + if (flags & 4) { /* extra field */ + len = NEXT(); + len += (unsigned)(NEXT()) << 8; + if (last == -1) break; + while (len > have) { + len -= have; + have = 0; + if (NEXT() == -1) break; + len--; + } + if (last == -1) break; + have -= len; + next += len; + } + if (flags & 8) /* file name */ + while (NEXT() != 0 && last != -1) + ; + if (flags & 16) /* comment */ + while (NEXT() != 0 && last != -1) + ; + if (flags & 2) { /* header crc */ + NEXT(); + NEXT(); + } + if (last == -1) break; + + /* set up output */ + outd.outfile = outfile; + outd.check = 1; + outd.crc = crc32(0L, Z_NULL, 0); + outd.total = 0; + + /* decompress data to output */ + strm->next_in = next; + strm->avail_in = have; + ret = inflateBack(strm, in, indp, out, &outd); + if (ret != Z_STREAM_END) break; + next = strm->next_in; + have = strm->avail_in; + strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */ + + /* check trailer */ + ret = Z_BUF_ERROR; + if (NEXT() != (int)(outd.crc & 0xff) || + NEXT() != (int)((outd.crc >> 8) & 0xff) || + NEXT() != (int)((outd.crc >> 16) & 0xff) || + NEXT() != (int)((outd.crc >> 24) & 0xff)) { + /* crc error */ + if (last != -1) { + strm->msg = (char *)"incorrect data check"; + ret = Z_DATA_ERROR; + } + break; + } + if (NEXT() != (int)(outd.total & 0xff) || + NEXT() != (int)((outd.total >> 8) & 0xff) || + NEXT() != (int)((outd.total >> 16) & 0xff) || + NEXT() != (int)((outd.total >> 24) & 0xff)) { + /* length error */ + if (last != -1) { + strm->msg = (char *)"incorrect length check"; + ret = Z_DATA_ERROR; + } + break; + } + + /* go back and look for another gzip stream */ + } + + /* clean up and return */ + return ret; +} + +/* Copy file attributes, from -> to, as best we can. This is best effort, so + no errors are reported. The mode bits, including suid, sgid, and the sticky + bit are copied (if allowed), the owner's user id and group id are copied + (again if allowed), and the access and modify times are copied. */ +local void copymeta(char *from, char *to) +{ + struct stat was; + struct utimbuf when; + + /* get all of from's Unix meta data, return if not a regular file */ + if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG) + return; + + /* set to's mode bits, ignore errors */ + (void)chmod(to, was.st_mode & 07777); + + /* copy owner's user and group, ignore errors */ + (void)chown(to, was.st_uid, was.st_gid); + + /* copy access and modify times, ignore errors */ + when.actime = was.st_atime; + when.modtime = was.st_mtime; + (void)utime(to, &when); +} + +/* Decompress the file inname to the file outnname, of if test is true, just + decompress without writing and check the gzip trailer for integrity. If + inname is NULL or an empty string, read from stdin. If outname is NULL or + an empty string, write to stdout. strm is a pre-initialized inflateBack + structure. When appropriate, copy the file attributes from inname to + outname. + + gunzip() returns 1 if there is an out-of-memory error or an unexpected + return code from gunpipe(). Otherwise it returns 0. + */ +local int gunzip(z_stream *strm, char *inname, char *outname, int test) +{ + int ret; + int infile, outfile; + + /* open files */ + if (inname == NULL || *inname == 0) { + inname = "-"; + infile = 0; /* stdin */ + } + else { + infile = open(inname, O_RDONLY, 0); + if (infile == -1) { + fprintf(stderr, "gun cannot open %s\n", inname); + return 0; + } + } + if (test) + outfile = -1; + else if (outname == NULL || *outname == 0) { + outname = "-"; + outfile = 1; /* stdout */ + } + else { + outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666); + if (outfile == -1) { + close(infile); + fprintf(stderr, "gun cannot create %s\n", outname); + return 0; + } + } + errno = 0; + + /* decompress */ + ret = gunpipe(strm, infile, outfile); + if (outfile > 2) close(outfile); + if (infile > 2) close(infile); + + /* interpret result */ + switch (ret) { + case Z_OK: + case Z_ERRNO: + if (infile > 2 && outfile > 2) { + copymeta(inname, outname); /* copy attributes */ + unlink(inname); + } + if (ret == Z_ERRNO) + fprintf(stderr, "gun warning: trailing garbage ignored in %s\n", + inname); + break; + case Z_DATA_ERROR: + if (outfile > 2) unlink(outname); + fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg); + break; + case Z_MEM_ERROR: + if (outfile > 2) unlink(outname); + fprintf(stderr, "gun out of memory error--aborting\n"); + return 1; + case Z_BUF_ERROR: + if (outfile > 2) unlink(outname); + if (strm->next_in != Z_NULL) { + fprintf(stderr, "gun write error on %s: %s\n", + outname, strerror(errno)); + } + else if (errno) { + fprintf(stderr, "gun read error on %s: %s\n", + inname, strerror(errno)); + } + else { + fprintf(stderr, "gun unexpected end of file on %s\n", + inname); + } + break; + default: + if (outfile > 2) unlink(outname); + fprintf(stderr, "gun internal error--aborting\n"); + return 1; + } + return 0; +} + +/* Process the gun command line arguments. See the command syntax near the + beginning of this source file. */ +int main(int argc, char **argv) +{ + int ret, len, test; + char *outname; + unsigned char *window; + z_stream strm; + + /* initialize inflateBack state for repeated use */ + window = match; /* reuse LZW match buffer */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = inflateBackInit(&strm, 15, window); + if (ret != Z_OK) { + fprintf(stderr, "gun out of memory error--aborting\n"); + return 1; + } + + /* decompress each file to the same name with the suffix removed */ + argc--; + argv++; + test = 0; + if (argc && strcmp(*argv, "-h") == 0) { + fprintf(stderr, "gun 1.6 (17 Jan 2010)\n"); + fprintf(stderr, "Copyright (C) 2003-2010 Mark Adler\n"); + fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n"); + return 0; + } + if (argc && strcmp(*argv, "-t") == 0) { + test = 1; + argc--; + argv++; + } + if (argc) + do { + if (test) + outname = NULL; + else { + len = (int)strlen(*argv); + if (strcmp(*argv + len - 3, ".gz") == 0 || + strcmp(*argv + len - 3, "-gz") == 0) + len -= 3; + else if (strcmp(*argv + len - 2, ".z") == 0 || + strcmp(*argv + len - 2, "-z") == 0 || + strcmp(*argv + len - 2, "_z") == 0 || + strcmp(*argv + len - 2, ".Z") == 0) + len -= 2; + else { + fprintf(stderr, "gun error: no gz type on %s--skipping\n", + *argv); + continue; + } + outname = malloc(len + 1); + if (outname == NULL) { + fprintf(stderr, "gun out of memory error--aborting\n"); + ret = 1; + break; + } + memcpy(outname, *argv, len); + outname[len] = 0; + } + ret = gunzip(&strm, *argv, outname, test); + if (outname != NULL) free(outname); + if (ret) break; + } while (argv++, --argc); + else + ret = gunzip(&strm, NULL, NULL, test); + + /* clean up */ + inflateBackEnd(&strm); + return ret; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzappend.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzappend.c new file mode 100644 index 00000000..e9e878e1 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzappend.c @@ -0,0 +1,500 @@ +/* gzappend -- command to append to a gzip file + + Copyright (C) 2003 Mark Adler, all rights reserved + version 1.1, 4 Nov 2003 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + +/* + * Change history: + * + * 1.0 19 Oct 2003 - First version + * 1.1 4 Nov 2003 - Expand and clarify some comments and notes + * - Add version and copyright to help + * - Send help to stdout instead of stderr + * - Add some preemptive typecasts + * - Add L to constants in lseek() calls + * - Remove some debugging information in error messages + * - Use new data_type definition for zlib 1.2.1 + * - Simplfy and unify file operations + * - Finish off gzip file in gztack() + * - Use deflatePrime() instead of adding empty blocks + * - Keep gzip file clean on appended file read errors + * - Use in-place rotate instead of auxiliary buffer + * (Why you ask? Because it was fun to write!) + */ + +/* + gzappend takes a gzip file and appends to it, compressing files from the + command line or data from stdin. The gzip file is written to directly, to + avoid copying that file, in case it's large. Note that this results in the + unfriendly behavior that if gzappend fails, the gzip file is corrupted. + + This program was written to illustrate the use of the new Z_BLOCK option of + zlib 1.2.x's inflate() function. This option returns from inflate() at each + block boundary to facilitate locating and modifying the last block bit at + the start of the final deflate block. Also whether using Z_BLOCK or not, + another required feature of zlib 1.2.x is that inflate() now provides the + number of unusued bits in the last input byte used. gzappend will not work + with versions of zlib earlier than 1.2.1. + + gzappend first decompresses the gzip file internally, discarding all but + the last 32K of uncompressed data, and noting the location of the last block + bit and the number of unused bits in the last byte of the compressed data. + The gzip trailer containing the CRC-32 and length of the uncompressed data + is verified. This trailer will be later overwritten. + + Then the last block bit is cleared by seeking back in the file and rewriting + the byte that contains it. Seeking forward, the last byte of the compressed + data is saved along with the number of unused bits to initialize deflate. + + A deflate process is initialized, using the last 32K of the uncompressed + data from the gzip file to initialize the dictionary. If the total + uncompressed data was less than 32K, then all of it is used to initialize + the dictionary. The deflate output bit buffer is also initialized with the + last bits from the original deflate stream. From here on, the data to + append is simply compressed using deflate, and written to the gzip file. + When that is complete, the new CRC-32 and uncompressed length are written + as the trailer of the gzip file. + */ + +#include +#include +#include +#include +#include +#include "zlib.h" + +#define local static +#define LGCHUNK 14 +#define CHUNK (1U << LGCHUNK) +#define DSIZE 32768U + +/* print an error message and terminate with extreme prejudice */ +local void bye(char *msg1, char *msg2) +{ + fprintf(stderr, "gzappend error: %s%s\n", msg1, msg2); + exit(1); +} + +/* return the greatest common divisor of a and b using Euclid's algorithm, + modified to be fast when one argument much greater than the other, and + coded to avoid unnecessary swapping */ +local unsigned gcd(unsigned a, unsigned b) +{ + unsigned c; + + while (a && b) + if (a > b) { + c = b; + while (a - c >= c) + c <<= 1; + a -= c; + } + else { + c = a; + while (b - c >= c) + c <<= 1; + b -= c; + } + return a + b; +} + +/* rotate list[0..len-1] left by rot positions, in place */ +local void rotate(unsigned char *list, unsigned len, unsigned rot) +{ + unsigned char tmp; + unsigned cycles; + unsigned char *start, *last, *to, *from; + + /* normalize rot and handle degenerate cases */ + if (len < 2) return; + if (rot >= len) rot %= len; + if (rot == 0) return; + + /* pointer to last entry in list */ + last = list + (len - 1); + + /* do simple left shift by one */ + if (rot == 1) { + tmp = *list; + memcpy(list, list + 1, len - 1); + *last = tmp; + return; + } + + /* do simple right shift by one */ + if (rot == len - 1) { + tmp = *last; + memmove(list + 1, list, len - 1); + *list = tmp; + return; + } + + /* otherwise do rotate as a set of cycles in place */ + cycles = gcd(len, rot); /* number of cycles */ + do { + start = from = list + cycles; /* start index is arbitrary */ + tmp = *from; /* save entry to be overwritten */ + for (;;) { + to = from; /* next step in cycle */ + from += rot; /* go right rot positions */ + if (from > last) from -= len; /* (pointer better not wrap) */ + if (from == start) break; /* all but one shifted */ + *to = *from; /* shift left */ + } + *to = tmp; /* complete the circle */ + } while (--cycles); +} + +/* structure for gzip file read operations */ +typedef struct { + int fd; /* file descriptor */ + int size; /* 1 << size is bytes in buf */ + unsigned left; /* bytes available at next */ + unsigned char *buf; /* buffer */ + unsigned char *next; /* next byte in buffer */ + char *name; /* file name for error messages */ +} file; + +/* reload buffer */ +local int readin(file *in) +{ + int len; + + len = read(in->fd, in->buf, 1 << in->size); + if (len == -1) bye("error reading ", in->name); + in->left = (unsigned)len; + in->next = in->buf; + return len; +} + +/* read from file in, exit if end-of-file */ +local int readmore(file *in) +{ + if (readin(in) == 0) bye("unexpected end of ", in->name); + return 0; +} + +#define read1(in) (in->left == 0 ? readmore(in) : 0, \ + in->left--, *(in->next)++) + +/* skip over n bytes of in */ +local void skip(file *in, unsigned n) +{ + unsigned bypass; + + if (n > in->left) { + n -= in->left; + bypass = n & ~((1U << in->size) - 1); + if (bypass) { + if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1) + bye("seeking ", in->name); + n -= bypass; + } + readmore(in); + if (n > in->left) + bye("unexpected end of ", in->name); + } + in->left -= n; + in->next += n; +} + +/* read a four-byte unsigned integer, little-endian, from in */ +unsigned long read4(file *in) +{ + unsigned long val; + + val = read1(in); + val += (unsigned)read1(in) << 8; + val += (unsigned long)read1(in) << 16; + val += (unsigned long)read1(in) << 24; + return val; +} + +/* skip over gzip header */ +local void gzheader(file *in) +{ + int flags; + unsigned n; + + if (read1(in) != 31 || read1(in) != 139) bye(in->name, " not a gzip file"); + if (read1(in) != 8) bye("unknown compression method in", in->name); + flags = read1(in); + if (flags & 0xe0) bye("unknown header flags set in", in->name); + skip(in, 6); + if (flags & 4) { + n = read1(in); + n += (unsigned)(read1(in)) << 8; + skip(in, n); + } + if (flags & 8) while (read1(in) != 0) ; + if (flags & 16) while (read1(in) != 0) ; + if (flags & 2) skip(in, 2); +} + +/* decompress gzip file "name", return strm with a deflate stream ready to + continue compression of the data in the gzip file, and return a file + descriptor pointing to where to write the compressed data -- the deflate + stream is initialized to compress using level "level" */ +local int gzscan(char *name, z_stream *strm, int level) +{ + int ret, lastbit, left, full; + unsigned have; + unsigned long crc, tot; + unsigned char *window; + off_t lastoff, end; + file gz; + + /* open gzip file */ + gz.name = name; + gz.fd = open(name, O_RDWR, 0); + if (gz.fd == -1) bye("cannot open ", name); + gz.buf = malloc(CHUNK); + if (gz.buf == NULL) bye("out of memory", ""); + gz.size = LGCHUNK; + gz.left = 0; + + /* skip gzip header */ + gzheader(&gz); + + /* prepare to decompress */ + window = malloc(DSIZE); + if (window == NULL) bye("out of memory", ""); + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = inflateInit2(strm, -15); + if (ret != Z_OK) bye("out of memory", " or library mismatch"); + + /* decompress the deflate stream, saving append information */ + lastbit = 0; + lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left; + left = 0; + strm->avail_in = gz.left; + strm->next_in = gz.next; + crc = crc32(0L, Z_NULL, 0); + have = full = 0; + do { + /* if needed, get more input */ + if (strm->avail_in == 0) { + readmore(&gz); + strm->avail_in = gz.left; + strm->next_in = gz.next; + } + + /* set up output to next available section of sliding window */ + strm->avail_out = DSIZE - have; + strm->next_out = window + have; + + /* inflate and check for errors */ + ret = inflate(strm, Z_BLOCK); + if (ret == Z_STREAM_ERROR) bye("internal stream error!", ""); + if (ret == Z_MEM_ERROR) bye("out of memory", ""); + if (ret == Z_DATA_ERROR) + bye("invalid compressed data--format violated in", name); + + /* update crc and sliding window pointer */ + crc = crc32(crc, window + have, DSIZE - have - strm->avail_out); + if (strm->avail_out) + have = DSIZE - strm->avail_out; + else { + have = 0; + full = 1; + } + + /* process end of block */ + if (strm->data_type & 128) { + if (strm->data_type & 64) + left = strm->data_type & 0x1f; + else { + lastbit = strm->data_type & 0x1f; + lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in; + } + } + } while (ret != Z_STREAM_END); + inflateEnd(strm); + gz.left = strm->avail_in; + gz.next = strm->next_in; + + /* save the location of the end of the compressed data */ + end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left; + + /* check gzip trailer and save total for deflate */ + if (crc != read4(&gz)) + bye("invalid compressed data--crc mismatch in ", name); + tot = strm->total_out; + if ((tot & 0xffffffffUL) != read4(&gz)) + bye("invalid compressed data--length mismatch in", name); + + /* if not at end of file, warn */ + if (gz.left || readin(&gz)) + fprintf(stderr, + "gzappend warning: junk at end of gzip file overwritten\n"); + + /* clear last block bit */ + lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET); + if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name); + *gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7))); + lseek(gz.fd, -1L, SEEK_CUR); + if (write(gz.fd, gz.buf, 1) != 1) bye("writing after seek to ", name); + + /* if window wrapped, build dictionary from window by rotating */ + if (full) { + rotate(window, DSIZE, have); + have = DSIZE; + } + + /* set up deflate stream with window, crc, total_in, and leftover bits */ + ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + if (ret != Z_OK) bye("out of memory", ""); + deflateSetDictionary(strm, window, have); + strm->adler = crc; + strm->total_in = tot; + if (left) { + lseek(gz.fd, --end, SEEK_SET); + if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name); + deflatePrime(strm, 8 - left, *gz.buf); + } + lseek(gz.fd, end, SEEK_SET); + + /* clean up and return */ + free(window); + free(gz.buf); + return gz.fd; +} + +/* append file "name" to gzip file gd using deflate stream strm -- if last + is true, then finish off the deflate stream at the end */ +local void gztack(char *name, int gd, z_stream *strm, int last) +{ + int fd, len, ret; + unsigned left; + unsigned char *in, *out; + + /* open file to compress and append */ + fd = 0; + if (name != NULL) { + fd = open(name, O_RDONLY, 0); + if (fd == -1) + fprintf(stderr, "gzappend warning: %s not found, skipping ...\n", + name); + } + + /* allocate buffers */ + in = fd == -1 ? NULL : malloc(CHUNK); + out = malloc(CHUNK); + if (out == NULL) bye("out of memory", ""); + + /* compress input file and append to gzip file */ + do { + /* get more input */ + len = fd == -1 ? 0 : read(fd, in, CHUNK); + if (len == -1) { + fprintf(stderr, + "gzappend warning: error reading %s, skipping rest ...\n", + name); + len = 0; + } + strm->avail_in = (unsigned)len; + strm->next_in = in; + if (len) strm->adler = crc32(strm->adler, in, (unsigned)len); + + /* compress and write all available output */ + do { + strm->avail_out = CHUNK; + strm->next_out = out; + ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH); + left = CHUNK - strm->avail_out; + while (left) { + len = write(gd, out + CHUNK - strm->avail_out - left, left); + if (len == -1) bye("writing gzip file", ""); + left -= (unsigned)len; + } + } while (strm->avail_out == 0 && ret != Z_STREAM_END); + } while (len != 0); + + /* write trailer after last entry */ + if (last) { + deflateEnd(strm); + out[0] = (unsigned char)(strm->adler); + out[1] = (unsigned char)(strm->adler >> 8); + out[2] = (unsigned char)(strm->adler >> 16); + out[3] = (unsigned char)(strm->adler >> 24); + out[4] = (unsigned char)(strm->total_in); + out[5] = (unsigned char)(strm->total_in >> 8); + out[6] = (unsigned char)(strm->total_in >> 16); + out[7] = (unsigned char)(strm->total_in >> 24); + len = 8; + do { + ret = write(gd, out + 8 - len, len); + if (ret == -1) bye("writing gzip file", ""); + len -= ret; + } while (len); + close(gd); + } + + /* clean up and return */ + free(out); + if (in != NULL) free(in); + if (fd > 0) close(fd); +} + +/* process the compression level option if present, scan the gzip file, and + append the specified files, or append the data from stdin if no other file + names are provided on the command line -- the gzip file must be writable + and seekable */ +int main(int argc, char **argv) +{ + int gd, level; + z_stream strm; + + /* ignore command name */ + argv++; + + /* provide usage if no arguments */ + if (*argv == NULL) { + printf("gzappend 1.1 (4 Nov 2003) Copyright (C) 2003 Mark Adler\n"); + printf( + "usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n"); + return 0; + } + + /* set compression level */ + level = Z_DEFAULT_COMPRESSION; + if (argv[0][0] == '-') { + if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0) + bye("invalid compression level", ""); + level = argv[0][1] - '0'; + if (*++argv == NULL) bye("no gzip file name after options", ""); + } + + /* prepare to append to gzip file */ + gd = gzscan(*argv++, &strm, level); + + /* append files on command line, or from stdin if none */ + if (*argv == NULL) + gztack(NULL, gd, &strm, 1); + else + do { + gztack(*argv, gd, &strm, argv[1] == NULL); + } while (*++argv != NULL); + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzjoin.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzjoin.c new file mode 100644 index 00000000..129347ce --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzjoin.c @@ -0,0 +1,448 @@ +/* gzjoin -- command to join gzip files into one gzip file + + Copyright (C) 2004 Mark Adler, all rights reserved + version 1.0, 11 Dec 2004 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + +/* + * Change history: + * + * 1.0 11 Dec 2004 - First version + * 1.1 12 Jun 2005 - Changed ssize_t to long for portability + */ + +/* + gzjoin takes one or more gzip files on the command line and writes out a + single gzip file that will uncompress to the concatenation of the + uncompressed data from the individual gzip files. gzjoin does this without + having to recompress any of the data and without having to calculate a new + crc32 for the concatenated uncompressed data. gzjoin does however have to + decompress all of the input data in order to find the bits in the compressed + data that need to be modified to concatenate the streams. + + gzjoin does not do an integrity check on the input gzip files other than + checking the gzip header and decompressing the compressed data. They are + otherwise assumed to be complete and correct. + + Each joint between gzip files removes at least 18 bytes of previous trailer + and subsequent header, and inserts an average of about three bytes to the + compressed data in order to connect the streams. The output gzip file + has a minimal ten-byte gzip header with no file name or modification time. + + This program was written to illustrate the use of the Z_BLOCK option of + inflate() and the crc32_combine() function. gzjoin will not compile with + versions of zlib earlier than 1.2.3. + */ + +#include /* fputs(), fprintf(), fwrite(), putc() */ +#include /* exit(), malloc(), free() */ +#include /* open() */ +#include /* close(), read(), lseek() */ +#include "zlib.h" + /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */ + +#define local static + +/* exit with an error (return a value to allow use in an expression) */ +local int bail(char *why1, char *why2) +{ + fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2); + exit(1); + return 0; +} + +/* -- simple buffered file input with access to the buffer -- */ + +#define CHUNK 32768 /* must be a power of two and fit in unsigned */ + +/* bin buffered input file type */ +typedef struct { + char *name; /* name of file for error messages */ + int fd; /* file descriptor */ + unsigned left; /* bytes remaining at next */ + unsigned char *next; /* next byte to read */ + unsigned char *buf; /* allocated buffer of length CHUNK */ +} bin; + +/* close a buffered file and free allocated memory */ +local void bclose(bin *in) +{ + if (in != NULL) { + if (in->fd != -1) + close(in->fd); + if (in->buf != NULL) + free(in->buf); + free(in); + } +} + +/* open a buffered file for input, return a pointer to type bin, or NULL on + failure */ +local bin *bopen(char *name) +{ + bin *in; + + in = malloc(sizeof(bin)); + if (in == NULL) + return NULL; + in->buf = malloc(CHUNK); + in->fd = open(name, O_RDONLY, 0); + if (in->buf == NULL || in->fd == -1) { + bclose(in); + return NULL; + } + in->left = 0; + in->next = in->buf; + in->name = name; + return in; +} + +/* load buffer from file, return -1 on read error, 0 or 1 on success, with + 1 indicating that end-of-file was reached */ +local int bload(bin *in) +{ + long len; + + if (in == NULL) + return -1; + if (in->left != 0) + return 0; + in->next = in->buf; + do { + len = (long)read(in->fd, in->buf + in->left, CHUNK - in->left); + if (len < 0) + return -1; + in->left += (unsigned)len; + } while (len != 0 && in->left < CHUNK); + return len == 0 ? 1 : 0; +} + +/* get a byte from the file, bail if end of file */ +#define bget(in) (in->left ? 0 : bload(in), \ + in->left ? (in->left--, *(in->next)++) : \ + bail("unexpected end of file on ", in->name)) + +/* get a four-byte little-endian unsigned integer from file */ +local unsigned long bget4(bin *in) +{ + unsigned long val; + + val = bget(in); + val += (unsigned long)(bget(in)) << 8; + val += (unsigned long)(bget(in)) << 16; + val += (unsigned long)(bget(in)) << 24; + return val; +} + +/* skip bytes in file */ +local void bskip(bin *in, unsigned skip) +{ + /* check pointer */ + if (in == NULL) + return; + + /* easy case -- skip bytes in buffer */ + if (skip <= in->left) { + in->left -= skip; + in->next += skip; + return; + } + + /* skip what's in buffer, discard buffer contents */ + skip -= in->left; + in->left = 0; + + /* seek past multiples of CHUNK bytes */ + if (skip > CHUNK) { + unsigned left; + + left = skip & (CHUNK - 1); + if (left == 0) { + /* exact number of chunks: seek all the way minus one byte to check + for end-of-file with a read */ + lseek(in->fd, skip - 1, SEEK_CUR); + if (read(in->fd, in->buf, 1) != 1) + bail("unexpected end of file on ", in->name); + return; + } + + /* skip the integral chunks, update skip with remainder */ + lseek(in->fd, skip - left, SEEK_CUR); + skip = left; + } + + /* read more input and skip remainder */ + bload(in); + if (skip > in->left) + bail("unexpected end of file on ", in->name); + in->left -= skip; + in->next += skip; +} + +/* -- end of buffered input functions -- */ + +/* skip the gzip header from file in */ +local void gzhead(bin *in) +{ + int flags; + + /* verify gzip magic header and compression method */ + if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8) + bail(in->name, " is not a valid gzip file"); + + /* get and verify flags */ + flags = bget(in); + if ((flags & 0xe0) != 0) + bail("unknown reserved bits set in ", in->name); + + /* skip modification time, extra flags, and os */ + bskip(in, 6); + + /* skip extra field if present */ + if (flags & 4) { + unsigned len; + + len = bget(in); + len += (unsigned)(bget(in)) << 8; + bskip(in, len); + } + + /* skip file name if present */ + if (flags & 8) + while (bget(in) != 0) + ; + + /* skip comment if present */ + if (flags & 16) + while (bget(in) != 0) + ; + + /* skip header crc if present */ + if (flags & 2) + bskip(in, 2); +} + +/* write a four-byte little-endian unsigned integer to out */ +local void put4(unsigned long val, FILE *out) +{ + putc(val & 0xff, out); + putc((val >> 8) & 0xff, out); + putc((val >> 16) & 0xff, out); + putc((val >> 24) & 0xff, out); +} + +/* Load up zlib stream from buffered input, bail if end of file */ +local void zpull(z_streamp strm, bin *in) +{ + if (in->left == 0) + bload(in); + if (in->left == 0) + bail("unexpected end of file on ", in->name); + strm->avail_in = in->left; + strm->next_in = in->next; +} + +/* Write header for gzip file to out and initialize trailer. */ +local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out) +{ + fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out); + *crc = crc32(0L, Z_NULL, 0); + *tot = 0; +} + +/* Copy the compressed data from name, zeroing the last block bit of the last + block if clr is true, and adding empty blocks as needed to get to a byte + boundary. If clr is false, then the last block becomes the last block of + the output, and the gzip trailer is written. crc and tot maintains the + crc and length (modulo 2^32) of the output for the trailer. The resulting + gzip file is written to out. gzinit() must be called before the first call + of gzcopy() to write the gzip header and to initialize crc and tot. */ +local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot, + FILE *out) +{ + int ret; /* return value from zlib functions */ + int pos; /* where the "last block" bit is in byte */ + int last; /* true if processing the last block */ + bin *in; /* buffered input file */ + unsigned char *start; /* start of compressed data in buffer */ + unsigned char *junk; /* buffer for uncompressed data -- discarded */ + z_off_t len; /* length of uncompressed data (support > 4 GB) */ + z_stream strm; /* zlib inflate stream */ + + /* open gzip file and skip header */ + in = bopen(name); + if (in == NULL) + bail("could not open ", name); + gzhead(in); + + /* allocate buffer for uncompressed data and initialize raw inflate + stream */ + junk = malloc(CHUNK); + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, -15); + if (junk == NULL || ret != Z_OK) + bail("out of memory", ""); + + /* inflate and copy compressed data, clear last-block bit if requested */ + len = 0; + zpull(&strm, in); + start = strm.next_in; + last = start[0] & 1; + if (last && clr) + start[0] &= ~1; + strm.avail_out = 0; + for (;;) { + /* if input used and output done, write used input and get more */ + if (strm.avail_in == 0 && strm.avail_out != 0) { + fwrite(start, 1, strm.next_in - start, out); + start = in->buf; + in->left = 0; + zpull(&strm, in); + } + + /* decompress -- return early when end-of-block reached */ + strm.avail_out = CHUNK; + strm.next_out = junk; + ret = inflate(&strm, Z_BLOCK); + switch (ret) { + case Z_MEM_ERROR: + bail("out of memory", ""); + case Z_DATA_ERROR: + bail("invalid compressed data in ", in->name); + } + + /* update length of uncompressed data */ + len += CHUNK - strm.avail_out; + + /* check for block boundary (only get this when block copied out) */ + if (strm.data_type & 128) { + /* if that was the last block, then done */ + if (last) + break; + + /* number of unused bits in last byte */ + pos = strm.data_type & 7; + + /* find the next last-block bit */ + if (pos != 0) { + /* next last-block bit is in last used byte */ + pos = 0x100 >> pos; + last = strm.next_in[-1] & pos; + if (last && clr) + strm.next_in[-1] &= ~pos; + } + else { + /* next last-block bit is in next unused byte */ + if (strm.avail_in == 0) { + /* don't have that byte yet -- get it */ + fwrite(start, 1, strm.next_in - start, out); + start = in->buf; + in->left = 0; + zpull(&strm, in); + } + last = strm.next_in[0] & 1; + if (last && clr) + strm.next_in[0] &= ~1; + } + } + } + + /* update buffer with unused input */ + in->left = strm.avail_in; + in->next = strm.next_in; + + /* copy used input, write empty blocks to get to byte boundary */ + pos = strm.data_type & 7; + fwrite(start, 1, in->next - start - 1, out); + last = in->next[-1]; + if (pos == 0 || !clr) + /* already at byte boundary, or last file: write last byte */ + putc(last, out); + else { + /* append empty blocks to last byte */ + last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */ + if (pos & 1) { + /* odd -- append an empty stored block */ + putc(last, out); + if (pos == 1) + putc(0, out); /* two more bits in block header */ + fwrite("\0\0\xff\xff", 1, 4, out); + } + else { + /* even -- append 1, 2, or 3 empty fixed blocks */ + switch (pos) { + case 6: + putc(last | 8, out); + last = 0; + case 4: + putc(last | 0x20, out); + last = 0; + case 2: + putc(last | 0x80, out); + putc(0, out); + } + } + } + + /* update crc and tot */ + *crc = crc32_combine(*crc, bget4(in), len); + *tot += (unsigned long)len; + + /* clean up */ + inflateEnd(&strm); + free(junk); + bclose(in); + + /* write trailer if this is the last gzip file */ + if (!clr) { + put4(*crc, out); + put4(*tot, out); + } +} + +/* join the gzip files on the command line, write result to stdout */ +int main(int argc, char **argv) +{ + unsigned long crc, tot; /* running crc and total uncompressed length */ + + /* skip command name */ + argc--; + argv++; + + /* show usage if no arguments */ + if (argc == 0) { + fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n", + stderr); + return 0; + } + + /* join gzip files on command line and write to stdout */ + gzinit(&crc, &tot, stdout); + while (argc--) + gzcopy(*argv++, argc, &crc, &tot, stdout); + + /* done */ + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzlog.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzlog.c new file mode 100644 index 00000000..d70aacab --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzlog.c @@ -0,0 +1,1058 @@ +/* + * gzlog.c + * Copyright (C) 2004, 2008 Mark Adler, all rights reserved + * For conditions of distribution and use, see copyright notice in gzlog.h + * version 2.0, 25 Apr 2008 + */ + +/* + gzlog provides a mechanism for frequently appending short strings to a gzip + file that is efficient both in execution time and compression ratio. The + strategy is to write the short strings in an uncompressed form to the end of + the gzip file, only compressing when the amount of uncompressed data has + reached a given threshold. + + gzlog also provides protection against interruptions in the process due to + system crashes. The status of the operation is recorded in an extra field + in the gzip file, and is only updated once the gzip file is brought to a + valid state. The last data to be appended or compressed is saved in an + auxiliary file, so that if the operation is interrupted, it can be completed + the next time an append operation is attempted. + + gzlog maintains another auxiliary file with the last 32K of data from the + compressed portion, which is preloaded for the compression of the subsequent + data. This minimizes the impact to the compression ratio of appending. + */ + +/* + Operations Concept: + + Files (log name "foo"): + foo.gz -- gzip file with the complete log + foo.add -- last message to append or last data to compress + foo.dict -- dictionary of the last 32K of data for next compression + foo.temp -- temporary dictionary file for compression after this one + foo.lock -- lock file for reading and writing the other files + foo.repairs -- log file for log file recovery operations (not compressed) + + gzip file structure: + - fixed-length (no file name) header with extra field (see below) + - compressed data ending initially with empty stored block + - uncompressed data filling out originally empty stored block and + subsequent stored blocks as needed (16K max each) + - gzip trailer + - no junk at end (no other gzip streams) + + When appending data, the information in the first three items above plus the + foo.add file are sufficient to recover an interrupted append operation. The + extra field has the necessary information to restore the start of the last + stored block and determine where to append the data in the foo.add file, as + well as the crc and length of the gzip data before the append operation. + + The foo.add file is created before the gzip file is marked for append, and + deleted after the gzip file is marked as complete. So if the append + operation is interrupted, the data to add will still be there. If due to + some external force, the foo.add file gets deleted between when the append + operation was interrupted and when recovery is attempted, the gzip file will + still be restored, but without the appended data. + + When compressing data, the information in the first two items above plus the + foo.add file are sufficient to recover an interrupted compress operation. + The extra field has the necessary information to find the end of the + compressed data, and contains both the crc and length of just the compressed + data and of the complete set of data including the contents of the foo.add + file. + + Again, the foo.add file is maintained during the compress operation in case + of an interruption. If in the unlikely event the foo.add file with the data + to be compressed is missing due to some external force, a gzip file with + just the previous compressed data will be reconstructed. In this case, all + of the data that was to be compressed is lost (approximately one megabyte). + This will not occur if all that happened was an interruption of the compress + operation. + + The third state that is marked is the replacement of the old dictionary with + the new dictionary after a compress operation. Once compression is + complete, the gzip file is marked as being in the replace state. This + completes the gzip file, so an interrupt after being so marked does not + result in recompression. Then the dictionary file is replaced, and the gzip + file is marked as completed. This state prevents the possibility of + restarting compression with the wrong dictionary file. + + All three operations are wrapped by a lock/unlock procedure. In order to + gain exclusive access to the log files, first a foo.lock file must be + exclusively created. When all operations are complete, the lock is + released by deleting the foo.lock file. If when attempting to create the + lock file, it already exists and the modify time of the lock file is more + than five minutes old (set by the PATIENCE define below), then the old + lock file is considered stale and deleted, and the exclusive creation of + the lock file is retried. To assure that there are no false assessments + of the staleness of the lock file, the operations periodically touch the + lock file to update the modified date. + + Following is the definition of the extra field with all of the information + required to enable the above append and compress operations and their + recovery if interrupted. Multi-byte values are stored little endian + (consistent with the gzip format). File pointers are eight bytes long. + The crc's and lengths for the gzip trailer are four bytes long. (Note that + the length at the end of a gzip file is used for error checking only, and + for large files is actually the length modulo 2^32.) The stored block + length is two bytes long. The gzip extra field two-byte identification is + "ap" for append. It is assumed that writing the extra field to the file is + an "atomic" operation. That is, either all of the extra field is written + to the file, or none of it is, if the operation is interrupted right at the + point of updating the extra field. This is a reasonable assumption, since + the extra field is within the first 52 bytes of the file, which is smaller + than any expected block size for a mass storage device (usually 512 bytes or + larger). + + Extra field (35 bytes): + - Pointer to first stored block length -- this points to the two-byte length + of the first stored block, which is followed by the two-byte, one's + complement of that length. The stored block length is preceded by the + three-bit header of the stored block, which is the actual start of the + stored block in the deflate format. See the bit offset field below. + - Pointer to the last stored block length. This is the same as above, but + for the last stored block of the uncompressed data in the gzip file. + Initially this is the same as the first stored block length pointer. + When the stored block gets to 16K (see the MAX_STORE define), then a new + stored block as added, at which point the last stored block length pointer + is different from the first stored block length pointer. When they are + different, the first bit of the last stored block header is eight bits, or + one byte back from the block length. + - Compressed data crc and length. This is the crc and length of the data + that is in the compressed portion of the deflate stream. These are used + only in the event that the foo.add file containing the data to compress is + lost after a compress operation is interrupted. + - Total data crc and length. This is the crc and length of all of the data + stored in the gzip file, compressed and uncompressed. It is used to + reconstruct the gzip trailer when compressing, as well as when recovering + interrupted operations. + - Final stored block length. This is used to quickly find where to append, + and allows the restoration of the original final stored block state when + an append operation is interrupted. + - First stored block start as the number of bits back from the final stored + block first length byte. This value is in the range of 3..10, and is + stored as the low three bits of the final byte of the extra field after + subtracting three (0..7). This allows the last-block bit of the stored + block header to be updated when a new stored block is added, for the case + when the first stored block and the last stored block are the same. (When + they are different, the numbers of bits back is known to be eight.) This + also allows for new compressed data to be appended to the old compressed + data in the compress operation, overwriting the previous first stored + block, or for the compressed data to be terminated and a valid gzip file + reconstructed on the off chance that a compression operation was + interrupted and the data to compress in the foo.add file was deleted. + - The operation in process. This is the next two bits in the last byte (the + bits under the mask 0x18). The are interpreted as 0: nothing in process, + 1: append in process, 2: compress in process, 3: replace in process. + - The top three bits of the last byte in the extra field are reserved and + are currently set to zero. + + Main procedure: + - Exclusively create the foo.lock file using the O_CREAT and O_EXCL modes of + the system open() call. If the modify time of an existing lock file is + more than PATIENCE seconds old, then the lock file is deleted and the + exclusive create is retried. + - Load the extra field from the foo.gz file, and see if an operation was in + progress but not completed. If so, apply the recovery procedure below. + - Perform the append procedure with the provided data. + - If the uncompressed data in the foo.gz file is 1MB or more, apply the + compress procedure. + - Delete the foo.lock file. + + Append procedure: + - Put what to append in the foo.add file so that the operation can be + restarted if this procedure is interrupted. + - Mark the foo.gz extra field with the append operation in progress. + + Restore the original last-block bit and stored block length of the last + stored block from the information in the extra field, in case a previous + append operation was interrupted. + - Append the provided data to the last stored block, creating new stored + blocks as needed and updating the stored blocks last-block bits and + lengths. + - Update the crc and length with the new data, and write the gzip trailer. + - Write over the extra field (with a single write operation) with the new + pointers, lengths, and crc's, and mark the gzip file as not in process. + Though there is still a foo.add file, it will be ignored since nothing + is in process. If a foo.add file is leftover from a previously + completed operation, it is truncated when writing new data to it. + - Delete the foo.add file. + + Compress and replace procedures: + - Read all of the uncompressed data in the stored blocks in foo.gz and write + it to foo.add. Also write foo.temp with the last 32K of that data to + provide a dictionary for the next invocation of this procedure. + - Rewrite the extra field marking foo.gz with a compression in process. + * If there is no data provided to compress (due to a missing foo.add file + when recovering), reconstruct and truncate the foo.gz file to contain + only the previous compressed data and proceed to the step after the next + one. Otherwise ... + - Compress the data with the dictionary in foo.dict, and write to the + foo.gz file starting at the bit immediately following the last previously + compressed block. If there is no foo.dict, proceed anyway with the + compression at slightly reduced efficiency. (For the foo.dict file to be + missing requires some external failure beyond simply the interruption of + a compress operation.) During this process, the foo.lock file is + periodically touched to assure that that file is not considered stale by + another process before we're done. The deflation is terminated with a + non-last empty static block (10 bits long), that is then located and + written over by a last-bit-set empty stored block. + - Append the crc and length of the data in the gzip file (previously + calculated during the append operations). + - Write over the extra field with the updated stored block offsets, bits + back, crc's, and lengths, and mark foo.gz as in process for a replacement + of the dictionary. + @ Delete the foo.add file. + - Replace foo.dict with foo.temp. + - Write over the extra field, marking foo.gz as complete. + + Recovery procedure: + - If not a replace recovery, read in the foo.add file, and provide that data + to the appropriate recovery below. If there is no foo.add file, provide + a zero data length to the recovery. In that case, the append recovery + restores the foo.gz to the previous compressed + uncompressed data state. + For the the compress recovery, a missing foo.add file results in foo.gz + being restored to the previous compressed-only data state. + - Append recovery: + - Pick up append at + step above + - Compress recovery: + - Pick up compress at * step above + - Replace recovery: + - Pick up compress at @ step above + - Log the repair with a date stamp in foo.repairs + */ + +#include +#include /* rename, fopen, fprintf, fclose */ +#include /* malloc, free */ +#include /* strlen, strrchr, strcpy, strncpy, strcmp */ +#include /* open */ +#include /* lseek, read, write, close, unlink, sleep, */ + /* ftruncate, fsync */ +#include /* errno */ +#include /* time, ctime */ +#include /* stat */ +#include /* utimes */ +#include "zlib.h" /* crc32 */ + +#include "gzlog.h" /* header for external access */ + +#define local static +typedef unsigned int uint; +typedef unsigned long ulong; + +/* Macro for debugging to deterministically force recovery operations */ +#ifdef DEBUG + #include /* longjmp */ + jmp_buf gzlog_jump; /* where to go back to */ + int gzlog_bail = 0; /* which point to bail at (1..8) */ + int gzlog_count = -1; /* number of times through to wait */ +# define BAIL(n) do { if (n == gzlog_bail && gzlog_count-- == 0) \ + longjmp(gzlog_jump, gzlog_bail); } while (0) +#else +# define BAIL(n) +#endif + +/* how old the lock file can be in seconds before considering it stale */ +#define PATIENCE 300 + +/* maximum stored block size in Kbytes -- must be in 1..63 */ +#define MAX_STORE 16 + +/* number of stored Kbytes to trigger compression (must be >= 32 to allow + dictionary construction, and <= 204 * MAX_STORE, in order for >> 10 to + discard the stored block headers contribution of five bytes each) */ +#define TRIGGER 1024 + +/* size of a deflate dictionary (this cannot be changed) */ +#define DICT 32768U + +/* values for the operation (2 bits) */ +#define NO_OP 0 +#define APPEND_OP 1 +#define COMPRESS_OP 2 +#define REPLACE_OP 3 + +/* macros to extract little-endian integers from an unsigned byte buffer */ +#define PULL2(p) ((p)[0]+((uint)((p)[1])<<8)) +#define PULL4(p) (PULL2(p)+((ulong)PULL2(p+2)<<16)) +#define PULL8(p) (PULL4(p)+((off_t)PULL4(p+4)<<32)) + +/* macros to store integers into a byte buffer in little-endian order */ +#define PUT2(p,a) do {(p)[0]=a;(p)[1]=(a)>>8;} while(0) +#define PUT4(p,a) do {PUT2(p,a);PUT2(p+2,a>>16);} while(0) +#define PUT8(p,a) do {PUT4(p,a);PUT4(p+4,a>>32);} while(0) + +/* internal structure for log information */ +#define LOGID "\106\035\172" /* should be three non-zero characters */ +struct log { + char id[4]; /* contains LOGID to detect inadvertent overwrites */ + int fd; /* file descriptor for .gz file, opened read/write */ + char *path; /* allocated path, e.g. "/var/log/foo" or "foo" */ + char *end; /* end of path, for appending suffices such as ".gz" */ + off_t first; /* offset of first stored block first length byte */ + int back; /* location of first block id in bits back from first */ + uint stored; /* bytes currently in last stored block */ + off_t last; /* offset of last stored block first length byte */ + ulong ccrc; /* crc of compressed data */ + ulong clen; /* length (modulo 2^32) of compressed data */ + ulong tcrc; /* crc of total data */ + ulong tlen; /* length (modulo 2^32) of total data */ + time_t lock; /* last modify time of our lock file */ +}; + +/* gzip header for gzlog */ +local unsigned char log_gzhead[] = { + 0x1f, 0x8b, /* magic gzip id */ + 8, /* compression method is deflate */ + 4, /* there is an extra field (no file name) */ + 0, 0, 0, 0, /* no modification time provided */ + 0, 0xff, /* no extra flags, no OS specified */ + 39, 0, 'a', 'p', 35, 0 /* extra field with "ap" subfield */ + /* 35 is EXTRA, 39 is EXTRA + 4 */ +}; + +#define HEAD sizeof(log_gzhead) /* should be 16 */ + +/* initial gzip extra field content (52 == HEAD + EXTRA + 1) */ +local unsigned char log_gzext[] = { + 52, 0, 0, 0, 0, 0, 0, 0, /* offset of first stored block length */ + 52, 0, 0, 0, 0, 0, 0, 0, /* offset of last stored block length */ + 0, 0, 0, 0, 0, 0, 0, 0, /* compressed data crc and length */ + 0, 0, 0, 0, 0, 0, 0, 0, /* total data crc and length */ + 0, 0, /* final stored block data length */ + 5 /* op is NO_OP, last bit 8 bits back */ +}; + +#define EXTRA sizeof(log_gzext) /* should be 35 */ + +/* initial gzip data and trailer */ +local unsigned char log_gzbody[] = { + 1, 0, 0, 0xff, 0xff, /* empty stored block (last) */ + 0, 0, 0, 0, /* crc */ + 0, 0, 0, 0 /* uncompressed length */ +}; + +#define BODY sizeof(log_gzbody) + +/* Exclusively create foo.lock in order to negotiate exclusive access to the + foo.* files. If the modify time of an existing lock file is greater than + PATIENCE seconds in the past, then consider the lock file to have been + abandoned, delete it, and try the exclusive create again. Save the lock + file modify time for verification of ownership. Return 0 on success, or -1 + on failure, usually due to an access restriction or invalid path. Note that + if stat() or unlink() fails, it may be due to another process noticing the + abandoned lock file a smidge sooner and deleting it, so those are not + flagged as an error. */ +local int log_lock(struct log *log) +{ + int fd; + struct stat st; + + strcpy(log->end, ".lock"); + while ((fd = open(log->path, O_CREAT | O_EXCL, 0644)) < 0) { + if (errno != EEXIST) + return -1; + if (stat(log->path, &st) == 0 && time(NULL) - st.st_mtime > PATIENCE) { + unlink(log->path); + continue; + } + sleep(2); /* relinquish the CPU for two seconds while waiting */ + } + close(fd); + if (stat(log->path, &st) == 0) + log->lock = st.st_mtime; + return 0; +} + +/* Update the modify time of the lock file to now, in order to prevent another + task from thinking that the lock is stale. Save the lock file modify time + for verification of ownership. */ +local void log_touch(struct log *log) +{ + struct stat st; + + strcpy(log->end, ".lock"); + utimes(log->path, NULL); + if (stat(log->path, &st) == 0) + log->lock = st.st_mtime; +} + +/* Check the log file modify time against what is expected. Return true if + this is not our lock. If it is our lock, touch it to keep it. */ +local int log_check(struct log *log) +{ + struct stat st; + + strcpy(log->end, ".lock"); + if (stat(log->path, &st) || st.st_mtime != log->lock) + return 1; + log_touch(log); + return 0; +} + +/* Unlock a previously acquired lock, but only if it's ours. */ +local void log_unlock(struct log *log) +{ + if (log_check(log)) + return; + strcpy(log->end, ".lock"); + unlink(log->path); + log->lock = 0; +} + +/* Check the gzip header and read in the extra field, filling in the values in + the log structure. Return op on success or -1 if the gzip header was not as + expected. op is the current operation in progress last written to the extra + field. This assumes that the gzip file has already been opened, with the + file descriptor log->fd. */ +local int log_head(struct log *log) +{ + int op; + unsigned char buf[HEAD + EXTRA]; + + if (lseek(log->fd, 0, SEEK_SET) < 0 || + read(log->fd, buf, HEAD + EXTRA) != HEAD + EXTRA || + memcmp(buf, log_gzhead, HEAD)) { + return -1; + } + log->first = PULL8(buf + HEAD); + log->last = PULL8(buf + HEAD + 8); + log->ccrc = PULL4(buf + HEAD + 16); + log->clen = PULL4(buf + HEAD + 20); + log->tcrc = PULL4(buf + HEAD + 24); + log->tlen = PULL4(buf + HEAD + 28); + log->stored = PULL2(buf + HEAD + 32); + log->back = 3 + (buf[HEAD + 34] & 7); + op = (buf[HEAD + 34] >> 3) & 3; + return op; +} + +/* Write over the extra field contents, marking the operation as op. Use fsync + to assure that the device is written to, and in the requested order. This + operation, and only this operation, is assumed to be atomic in order to + assure that the log is recoverable in the event of an interruption at any + point in the process. Return -1 if the write to foo.gz failed. */ +local int log_mark(struct log *log, int op) +{ + int ret; + unsigned char ext[EXTRA]; + + PUT8(ext, log->first); + PUT8(ext + 8, log->last); + PUT4(ext + 16, log->ccrc); + PUT4(ext + 20, log->clen); + PUT4(ext + 24, log->tcrc); + PUT4(ext + 28, log->tlen); + PUT2(ext + 32, log->stored); + ext[34] = log->back - 3 + (op << 3); + fsync(log->fd); + ret = lseek(log->fd, HEAD, SEEK_SET) < 0 || + write(log->fd, ext, EXTRA) != EXTRA ? -1 : 0; + fsync(log->fd); + return ret; +} + +/* Rewrite the last block header bits and subsequent zero bits to get to a byte + boundary, setting the last block bit if last is true, and then write the + remainder of the stored block header (length and one's complement). Leave + the file pointer after the end of the last stored block data. Return -1 if + there is a read or write failure on the foo.gz file */ +local int log_last(struct log *log, int last) +{ + int back, len, mask; + unsigned char buf[6]; + + /* determine the locations of the bytes and bits to modify */ + back = log->last == log->first ? log->back : 8; + len = back > 8 ? 2 : 1; /* bytes back from log->last */ + mask = 0x80 >> ((back - 1) & 7); /* mask for block last-bit */ + + /* get the byte to modify (one or two back) into buf[0] -- don't need to + read the byte if the last-bit is eight bits back, since in that case + the entire byte will be modified */ + buf[0] = 0; + if (back != 8 && (lseek(log->fd, log->last - len, SEEK_SET) < 0 || + read(log->fd, buf, 1) != 1)) + return -1; + + /* change the last-bit of the last stored block as requested -- note + that all bits above the last-bit are set to zero, per the type bits + of a stored block being 00 and per the convention that the bits to + bring the stream to a byte boundary are also zeros */ + buf[1] = 0; + buf[2 - len] = (*buf & (mask - 1)) + (last ? mask : 0); + + /* write the modified stored block header and lengths, move the file + pointer to after the last stored block data */ + PUT2(buf + 2, log->stored); + PUT2(buf + 4, log->stored ^ 0xffff); + return lseek(log->fd, log->last - len, SEEK_SET) < 0 || + write(log->fd, buf + 2 - len, len + 4) != len + 4 || + lseek(log->fd, log->stored, SEEK_CUR) < 0 ? -1 : 0; +} + +/* Append len bytes from data to the locked and open log file. len may be zero + if recovering and no .add file was found. In that case, the previous state + of the foo.gz file is restored. The data is appended uncompressed in + deflate stored blocks. Return -1 if there was an error reading or writing + the foo.gz file. */ +local int log_append(struct log *log, unsigned char *data, size_t len) +{ + uint put; + off_t end; + unsigned char buf[8]; + + /* set the last block last-bit and length, in case recovering an + interrupted append, then position the file pointer to append to the + block */ + if (log_last(log, 1)) + return -1; + + /* append, adding stored blocks and updating the offset of the last stored + block as needed, and update the total crc and length */ + while (len) { + /* append as much as we can to the last block */ + put = (MAX_STORE << 10) - log->stored; + if (put > len) + put = (uint)len; + if (put) { + if (write(log->fd, data, put) != put) + return -1; + BAIL(1); + log->tcrc = crc32(log->tcrc, data, put); + log->tlen += put; + log->stored += put; + data += put; + len -= put; + } + + /* if we need to, add a new empty stored block */ + if (len) { + /* mark current block as not last */ + if (log_last(log, 0)) + return -1; + + /* point to new, empty stored block */ + log->last += 4 + log->stored + 1; + log->stored = 0; + } + + /* mark last block as last, update its length */ + if (log_last(log, 1)) + return -1; + BAIL(2); + } + + /* write the new crc and length trailer, and truncate just in case (could + be recovering from partial append with a missing foo.add file) */ + PUT4(buf, log->tcrc); + PUT4(buf + 4, log->tlen); + if (write(log->fd, buf, 8) != 8 || + (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end)) + return -1; + + /* write the extra field, marking the log file as done, delete .add file */ + if (log_mark(log, NO_OP)) + return -1; + strcpy(log->end, ".add"); + unlink(log->path); /* ignore error, since may not exist */ + return 0; +} + +/* Replace the foo.dict file with the foo.temp file. Also delete the foo.add + file, since the compress operation may have been interrupted before that was + done. Returns 1 if memory could not be allocated, or -1 if reading or + writing foo.gz fails, or if the rename fails for some reason other than + foo.temp not existing. foo.temp not existing is a permitted error, since + the replace operation may have been interrupted after the rename is done, + but before foo.gz is marked as complete. */ +local int log_replace(struct log *log) +{ + int ret; + char *dest; + + /* delete foo.add file */ + strcpy(log->end, ".add"); + unlink(log->path); /* ignore error, since may not exist */ + BAIL(3); + + /* rename foo.name to foo.dict, replacing foo.dict if it exists */ + strcpy(log->end, ".dict"); + dest = malloc(strlen(log->path) + 1); + if (dest == NULL) + return -2; + strcpy(dest, log->path); + strcpy(log->end, ".temp"); + ret = rename(log->path, dest); + free(dest); + if (ret && errno != ENOENT) + return -1; + BAIL(4); + + /* mark the foo.gz file as done */ + return log_mark(log, NO_OP); +} + +/* Compress the len bytes at data and append the compressed data to the + foo.gz deflate data immediately after the previous compressed data. This + overwrites the previous uncompressed data, which was stored in foo.add + and is the data provided in data[0..len-1]. If this operation is + interrupted, it picks up at the start of this routine, with the foo.add + file read in again. If there is no data to compress (len == 0), then we + simply terminate the foo.gz file after the previously compressed data, + appending a final empty stored block and the gzip trailer. Return -1 if + reading or writing the log.gz file failed, or -2 if there was a memory + allocation failure. */ +local int log_compress(struct log *log, unsigned char *data, size_t len) +{ + int fd; + uint got, max; + ssize_t dict; + off_t end; + z_stream strm; + unsigned char buf[DICT]; + + /* compress and append compressed data */ + if (len) { + /* set up for deflate, allocating memory */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, + Z_DEFAULT_STRATEGY) != Z_OK) + return -2; + + /* read in dictionary (last 32K of data that was compressed) */ + strcpy(log->end, ".dict"); + fd = open(log->path, O_RDONLY, 0); + if (fd >= 0) { + dict = read(fd, buf, DICT); + close(fd); + if (dict < 0) { + deflateEnd(&strm); + return -1; + } + if (dict) + deflateSetDictionary(&strm, buf, (uint)dict); + } + log_touch(log); + + /* prime deflate with last bits of previous block, position write + pointer to write those bits and overwrite what follows */ + if (lseek(log->fd, log->first - (log->back > 8 ? 2 : 1), + SEEK_SET) < 0 || + read(log->fd, buf, 1) != 1 || lseek(log->fd, -1, SEEK_CUR) < 0) { + deflateEnd(&strm); + return -1; + } + deflatePrime(&strm, (8 - log->back) & 7, *buf); + + /* compress, finishing with a partial non-last empty static block */ + strm.next_in = data; + max = (((uint)0 - 1) >> 1) + 1; /* in case int smaller than size_t */ + do { + strm.avail_in = len > max ? max : (uint)len; + len -= strm.avail_in; + do { + strm.avail_out = DICT; + strm.next_out = buf; + deflate(&strm, len ? Z_NO_FLUSH : Z_PARTIAL_FLUSH); + got = DICT - strm.avail_out; + if (got && write(log->fd, buf, got) != got) { + deflateEnd(&strm); + return -1; + } + log_touch(log); + } while (strm.avail_out == 0); + } while (len); + deflateEnd(&strm); + BAIL(5); + + /* find start of empty static block -- scanning backwards the first one + bit is the second bit of the block, if the last byte is zero, then + we know the byte before that has a one in the top bit, since an + empty static block is ten bits long */ + if ((log->first = lseek(log->fd, -1, SEEK_CUR)) < 0 || + read(log->fd, buf, 1) != 1) + return -1; + log->first++; + if (*buf) { + log->back = 1; + while ((*buf & ((uint)1 << (8 - log->back++))) == 0) + ; /* guaranteed to terminate, since *buf != 0 */ + } + else + log->back = 10; + + /* update compressed crc and length */ + log->ccrc = log->tcrc; + log->clen = log->tlen; + } + else { + /* no data to compress -- fix up existing gzip stream */ + log->tcrc = log->ccrc; + log->tlen = log->clen; + } + + /* complete and truncate gzip stream */ + log->last = log->first; + log->stored = 0; + PUT4(buf, log->tcrc); + PUT4(buf + 4, log->tlen); + if (log_last(log, 1) || write(log->fd, buf, 8) != 8 || + (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end)) + return -1; + BAIL(6); + + /* mark as being in the replace operation */ + if (log_mark(log, REPLACE_OP)) + return -1; + + /* execute the replace operation and mark the file as done */ + return log_replace(log); +} + +/* log a repair record to the .repairs file */ +local void log_log(struct log *log, int op, char *record) +{ + time_t now; + FILE *rec; + + now = time(NULL); + strcpy(log->end, ".repairs"); + rec = fopen(log->path, "a"); + if (rec == NULL) + return; + fprintf(rec, "%.24s %s recovery: %s\n", ctime(&now), op == APPEND_OP ? + "append" : (op == COMPRESS_OP ? "compress" : "replace"), record); + fclose(rec); + return; +} + +/* Recover the interrupted operation op. First read foo.add for recovering an + append or compress operation. Return -1 if there was an error reading or + writing foo.gz or reading an existing foo.add, or -2 if there was a memory + allocation failure. */ +local int log_recover(struct log *log, int op) +{ + int fd, ret = 0; + unsigned char *data = NULL; + size_t len = 0; + struct stat st; + + /* log recovery */ + log_log(log, op, "start"); + + /* load foo.add file if expected and present */ + if (op == APPEND_OP || op == COMPRESS_OP) { + strcpy(log->end, ".add"); + if (stat(log->path, &st) == 0 && st.st_size) { + len = (size_t)(st.st_size); + if (len != st.st_size || (data = malloc(st.st_size)) == NULL) { + log_log(log, op, "allocation failure"); + return -2; + } + if ((fd = open(log->path, O_RDONLY, 0)) < 0) { + log_log(log, op, ".add file read failure"); + return -1; + } + ret = read(fd, data, len) != len; + close(fd); + if (ret) { + log_log(log, op, ".add file read failure"); + return -1; + } + log_log(log, op, "loaded .add file"); + } + else + log_log(log, op, "missing .add file!"); + } + + /* recover the interrupted operation */ + switch (op) { + case APPEND_OP: + ret = log_append(log, data, len); + break; + case COMPRESS_OP: + ret = log_compress(log, data, len); + break; + case REPLACE_OP: + ret = log_replace(log); + } + + /* log status */ + log_log(log, op, ret ? "failure" : "complete"); + + /* clean up */ + if (data != NULL) + free(data); + return ret; +} + +/* Close the foo.gz file (if open) and release the lock. */ +local void log_close(struct log *log) +{ + if (log->fd >= 0) + close(log->fd); + log->fd = -1; + log_unlock(log); +} + +/* Open foo.gz, verify the header, and load the extra field contents, after + first creating the foo.lock file to gain exclusive access to the foo.* + files. If foo.gz does not exist or is empty, then write the initial header, + extra, and body content of an empty foo.gz log file. If there is an error + creating the lock file due to access restrictions, or an error reading or + writing the foo.gz file, or if the foo.gz file is not a proper log file for + this object (e.g. not a gzip file or does not contain the expected extra + field), then return true. If there is an error, the lock is released. + Otherwise, the lock is left in place. */ +local int log_open(struct log *log) +{ + int op; + + /* release open file resource if left over -- can occur if lock lost + between gzlog_open() and gzlog_write() */ + if (log->fd >= 0) + close(log->fd); + log->fd = -1; + + /* negotiate exclusive access */ + if (log_lock(log) < 0) + return -1; + + /* open the log file, foo.gz */ + strcpy(log->end, ".gz"); + log->fd = open(log->path, O_RDWR | O_CREAT, 0644); + if (log->fd < 0) { + log_close(log); + return -1; + } + + /* if new, initialize foo.gz with an empty log, delete old dictionary */ + if (lseek(log->fd, 0, SEEK_END) == 0) { + if (write(log->fd, log_gzhead, HEAD) != HEAD || + write(log->fd, log_gzext, EXTRA) != EXTRA || + write(log->fd, log_gzbody, BODY) != BODY) { + log_close(log); + return -1; + } + strcpy(log->end, ".dict"); + unlink(log->path); + } + + /* verify log file and load extra field information */ + if ((op = log_head(log)) < 0) { + log_close(log); + return -1; + } + + /* check for interrupted process and if so, recover */ + if (op != NO_OP && log_recover(log, op)) { + log_close(log); + return -1; + } + + /* touch the lock file to prevent another process from grabbing it */ + log_touch(log); + return 0; +} + +/* See gzlog.h for the description of the external methods below */ +gzlog *gzlog_open(char *path) +{ + size_t n; + struct log *log; + + /* check arguments */ + if (path == NULL || *path == 0) + return NULL; + + /* allocate and initialize log structure */ + log = malloc(sizeof(struct log)); + if (log == NULL) + return NULL; + strcpy(log->id, LOGID); + log->fd = -1; + + /* save path and end of path for name construction */ + n = strlen(path); + log->path = malloc(n + 9); /* allow for ".repairs" */ + if (log->path == NULL) { + free(log); + return NULL; + } + strcpy(log->path, path); + log->end = log->path + n; + + /* gain exclusive access and verify log file -- may perform a + recovery operation if needed */ + if (log_open(log)) { + free(log->path); + free(log); + return NULL; + } + + /* return pointer to log structure */ + return log; +} + +/* gzlog_compress() return values: + 0: all good + -1: file i/o error (usually access issue) + -2: memory allocation failure + -3: invalid log pointer argument */ +int gzlog_compress(gzlog *logd) +{ + int fd, ret; + uint block; + size_t len, next; + unsigned char *data, buf[5]; + struct log *log = logd; + + /* check arguments */ + if (log == NULL || strcmp(log->id, LOGID) || len < 0) + return -3; + + /* see if we lost the lock -- if so get it again and reload the extra + field information (it probably changed), recover last operation if + necessary */ + if (log_check(log) && log_open(log)) + return -1; + + /* create space for uncompressed data */ + len = ((size_t)(log->last - log->first) & ~(((size_t)1 << 10) - 1)) + + log->stored; + if ((data = malloc(len)) == NULL) + return -2; + + /* do statement here is just a cheap trick for error handling */ + do { + /* read in the uncompressed data */ + if (lseek(log->fd, log->first - 1, SEEK_SET) < 0) + break; + next = 0; + while (next < len) { + if (read(log->fd, buf, 5) != 5) + break; + block = PULL2(buf + 1); + if (next + block > len || + read(log->fd, (char *)data + next, block) != block) + break; + next += block; + } + if (lseek(log->fd, 0, SEEK_CUR) != log->last + 4 + log->stored) + break; + log_touch(log); + + /* write the uncompressed data to the .add file */ + strcpy(log->end, ".add"); + fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + break; + ret = write(fd, data, len) != len; + if (ret | close(fd)) + break; + log_touch(log); + + /* write the dictionary for the next compress to the .temp file */ + strcpy(log->end, ".temp"); + fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + break; + next = DICT > len ? len : DICT; + ret = write(fd, (char *)data + len - next, next) != next; + if (ret | close(fd)) + break; + log_touch(log); + + /* roll back to compressed data, mark the compress in progress */ + log->last = log->first; + log->stored = 0; + if (log_mark(log, COMPRESS_OP)) + break; + BAIL(7); + + /* compress and append the data (clears mark) */ + ret = log_compress(log, data, len); + free(data); + return ret; + } while (0); + + /* broke out of do above on i/o error */ + free(data); + return -1; +} + +/* gzlog_write() return values: + 0: all good + -1: file i/o error (usually access issue) + -2: memory allocation failure + -3: invalid log pointer argument */ +int gzlog_write(gzlog *logd, void *data, size_t len) +{ + int fd, ret; + struct log *log = logd; + + /* check arguments */ + if (log == NULL || strcmp(log->id, LOGID) || len < 0) + return -3; + if (data == NULL || len == 0) + return 0; + + /* see if we lost the lock -- if so get it again and reload the extra + field information (it probably changed), recover last operation if + necessary */ + if (log_check(log) && log_open(log)) + return -1; + + /* create and write .add file */ + strcpy(log->end, ".add"); + fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + return -1; + ret = write(fd, data, len) != len; + if (ret | close(fd)) + return -1; + log_touch(log); + + /* mark log file with append in progress */ + if (log_mark(log, APPEND_OP)) + return -1; + BAIL(8); + + /* append data (clears mark) */ + if (log_append(log, data, len)) + return -1; + + /* check to see if it's time to compress -- if not, then done */ + if (((log->last - log->first) >> 10) + (log->stored >> 10) < TRIGGER) + return 0; + + /* time to compress */ + return gzlog_compress(log); +} + +/* gzlog_close() return values: + 0: ok + -3: invalid log pointer argument */ +int gzlog_close(gzlog *logd) +{ + struct log *log = logd; + + /* check arguments */ + if (log == NULL || strcmp(log->id, LOGID)) + return -3; + + /* close the log file and release the lock */ + log_close(log); + + /* free structure and return */ + if (log->path != NULL) + free(log->path); + strcpy(log->id, "bad"); + free(log); + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzlog.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzlog.h new file mode 100644 index 00000000..c4614267 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/gzlog.h @@ -0,0 +1,89 @@ +/* gzlog.h + Copyright (C) 2004, 2008 Mark Adler, all rights reserved + version 2.0, 25 Apr 2008 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + +/* Version History: + 1.0 26 Nov 2004 First version + 2.0 25 Apr 2008 Complete redesign for recovery of interrupted operations + Interface changed slightly in that now path is a prefix + Compression now occurs as needed during gzlog_write() + gzlog_write() now always leaves the log file as valid gzip + */ + +/* + The gzlog object allows writing short messages to a gzipped log file, + opening the log file locked for small bursts, and then closing it. The log + object works by appending stored (uncompressed) data to the gzip file until + 1 MB has been accumulated. At that time, the stored data is compressed, and + replaces the uncompressed data in the file. The log file is truncated to + its new size at that time. After each write operation, the log file is a + valid gzip file that can decompressed to recover what was written. + + The gzlog operations can be interupted at any point due to an application or + system crash, and the log file will be recovered the next time the log is + opened with gzlog_open(). + */ + +#ifndef GZLOG_H +#define GZLOG_H + +/* gzlog object type */ +typedef void gzlog; + +/* Open a gzlog object, creating the log file if it does not exist. Return + NULL on error. Note that gzlog_open() could take a while to complete if it + has to wait to verify that a lock is stale (possibly for five minutes), or + if there is significant contention with other instantiations of this object + when locking the resource. path is the prefix of the file names created by + this object. If path is "foo", then the log file will be "foo.gz", and + other auxiliary files will be created and destroyed during the process: + "foo.dict" for a compression dictionary, "foo.temp" for a temporary (next) + dictionary, "foo.add" for data being added or compressed, "foo.lock" for the + lock file, and "foo.repairs" to log recovery operations performed due to + interrupted gzlog operations. A gzlog_open() followed by a gzlog_close() + will recover a previously interrupted operation, if any. */ +gzlog *gzlog_open(char *path); + +/* Write to a gzlog object. Return zero on success, -1 if there is a file i/o + error on any of the gzlog files (this should not happen if gzlog_open() + succeeded, unless the device has run out of space or leftover auxiliary + files have permissions or ownership that prevent their use), -2 if there is + a memory allocation failure, or -3 if the log argument is invalid (e.g. if + it was not created by gzlog_open()). This function will write data to the + file uncompressed, until 1 MB has been accumulated, at which time that data + will be compressed. The log file will be a valid gzip file upon successful + return. */ +int gzlog_write(gzlog *log, void *data, size_t len); + +/* Force compression of any uncompressed data in the log. This should be used + sparingly, if at all. The main application would be when a log file will + not be appended to again. If this is used to compress frequently while + appending, it will both significantly increase the execution time and + reduce the compression ratio. The return codes are the same as for + gzlog_write(). */ +int gzlog_compress(gzlog *log); + +/* Close a gzlog object. Return zero on success, -3 if the log argument is + invalid. The log object is freed, and so cannot be referenced again. */ +int gzlog_close(gzlog *log); + +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/zlib_how.html b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/zlib_how.html new file mode 100644 index 00000000..444ff1c9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/zlib_how.html @@ -0,0 +1,545 @@ + + + + +zlib Usage Example + + + +

zlib Usage Example

+We often get questions about how the deflate() and inflate() functions should be used. +Users wonder when they should provide more input, when they should use more output, +what to do with a Z_BUF_ERROR, how to make sure the process terminates properly, and +so on. So for those who have read zlib.h (a few times), and +would like further edification, below is an annotated example in C of simple routines to compress and decompress +from an input file to an output file using deflate() and inflate() respectively. The +annotations are interspersed between lines of the code. So please read between the lines. +We hope this helps explain some of the intricacies of zlib. +

+Without further adieu, here is the program zpipe.c: +


+/* zpipe.c: example of proper use of zlib's inflate() and deflate()
+   Not copyrighted -- provided to the public domain
+   Version 1.4  11 December 2005  Mark Adler */
+
+/* Version history:
+   1.0  30 Oct 2004  First version
+   1.1   8 Nov 2004  Add void casting for unused return values
+                     Use switch statement for inflate() return values
+   1.2   9 Nov 2004  Add assertions to document zlib guarantees
+   1.3   6 Apr 2005  Remove incorrect assertion in inf()
+   1.4  11 Dec 2005  Add hack to avoid MSDOS end-of-line conversions
+                     Avoid some compiler warnings for input and output buffers
+ */
+
+We now include the header files for the required definitions. From +stdio.h we use fopen(), fread(), fwrite(), +feof(), ferror(), and fclose() for file i/o, and +fputs() for error messages. From string.h we use +strcmp() for command line argument processing. +From assert.h we use the assert() macro. +From zlib.h +we use the basic compression functions deflateInit(), +deflate(), and deflateEnd(), and the basic decompression +functions inflateInit(), inflate(), and +inflateEnd(). +

+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "zlib.h"
+
+This is an ugly hack required to avoid corruption of the input and output data on +Windows/MS-DOS systems. Without this, those systems would assume that the input and output +files are text, and try to convert the end-of-line characters from one standard to +another. That would corrupt binary data, and in particular would render the compressed data unusable. +This sets the input and output to binary which suppresses the end-of-line conversions. +SET_BINARY_MODE() will be used later on stdin and stdout, at the beginning of main(). +

+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include <fcntl.h>
+#  include <io.h>
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+CHUNK is simply the buffer size for feeding data to and pulling data +from the zlib routines. Larger buffer sizes would be more efficient, +especially for inflate(). If the memory is available, buffers sizes +on the order of 128K or 256K bytes should be used. +

+#define CHUNK 16384
+
+The def() routine compresses data from an input file to an output file. The output data +will be in the zlib format, which is different from the gzip or zip +formats. The zlib format has a very small header of only two bytes to identify it as +a zlib stream and to provide decoding information, and a four-byte trailer with a fast +check value to verify the integrity of the uncompressed data after decoding. +

+/* Compress from file source to file dest until EOF on source.
+   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_STREAM_ERROR if an invalid compression
+   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
+   version of the library linked do not match, or Z_ERRNO if there is
+   an error reading or writing the files. */
+int def(FILE *source, FILE *dest, int level)
+{
+
+Here are the local variables for def(). ret will be used for zlib +return codes. flush will keep track of the current flushing state for deflate(), +which is either no flushing, or flush to completion after the end of the input file is reached. +have is the amount of data returned from deflate(). The strm structure +is used to pass information to and from the zlib routines, and to maintain the +deflate() state. in and out are the input and output buffers for +deflate(). +

+    int ret, flush;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+
+The first thing we do is to initialize the zlib state for compression using +deflateInit(). This must be done before the first use of deflate(). +The zalloc, zfree, and opaque fields in the strm +structure must be initialized before calling deflateInit(). Here they are +set to the zlib constant Z_NULL to request that zlib use +the default memory allocation routines. An application may also choose to provide +custom memory allocation routines here. deflateInit() will allocate on the +order of 256K bytes for the internal state. +(See zlib Technical Details.) +

+deflateInit() is called with a pointer to the structure to be initialized and +the compression level, which is an integer in the range of -1 to 9. Lower compression +levels result in faster execution, but less compression. Higher levels result in +greater compression, but slower execution. The zlib constant Z_DEFAULT_COMPRESSION, +equal to -1, +provides a good compromise between compression and speed and is equivalent to level 6. +Level 0 actually does no compression at all, and in fact expands the data slightly to produce +the zlib format (it is not a byte-for-byte copy of the input). +More advanced applications of zlib +may use deflateInit2() here instead. Such an application may want to reduce how +much memory will be used, at some price in compression. Or it may need to request a +gzip header and trailer instead of a zlib header and trailer, or raw +encoding with no header or trailer at all. +

+We must check the return value of deflateInit() against the zlib constant +Z_OK to make sure that it was able to +allocate memory for the internal state, and that the provided arguments were valid. +deflateInit() will also check that the version of zlib that the zlib.h +file came from matches the version of zlib actually linked with the program. This +is especially important for environments in which zlib is a shared library. +

+Note that an application can initialize multiple, independent zlib streams, which can +operate in parallel. The state information maintained in the structure allows the zlib +routines to be reentrant. +


+    /* allocate deflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = deflateInit(&strm, level);
+    if (ret != Z_OK)
+        return ret;
+
+With the pleasantries out of the way, now we can get down to business. The outer do-loop +reads all of the input file and exits at the bottom of the loop once end-of-file is reached. +This loop contains the only call of deflate(). So we must make sure that all of the +input data has been processed and that all of the output data has been generated and consumed +before we fall out of the loop at the bottom. +

+    /* compress until end of file */
+    do {
+
+We start off by reading data from the input file. The number of bytes read is put directly +into avail_in, and a pointer to those bytes is put into next_in. We also +check to see if end-of-file on the input has been reached. If we are at the end of file, then flush is set to the +zlib constant Z_FINISH, which is later passed to deflate() to +indicate that this is the last chunk of input data to compress. We need to use feof() +to check for end-of-file as opposed to seeing if fewer than CHUNK bytes have been read. The +reason is that if the input file length is an exact multiple of CHUNK, we will miss +the fact that we got to the end-of-file, and not know to tell deflate() to finish +up the compressed stream. If we are not yet at the end of the input, then the zlib +constant Z_NO_FLUSH will be passed to deflate to indicate that we are still +in the middle of the uncompressed data. +

+If there is an error in reading from the input file, the process is aborted with +deflateEnd() being called to free the allocated zlib state before returning +the error. We wouldn't want a memory leak, now would we? deflateEnd() can be called +at any time after the state has been initialized. Once that's done, deflateInit() (or +deflateInit2()) would have to be called to start a new compression process. There is +no point here in checking the deflateEnd() return code. The deallocation can't fail. +


+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)deflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
+        strm.next_in = in;
+
+The inner do-loop passes our chunk of input data to deflate(), and then +keeps calling deflate() until it is done producing output. Once there is no more +new output, deflate() is guaranteed to have consumed all of the input, i.e., +avail_in will be zero. +

+        /* run deflate() on input until output buffer not full, finish
+           compression if all of source has been read in */
+        do {
+
+Output space is provided to deflate() by setting avail_out to the number +of available output bytes and next_out to a pointer to that space. +

+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+
+Now we call the compression engine itself, deflate(). It takes as many of the +avail_in bytes at next_in as it can process, and writes as many as +avail_out bytes to next_out. Those counters and pointers are then +updated past the input data consumed and the output data written. It is the amount of +output space available that may limit how much input is consumed. +Hence the inner loop to make sure that +all of the input is consumed by providing more output space each time. Since avail_in +and next_in are updated by deflate(), we don't have to mess with those +between deflate() calls until it's all used up. +

+The parameters to deflate() are a pointer to the strm structure containing +the input and output information and the internal compression engine state, and a parameter +indicating whether and how to flush data to the output. Normally deflate will consume +several K bytes of input data before producing any output (except for the header), in order +to accumulate statistics on the data for optimum compression. It will then put out a burst of +compressed data, and proceed to consume more input before the next burst. Eventually, +deflate() +must be told to terminate the stream, complete the compression with provided input data, and +write out the trailer check value. deflate() will continue to compress normally as long +as the flush parameter is Z_NO_FLUSH. Once the Z_FINISH parameter is provided, +deflate() will begin to complete the compressed output stream. However depending on how +much output space is provided, deflate() may have to be called several times until it +has provided the complete compressed stream, even after it has consumed all of the input. The flush +parameter must continue to be Z_FINISH for those subsequent calls. +

+There are other values of the flush parameter that are used in more advanced applications. You can +force deflate() to produce a burst of output that encodes all of the input data provided +so far, even if it wouldn't have otherwise, for example to control data latency on a link with +compressed data. You can also ask that deflate() do that as well as erase any history up to +that point so that what follows can be decompressed independently, for example for random access +applications. Both requests will degrade compression by an amount depending on how often such +requests are made. +

+deflate() has a return value that can indicate errors, yet we do not check it here. Why +not? Well, it turns out that deflate() can do no wrong here. Let's go through +deflate()'s return values and dispense with them one by one. The possible values are +Z_OK, Z_STREAM_END, Z_STREAM_ERROR, or Z_BUF_ERROR. Z_OK +is, well, ok. Z_STREAM_END is also ok and will be returned for the last call of +deflate(). This is already guaranteed by calling deflate() with Z_FINISH +until it has no more output. Z_STREAM_ERROR is only possible if the stream is not +initialized properly, but we did initialize it properly. There is no harm in checking for +Z_STREAM_ERROR here, for example to check for the possibility that some +other part of the application inadvertently clobbered the memory containing the zlib state. +Z_BUF_ERROR will be explained further below, but +suffice it to say that this is simply an indication that deflate() could not consume +more input or produce more output. deflate() can be called again with more output space +or more available input, which it will be in this code. +


+            ret = deflate(&strm, flush);    /* no bad return value */
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+
+Now we compute how much output deflate() provided on the last call, which is the +difference between how much space was provided before the call, and how much output space +is still available after the call. Then that data, if any, is written to the output file. +We can then reuse the output buffer for the next call of deflate(). Again if there +is a file i/o error, we call deflateEnd() before returning to avoid a memory leak. +

+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)deflateEnd(&strm);
+                return Z_ERRNO;
+            }
+
+The inner do-loop is repeated until the last deflate() call fails to fill the +provided output buffer. Then we know that deflate() has done as much as it can with +the provided input, and that all of that input has been consumed. We can then fall out of this +loop and reuse the input buffer. +

+The way we tell that deflate() has no more output is by seeing that it did not fill +the output buffer, leaving avail_out greater than zero. However suppose that +deflate() has no more output, but just so happened to exactly fill the output buffer! +avail_out is zero, and we can't tell that deflate() has done all it can. +As far as we know, deflate() +has more output for us. So we call it again. But now deflate() produces no output +at all, and avail_out remains unchanged as CHUNK. That deflate() call +wasn't able to do anything, either consume input or produce output, and so it returns +Z_BUF_ERROR. (See, I told you I'd cover this later.) However this is not a problem at +all. Now we finally have the desired indication that deflate() is really done, +and so we drop out of the inner loop to provide more input to deflate(). +

+With flush set to Z_FINISH, this final set of deflate() calls will +complete the output stream. Once that is done, subsequent calls of deflate() would return +Z_STREAM_ERROR if the flush parameter is not Z_FINISH, and do no more processing +until the state is reinitialized. +

+Some applications of zlib have two loops that call deflate() +instead of the single inner loop we have here. The first loop would call +without flushing and feed all of the data to deflate(). The second loop would call +deflate() with no more +data and the Z_FINISH parameter to complete the process. As you can see from this +example, that can be avoided by simply keeping track of the current flush state. +


+        } while (strm.avail_out == 0);
+        assert(strm.avail_in == 0);     /* all input will be used */
+
+Now we check to see if we have already processed all of the input file. That information was +saved in the flush variable, so we see if that was set to Z_FINISH. If so, +then we're done and we fall out of the outer loop. We're guaranteed to get Z_STREAM_END +from the last deflate() call, since we ran it until the last chunk of input was +consumed and all of the output was generated. +

+        /* done when last data in file processed */
+    } while (flush != Z_FINISH);
+    assert(ret == Z_STREAM_END);        /* stream will be complete */
+
+The process is complete, but we still need to deallocate the state to avoid a memory leak +(or rather more like a memory hemorrhage if you didn't do this). Then +finally we can return with a happy return value. +

+    /* clean up and return */
+    (void)deflateEnd(&strm);
+    return Z_OK;
+}
+
+Now we do the same thing for decompression in the inf() routine. inf() +decompresses what is hopefully a valid zlib stream from the input file and writes the +uncompressed data to the output file. Much of the discussion above for def() +applies to inf() as well, so the discussion here will focus on the differences between +the two. +

+/* Decompress from file source to file dest until stream ends or EOF.
+   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_DATA_ERROR if the deflate data is
+   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
+   the version of the library linked do not match, or Z_ERRNO if there
+   is an error reading or writing the files. */
+int inf(FILE *source, FILE *dest)
+{
+
+The local variables have the same functionality as they do for def(). The +only difference is that there is no flush variable, since inflate() +can tell from the zlib stream itself when the stream is complete. +

+    int ret;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+
+The initialization of the state is the same, except that there is no compression level, +of course, and two more elements of the structure are initialized. avail_in +and next_in must be initialized before calling inflateInit(). This +is because the application has the option to provide the start of the zlib stream in +order for inflateInit() to have access to information about the compression +method to aid in memory allocation. In the current implementation of zlib +(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of +inflate() anyway. However those fields must be initialized since later versions +of zlib that provide more compression methods may take advantage of this interface. +In any case, no decompression is performed by inflateInit(), so the +avail_out and next_out fields do not need to be initialized before calling. +

+Here avail_in is set to zero and next_in is set to Z_NULL to +indicate that no input data is being provided. +


+    /* allocate inflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&strm);
+    if (ret != Z_OK)
+        return ret;
+
+The outer do-loop decompresses input until inflate() indicates +that it has reached the end of the compressed data and has produced all of the uncompressed +output. This is in contrast to def() which processes all of the input file. +If end-of-file is reached before the compressed data self-terminates, then the compressed +data is incomplete and an error is returned. +

+    /* decompress until deflate stream ends or end of file */
+    do {
+
+We read input data and set the strm structure accordingly. If we've reached the +end of the input file, then we leave the outer loop and report an error, since the +compressed data is incomplete. Note that we may read more data than is eventually consumed +by inflate(), if the input file continues past the zlib stream. +For applications where zlib streams are embedded in other data, this routine would +need to be modified to return the unused data, or at least indicate how much of the input +data was not used, so the application would know where to pick up after the zlib stream. +

+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)inflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        if (strm.avail_in == 0)
+            break;
+        strm.next_in = in;
+
+The inner do-loop has the same function it did in def(), which is to +keep calling inflate() until has generated all of the output it can with the +provided input. +

+        /* run inflate() on input until output buffer not full */
+        do {
+
+Just like in def(), the same output space is provided for each call of inflate(). +

+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+
+Now we run the decompression engine itself. There is no need to adjust the flush parameter, since +the zlib format is self-terminating. The main difference here is that there are +return values that we need to pay attention to. Z_DATA_ERROR +indicates that inflate() detected an error in the zlib compressed data format, +which means that either the data is not a zlib stream to begin with, or that the data was +corrupted somewhere along the way since it was compressed. The other error to be processed is +Z_MEM_ERROR, which can occur since memory allocation is deferred until inflate() +needs it, unlike deflate(), whose memory is allocated at the start by deflateInit(). +

+Advanced applications may use +deflateSetDictionary() to prime deflate() with a set of likely data to improve the +first 32K or so of compression. This is noted in the zlib header, so inflate() +requests that that dictionary be provided before it can start to decompress. Without the dictionary, +correct decompression is not possible. For this routine, we have no idea what the dictionary is, +so the Z_NEED_DICT indication is converted to a Z_DATA_ERROR. +

+inflate() can also return Z_STREAM_ERROR, which should not be possible here, +but could be checked for as noted above for def(). Z_BUF_ERROR does not need to be +checked for here, for the same reasons noted for def(). Z_STREAM_END will be +checked for later. +


+            ret = inflate(&strm, Z_NO_FLUSH);
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+            switch (ret) {
+            case Z_NEED_DICT:
+                ret = Z_DATA_ERROR;     /* and fall through */
+            case Z_DATA_ERROR:
+            case Z_MEM_ERROR:
+                (void)inflateEnd(&strm);
+                return ret;
+            }
+
+The output of inflate() is handled identically to that of deflate(). +

+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)inflateEnd(&strm);
+                return Z_ERRNO;
+            }
+
+The inner do-loop ends when inflate() has no more output as indicated +by not filling the output buffer, just as for deflate(). In this case, we cannot +assert that strm.avail_in will be zero, since the deflate stream may end before the file +does. +

+        } while (strm.avail_out == 0);
+
+The outer do-loop ends when inflate() reports that it has reached the +end of the input zlib stream, has completed the decompression and integrity +check, and has provided all of the output. This is indicated by the inflate() +return value Z_STREAM_END. The inner loop is guaranteed to leave ret +equal to Z_STREAM_END if the last chunk of the input file read contained the end +of the zlib stream. So if the return value is not Z_STREAM_END, the +loop continues to read more input. +

+        /* done when inflate() says it's done */
+    } while (ret != Z_STREAM_END);
+
+At this point, decompression successfully completed, or we broke out of the loop due to no +more data being available from the input file. If the last inflate() return value +is not Z_STREAM_END, then the zlib stream was incomplete and a data error +is returned. Otherwise, we return with a happy return value. Of course, inflateEnd() +is called first to avoid a memory leak. +

+    /* clean up and return */
+    (void)inflateEnd(&strm);
+    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+
+That ends the routines that directly use zlib. The following routines make this +a command-line program by running data through the above routines from stdin to +stdout, and handling any errors reported by def() or inf(). +

+zerr() is used to interpret the possible error codes from def() +and inf(), as detailed in their comments above, and print out an error message. +Note that these are only a subset of the possible return values from deflate() +and inflate(). +


+/* report a zlib or i/o error */
+void zerr(int ret)
+{
+    fputs("zpipe: ", stderr);
+    switch (ret) {
+    case Z_ERRNO:
+        if (ferror(stdin))
+            fputs("error reading stdin\n", stderr);
+        if (ferror(stdout))
+            fputs("error writing stdout\n", stderr);
+        break;
+    case Z_STREAM_ERROR:
+        fputs("invalid compression level\n", stderr);
+        break;
+    case Z_DATA_ERROR:
+        fputs("invalid or incomplete deflate data\n", stderr);
+        break;
+    case Z_MEM_ERROR:
+        fputs("out of memory\n", stderr);
+        break;
+    case Z_VERSION_ERROR:
+        fputs("zlib version mismatch!\n", stderr);
+    }
+}
+
+Here is the main() routine used to test def() and inf(). The +zpipe command is simply a compression pipe from stdin to stdout, if +no arguments are given, or it is a decompression pipe if zpipe -d is used. If any other +arguments are provided, no compression or decompression is performed. Instead a usage +message is displayed. Examples are zpipe < foo.txt > foo.txt.z to compress, and +zpipe -d < foo.txt.z > foo.txt to decompress. +

+/* compress or decompress from stdin to stdout */
+int main(int argc, char **argv)
+{
+    int ret;
+
+    /* avoid end-of-line conversions */
+    SET_BINARY_MODE(stdin);
+    SET_BINARY_MODE(stdout);
+
+    /* do compression if no arguments */
+    if (argc == 1) {
+        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* do decompression if -d specified */
+    else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
+        ret = inf(stdin, stdout);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* otherwise, report usage */
+    else {
+        fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
+        return 1;
+    }
+}
+
+
+Copyright (c) 2004, 2005 by Mark Adler
Last modified 11 December 2005
+ + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/zpipe.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/zpipe.c new file mode 100644 index 00000000..83535d16 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/zpipe.c @@ -0,0 +1,205 @@ +/* zpipe.c: example of proper use of zlib's inflate() and deflate() + Not copyrighted -- provided to the public domain + Version 1.4 11 December 2005 Mark Adler */ + +/* Version history: + 1.0 30 Oct 2004 First version + 1.1 8 Nov 2004 Add void casting for unused return values + Use switch statement for inflate() return values + 1.2 9 Nov 2004 Add assertions to document zlib guarantees + 1.3 6 Apr 2005 Remove incorrect assertion in inf() + 1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions + Avoid some compiler warnings for input and output buffers + */ + +#include +#include +#include +#include "zlib.h" + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#define CHUNK 16384 + +/* Compress from file source to file dest until EOF on source. + def() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_STREAM_ERROR if an invalid compression + level is supplied, Z_VERSION_ERROR if the version of zlib.h and the + version of the library linked do not match, or Z_ERRNO if there is + an error reading or writing the files. */ +int def(FILE *source, FILE *dest, int level) +{ + int ret, flush; + unsigned have; + z_stream strm; + unsigned char in[CHUNK]; + unsigned char out[CHUNK]; + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, level); + if (ret != Z_OK) + return ret; + + /* compress until end of file */ + do { + strm.avail_in = fread(in, 1, CHUNK, source); + if (ferror(source)) { + (void)deflateEnd(&strm); + return Z_ERRNO; + } + flush = feof(source) ? Z_FINISH : Z_NO_FLUSH; + strm.next_in = in; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = deflate(&strm, flush); /* no bad return value */ + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + have = CHUNK - strm.avail_out; + if (fwrite(out, 1, have, dest) != have || ferror(dest)) { + (void)deflateEnd(&strm); + return Z_ERRNO; + } + } while (strm.avail_out == 0); + assert(strm.avail_in == 0); /* all input will be used */ + + /* done when last data in file processed */ + } while (flush != Z_FINISH); + assert(ret == Z_STREAM_END); /* stream will be complete */ + + /* clean up and return */ + (void)deflateEnd(&strm); + return Z_OK; +} + +/* Decompress from file source to file dest until stream ends or EOF. + inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_DATA_ERROR if the deflate data is + invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and + the version of the library linked do not match, or Z_ERRNO if there + is an error reading or writing the files. */ +int inf(FILE *source, FILE *dest) +{ + int ret; + unsigned have; + z_stream strm; + unsigned char in[CHUNK]; + unsigned char out[CHUNK]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if (ret != Z_OK) + return ret; + + /* decompress until deflate stream ends or end of file */ + do { + strm.avail_in = fread(in, 1, CHUNK, source); + if (ferror(source)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + if (strm.avail_in == 0) + break; + strm.next_in = in; + + /* run inflate() on input until output buffer not full */ + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return ret; + } + have = CHUNK - strm.avail_out; + if (fwrite(out, 1, have, dest) != have || ferror(dest)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + } while (strm.avail_out == 0); + + /* done when inflate() says it's done */ + } while (ret != Z_STREAM_END); + + /* clean up and return */ + (void)inflateEnd(&strm); + return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; +} + +/* report a zlib or i/o error */ +void zerr(int ret) +{ + fputs("zpipe: ", stderr); + switch (ret) { + case Z_ERRNO: + if (ferror(stdin)) + fputs("error reading stdin\n", stderr); + if (ferror(stdout)) + fputs("error writing stdout\n", stderr); + break; + case Z_STREAM_ERROR: + fputs("invalid compression level\n", stderr); + break; + case Z_DATA_ERROR: + fputs("invalid or incomplete deflate data\n", stderr); + break; + case Z_MEM_ERROR: + fputs("out of memory\n", stderr); + break; + case Z_VERSION_ERROR: + fputs("zlib version mismatch!\n", stderr); + } +} + +/* compress or decompress from stdin to stdout */ +int main(int argc, char **argv) +{ + int ret; + + /* avoid end-of-line conversions */ + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + + /* do compression if no arguments */ + if (argc == 1) { + ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION); + if (ret != Z_OK) + zerr(ret); + return ret; + } + + /* do decompression if -d specified */ + else if (argc == 2 && strcmp(argv[1], "-d") == 0) { + ret = inf(stdin, stdout); + if (ret != Z_OK) + zerr(ret); + return ret; + } + + /* otherwise, report usage */ + else { + fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr); + return 1; + } +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/zran.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/zran.c new file mode 100644 index 00000000..617a1308 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/examples/zran.c @@ -0,0 +1,404 @@ +/* zran.c -- example of zlib/gzip stream indexing and random access + * Copyright (C) 2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + Version 1.0 29 May 2005 Mark Adler */ + +/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary() + for random access of a compressed file. A file containing a zlib or gzip + stream is provided on the command line. The compressed stream is decoded in + its entirety, and an index built with access points about every SPAN bytes + in the uncompressed output. The compressed file is left open, and can then + be read randomly, having to decompress on the average SPAN/2 uncompressed + bytes before getting to the desired block of data. + + An access point can be created at the start of any deflate block, by saving + the starting file offset and bit of that block, and the 32K bytes of + uncompressed data that precede that block. Also the uncompressed offset of + that block is saved to provide a referece for locating a desired starting + point in the uncompressed stream. build_index() works by decompressing the + input zlib or gzip stream a block at a time, and at the end of each block + deciding if enough uncompressed data has gone by to justify the creation of + a new access point. If so, that point is saved in a data structure that + grows as needed to accommodate the points. + + To use the index, an offset in the uncompressed data is provided, for which + the latest accees point at or preceding that offset is located in the index. + The input file is positioned to the specified location in the index, and if + necessary the first few bits of the compressed data is read from the file. + inflate is initialized with those bits and the 32K of uncompressed data, and + the decompression then proceeds until the desired offset in the file is + reached. Then the decompression continues to read the desired uncompressed + data from the file. + + Another approach would be to generate the index on demand. In that case, + requests for random access reads from the compressed data would try to use + the index, but if a read far enough past the end of the index is required, + then further index entries would be generated and added. + + There is some fair bit of overhead to starting inflation for the random + access, mainly copying the 32K byte dictionary. So if small pieces of the + file are being accessed, it would make sense to implement a cache to hold + some lookahead and avoid many calls to extract() for small lengths. + + Another way to build an index would be to use inflateCopy(). That would + not be constrained to have access points at block boundaries, but requires + more memory per access point, and also cannot be saved to file due to the + use of pointers in the state. The approach here allows for storage of the + index in a file. + */ + +#include +#include +#include +#include "zlib.h" + +#define local static + +#define SPAN 1048576L /* desired distance between access points */ +#define WINSIZE 32768U /* sliding window size */ +#define CHUNK 16384 /* file input buffer size */ + +/* access point entry */ +struct point { + off_t out; /* corresponding offset in uncompressed data */ + off_t in; /* offset in input file of first full byte */ + int bits; /* number of bits (1-7) from byte at in - 1, or 0 */ + unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */ +}; + +/* access point list */ +struct access { + int have; /* number of list entries filled in */ + int size; /* number of list entries allocated */ + struct point *list; /* allocated list */ +}; + +/* Deallocate an index built by build_index() */ +local void free_index(struct access *index) +{ + if (index != NULL) { + free(index->list); + free(index); + } +} + +/* Add an entry to the access point list. If out of memory, deallocate the + existing list and return NULL. */ +local struct access *addpoint(struct access *index, int bits, + off_t in, off_t out, unsigned left, unsigned char *window) +{ + struct point *next; + + /* if list is empty, create it (start with eight points) */ + if (index == NULL) { + index = malloc(sizeof(struct access)); + if (index == NULL) return NULL; + index->list = malloc(sizeof(struct point) << 3); + if (index->list == NULL) { + free(index); + return NULL; + } + index->size = 8; + index->have = 0; + } + + /* if list is full, make it bigger */ + else if (index->have == index->size) { + index->size <<= 1; + next = realloc(index->list, sizeof(struct point) * index->size); + if (next == NULL) { + free_index(index); + return NULL; + } + index->list = next; + } + + /* fill in entry and increment how many we have */ + next = index->list + index->have; + next->bits = bits; + next->in = in; + next->out = out; + if (left) + memcpy(next->window, window + WINSIZE - left, left); + if (left < WINSIZE) + memcpy(next->window + left, window, WINSIZE - left); + index->have++; + + /* return list, possibly reallocated */ + return index; +} + +/* Make one entire pass through the compressed stream and build an index, with + access points about every span bytes of uncompressed output -- span is + chosen to balance the speed of random access against the memory requirements + of the list, about 32K bytes per access point. Note that data after the end + of the first zlib or gzip stream in the file is ignored. build_index() + returns the number of access points on success (>= 1), Z_MEM_ERROR for out + of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a + file read error. On success, *built points to the resulting index. */ +local int build_index(FILE *in, off_t span, struct access **built) +{ + int ret; + off_t totin, totout; /* our own total counters to avoid 4GB limit */ + off_t last; /* totout value of last access point */ + struct access *index; /* access points being generated */ + z_stream strm; + unsigned char input[CHUNK]; + unsigned char window[WINSIZE]; + + /* initialize inflate */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, 47); /* automatic zlib or gzip decoding */ + if (ret != Z_OK) + return ret; + + /* inflate the input, maintain a sliding window, and build an index -- this + also validates the integrity of the compressed data using the check + information at the end of the gzip or zlib stream */ + totin = totout = last = 0; + index = NULL; /* will be allocated by first addpoint() */ + strm.avail_out = 0; + do { + /* get some compressed data from input file */ + strm.avail_in = fread(input, 1, CHUNK, in); + if (ferror(in)) { + ret = Z_ERRNO; + goto build_index_error; + } + if (strm.avail_in == 0) { + ret = Z_DATA_ERROR; + goto build_index_error; + } + strm.next_in = input; + + /* process all of that, or until end of stream */ + do { + /* reset sliding window if necessary */ + if (strm.avail_out == 0) { + strm.avail_out = WINSIZE; + strm.next_out = window; + } + + /* inflate until out of input, output, or at end of block -- + update the total input and output counters */ + totin += strm.avail_in; + totout += strm.avail_out; + ret = inflate(&strm, Z_BLOCK); /* return at end of block */ + totin -= strm.avail_in; + totout -= strm.avail_out; + if (ret == Z_NEED_DICT) + ret = Z_DATA_ERROR; + if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR) + goto build_index_error; + if (ret == Z_STREAM_END) + break; + + /* if at end of block, consider adding an index entry (note that if + data_type indicates an end-of-block, then all of the + uncompressed data from that block has been delivered, and none + of the compressed data after that block has been consumed, + except for up to seven bits) -- the totout == 0 provides an + entry point after the zlib or gzip header, and assures that the + index always has at least one access point; we avoid creating an + access point after the last block by checking bit 6 of data_type + */ + if ((strm.data_type & 128) && !(strm.data_type & 64) && + (totout == 0 || totout - last > span)) { + index = addpoint(index, strm.data_type & 7, totin, + totout, strm.avail_out, window); + if (index == NULL) { + ret = Z_MEM_ERROR; + goto build_index_error; + } + last = totout; + } + } while (strm.avail_in != 0); + } while (ret != Z_STREAM_END); + + /* clean up and return index (release unused entries in list) */ + (void)inflateEnd(&strm); + index = realloc(index, sizeof(struct point) * index->have); + index->size = index->have; + *built = index; + return index->size; + + /* return error */ + build_index_error: + (void)inflateEnd(&strm); + if (index != NULL) + free_index(index); + return ret; +} + +/* Use the index to read len bytes from offset into buf, return bytes read or + negative for error (Z_DATA_ERROR or Z_MEM_ERROR). If data is requested past + the end of the uncompressed data, then extract() will return a value less + than len, indicating how much as actually read into buf. This function + should not return a data error unless the file was modified since the index + was generated. extract() may also return Z_ERRNO if there is an error on + reading or seeking the input file. */ +local int extract(FILE *in, struct access *index, off_t offset, + unsigned char *buf, int len) +{ + int ret, skip; + z_stream strm; + struct point *here; + unsigned char input[CHUNK]; + unsigned char discard[WINSIZE]; + + /* proceed only if something reasonable to do */ + if (len < 0) + return 0; + + /* find where in stream to start */ + here = index->list; + ret = index->have; + while (--ret && here[1].out <= offset) + here++; + + /* initialize file and inflate state to start there */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, -15); /* raw inflate */ + if (ret != Z_OK) + return ret; + ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET); + if (ret == -1) + goto extract_ret; + if (here->bits) { + ret = getc(in); + if (ret == -1) { + ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR; + goto extract_ret; + } + (void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits)); + } + (void)inflateSetDictionary(&strm, here->window, WINSIZE); + + /* skip uncompressed bytes until offset reached, then satisfy request */ + offset -= here->out; + strm.avail_in = 0; + skip = 1; /* while skipping to offset */ + do { + /* define where to put uncompressed data, and how much */ + if (offset == 0 && skip) { /* at offset now */ + strm.avail_out = len; + strm.next_out = buf; + skip = 0; /* only do this once */ + } + if (offset > WINSIZE) { /* skip WINSIZE bytes */ + strm.avail_out = WINSIZE; + strm.next_out = discard; + offset -= WINSIZE; + } + else if (offset != 0) { /* last skip */ + strm.avail_out = (unsigned)offset; + strm.next_out = discard; + offset = 0; + } + + /* uncompress until avail_out filled, or end of stream */ + do { + if (strm.avail_in == 0) { + strm.avail_in = fread(input, 1, CHUNK, in); + if (ferror(in)) { + ret = Z_ERRNO; + goto extract_ret; + } + if (strm.avail_in == 0) { + ret = Z_DATA_ERROR; + goto extract_ret; + } + strm.next_in = input; + } + ret = inflate(&strm, Z_NO_FLUSH); /* normal inflate */ + if (ret == Z_NEED_DICT) + ret = Z_DATA_ERROR; + if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR) + goto extract_ret; + if (ret == Z_STREAM_END) + break; + } while (strm.avail_out != 0); + + /* if reach end of stream, then don't keep trying to get more */ + if (ret == Z_STREAM_END) + break; + + /* do until offset reached and requested data read, or stream ends */ + } while (skip); + + /* compute number of uncompressed bytes read after offset */ + ret = skip ? 0 : len - strm.avail_out; + + /* clean up and return bytes read or error */ + extract_ret: + (void)inflateEnd(&strm); + return ret; +} + +/* Demonstrate the use of build_index() and extract() by processing the file + provided on the command line, and the extracting 16K from about 2/3rds of + the way through the uncompressed output, and writing that to stdout. */ +int main(int argc, char **argv) +{ + int len; + off_t offset; + FILE *in; + struct access *index = NULL; + unsigned char buf[CHUNK]; + + /* open input file */ + if (argc != 2) { + fprintf(stderr, "usage: zran file.gz\n"); + return 1; + } + in = fopen(argv[1], "rb"); + if (in == NULL) { + fprintf(stderr, "zran: could not open %s for reading\n", argv[1]); + return 1; + } + + /* build index */ + len = build_index(in, SPAN, &index); + if (len < 0) { + fclose(in); + switch (len) { + case Z_MEM_ERROR: + fprintf(stderr, "zran: out of memory\n"); + break; + case Z_DATA_ERROR: + fprintf(stderr, "zran: compressed data error in %s\n", argv[1]); + break; + case Z_ERRNO: + fprintf(stderr, "zran: read error on %s\n", argv[1]); + break; + default: + fprintf(stderr, "zran: error %d while building index\n", len); + } + return 1; + } + fprintf(stderr, "zran: built index with %d access points\n", len); + + /* use index by reading some bytes from an arbitrary offset */ + offset = (index->list[index->have - 1].out << 1) / 3; + len = extract(in, index, offset, buf, CHUNK); + if (len < 0) + fprintf(stderr, "zran: extraction failed: %s error\n", + len == Z_MEM_ERROR ? "out of memory" : "input corrupted"); + else { + fwrite(buf, 1, len, stdout); + fprintf(stderr, "zran: extracted %d bytes at %llu\n", len, offset); + } + + /* clean up and exit */ + free_index(index); + fclose(in); + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzclose.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzclose.c new file mode 100644 index 00000000..caeb99a3 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzguts.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzguts.h new file mode 100644 index 00000000..3107c363 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzguts.h @@ -0,0 +1,190 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef __TURBOC__ +# include +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# include +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifdef STDC +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzlib.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzlib.c new file mode 100644 index 00000000..7aedab8e --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzlib.c @@ -0,0 +1,564 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010, 2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const char *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gz_statep state; + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + case 'T': + state->direct = 1; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ + state->path = malloc(strlen(path) + 1); + if (state->path == NULL) { + free(state); + return NULL; + } + strcpy(state->path, path); + + /* open the file with the appropriate mode (or just use fd) */ + state->fd = fd != -1 ? fd : + open(path, +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | ( + state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))), + 0666); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + sprintf(path, "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->msg == NULL ? "" : state->msg; +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, save as static string */ + if (err == Z_MEM_ERROR) { + state->msg = (char *)msg; + return; + } + + /* construct error message with path */ + if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + state->msg = (char *)"out of memory"; + return; + } + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzread.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzread.c new file mode 100644 index 00000000..46d40e0b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzread.c @@ -0,0 +1,584 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010, 2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_look OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_fetch OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) + memmove(state->in, strm->next_in, strm->avail_in); + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = malloc(state->want); + state->out = malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->x.have) { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + continue; /* no progress yet -- go back to memcpy() above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = buf; + if (gz_decomp(state) == -1) + return -1; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzgetc_(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +#undef gzgetc +int ZEXPORT gzgetc(file) +gzFile file; +{ + return gzgetc_(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzwrite.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzwrite.c new file mode 100644 index 00000000..caa35b61 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/gzwrite.c @@ -0,0 +1,593 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer */ + state->in = malloc(state->want); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. If gz->direct + is true, then simply write to the output file without compressing, and + ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + unsigned n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + if (strm->avail_in == 0) + strm->next_in = state->in; + n = state->size - strm->avail_in; + if (n > len) + n = len; + memcpy(strm->next_in + strm->avail_in, buf, n); + strm->avail_in += n; + state->x.pos += n; + buf = (char *)buf + n; + len -= n; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (voidp)buf; + state->x.pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (strm->avail_in < state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + strm->next_in[strm->avail_in++] = c; + state->x.pos++; + return c & 0xff; + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) +{ + int size, len; + gz_statep state; + z_streamp strm; + va_list va; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(state->in, format, va); + va_end(va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf(state->in, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(state->in, size, format, va); + va_end(va); + len = strlen(state->in); +# else + len = vsnprintf((char *)(state->in), size, format, va); + va_end(va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(state->in); +# else + len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} + +/* used by zlibVersion() to get the vsnprintf story from the horse's mouth */ +unsigned long ZEXPORT gzflags() +{ + unsigned long flags = 0; +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/infback.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/infback.c new file mode 100644 index 00000000..981aff17 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/infback.c @@ -0,0 +1,640 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inffast.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inffast.c new file mode 100644 index 00000000..2f1d60b4 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inffast.c @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inffast.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inffast.h new file mode 100644 index 00000000..e5c1aa4c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inffixed.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inffixed.h new file mode 100644 index 00000000..d6283277 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inflate.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inflate.c new file mode 100644 index 00000000..cc89517b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inflate.c @@ -0,0 +1,1501 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateResetKeep(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + unsigned char *next; + unsigned avail; + int ret; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + next = strm->next_out; + avail = strm->avail_out; + strm->next_out = (Bytef *)dictionary + dictLength; + strm->avail_out = 0; + ret = updatewindow(strm, dictLength); + strm->avail_out = avail; + strm->next_out = next; + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inflate.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inflate.h new file mode 100644 index 00000000..95f4986d --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inftrees.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inftrees.c new file mode 100644 index 00000000..60bbd58b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inftrees.c @@ -0,0 +1,306 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.6 Copyright 1995-2012 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 69}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inftrees.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inftrees.h new file mode 100644 index 00000000..baa53a0b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/make_vms.com b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/make_vms.com new file mode 100644 index 00000000..11be527f --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/make_vms.com @@ -0,0 +1,804 @@ +$! make libz under VMS written by +$! Martin P.J. Zinser +$! +$! In case of problems with the install you might contact me at +$! zinser@zinser.no-ip.info(preferred) or +$! zinser@sysdev.deutsche-boerse.com (work) +$! +$! Make procedure history for Zlib +$! +$!------------------------------------------------------------------------------ +$! Version history +$! 0.01 20060120 First version to receive a number +$! 0.02 20061008 Adapt to new Makefile.in +$! 0.03 20091224 Add support for large file check +$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite +$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in +$! +$ on error then goto err_exit +$ set proc/parse=ext +$! +$ true = 1 +$ false = 0 +$ tmpnam = "temp_" + f$getjpi("","pid") +$ tt = tmpnam + ".txt" +$ tc = tmpnam + ".c" +$ th = tmpnam + ".h" +$ define/nolog tconfig 'th' +$ its_decc = false +$ its_vaxc = false +$ its_gnuc = false +$ s_case = False +$! +$! Setup variables holding "config" information +$! +$ Make = "" +$ name = "Zlib" +$ version = "?.?.?" +$ v_string = "ZLIB_VERSION" +$ v_file = "zlib.h" +$ ccopt = "" +$ lopts = "" +$ dnsrl = "" +$ aconf_in_file = "zconf.h.in#zconf.h_in" +$ conf_check_string = "" +$ linkonly = false +$ optfile = name + ".opt" +$ libdefs = "" +$ axp = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096 +$! +$ whoami = f$parse(f$enviornment("Procedure"),,,,"NO_CONCEAL") +$ mydef = F$parse(whoami,,,"DEVICE") +$ mydir = f$parse(whoami,,,"DIRECTORY") - "][" +$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type") +$! +$! Check for MMK/MMS +$! +$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS" +$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK" +$! +$! +$ gosub find_version +$! +$ open/write topt tmp.opt +$ open/write optf 'optfile' +$! +$ gosub check_opts +$! +$! Look for the compiler used +$! +$ gosub check_compiler +$ close topt +$! +$ if its_decc +$ then +$ ccopt = "/prefix=all" + ccopt +$ if f$trnlnm("SYS") .eqs. "" +$ then +$ if axp +$ then +$ define sys sys$library: +$ else +$ ccopt = "/decc" + ccopt +$ define sys decc$library_include: +$ endif +$ endif +$ endif +$ if its_vaxc .or. its_gnuc +$ then +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ endif +$! +$! Build a fake configure input header +$! +$ open/write conf_hin config.hin +$ write conf_hin "#undef _LARGEFILE64_SOURCE" +$ close conf_hin +$! +$! +$ i = 0 +$FIND_ACONF: +$ fname = f$element(i,"#",aconf_in_file) +$ if fname .eqs. "#" then goto AMISS_ERR +$ if f$search(fname) .eqs. "" +$ then +$ i = i + 1 +$ goto find_aconf +$ endif +$ open/read/err=aconf_err aconf_in 'fname' +$ open/write aconf zconf.h +$ACONF_LOOP: +$ read/end_of_file=aconf_exit aconf_in line +$ work = f$edit(line, "compress,trim") +$ if f$extract(0,6,work) .nes. "#undef" +$ then +$ if f$extract(0,12,work) .nes. "#cmakedefine" +$ then +$ write aconf line +$ endif +$ else +$ cdef = f$element(1," ",work) +$ gosub check_config +$ endif +$ goto aconf_loop +$ACONF_EXIT: +$ write aconf "#define VMS 1" +$ write aconf "#include " +$ write aconf "#include " +$ write aconf "#ifdef _LARGEFILE" +$ write aconf "#define off64_t __off64_t" +$ write aconf "#define fopen64 fopen" +$ write aconf "#define fseeko64 fseeko" +$ write aconf "#define lseek64 lseek" +$ write aconf "#define ftello64 ftell" +$ write aconf "#endif" +$ close aconf_in +$ close aconf +$ if f$search("''th'") .nes. "" then delete 'th';* +$! Build the thing plain or with mms +$! +$ write sys$output "Compiling Zlib sources ..." +$ if make.eqs."" +$ then +$ dele example.obj;*,minigzip.obj;* +$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - + adler32.c zlib.h zconf.h +$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - + compress.c zlib.h zconf.h +$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - + crc32.c zlib.h zconf.h +$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - + deflate.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" - + gzclose.c zutil.h zlib.h zconf.h +$ CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" - + gzlib.c zutil.h zlib.h zconf.h +$ CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" - + gzread.c zutil.h zlib.h zconf.h +$ CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" - + gzwrite.c zutil.h zlib.h zconf.h +$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" - + infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h +$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - + inffast.c zutil.h zlib.h zconf.h inffast.h +$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - + inflate.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - + inftrees.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - + trees.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - + uncompr.c zlib.h zconf.h +$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - + zutil.c zutil.h zlib.h zconf.h +$ write sys$output "Building Zlib ..." +$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ +$ write sys$output "Building example..." +$ CALL MAKE example.OBJ "CC ''CCOPT' example" - + test/example.c zlib.h zconf.h +$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb +$ if f$search("x11vms:xvmsutils.olb") .nes. "" +$ then +$ write sys$output "Building minigzip..." +$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - + test/minigzip.c zlib.h zconf.h +$ call make minigzip.exe - + "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - + minigzip.obj libz.olb +$ endif +$ else +$ gosub crea_mms +$ write sys$output "Make ''name' ''version' with ''Make' " +$ 'make' +$ endif +$! +$! Alpha gets a shareable image +$! +$ If axp +$ Then +$ gosub crea_olist +$ write sys$output "Creating libzshr.exe" +$ call anal_obj_axp modules.opt _link.opt +$ if s_case +$ then +$ open/append optf modules.opt +$ write optf "case_sensitive=YES" +$ close optf +$ endif +$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,_link.opt/opt +$ endif +$ write sys$output "Zlib build completed" +$ exit +$CC_ERR: +$ write sys$output "C compiler required to build ''name'" +$ goto err_exit +$ERR_EXIT: +$ set message/facil/ident/sever/text +$ close/nolog optf +$ close/nolog topt +$ close/nolog conf_hin +$ close/nolog aconf_in +$ close/nolog aconf +$ close/nolog out +$ close/nolog min +$ close/nolog mod +$ close/nolog h_in +$ write sys$output "Exiting..." +$ exit 2 +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE +$!------------------------------------------------------------------------------ +$! +$! Check command line options and set symbols accordingly +$! +$!------------------------------------------------------------------------------ +$! Version history +$! 0.01 20041206 First version to receive a number +$! 0.02 20060126 Add new "HELP" target +$ CHECK_OPTS: +$ i = 1 +$ OPT_LOOP: +$ if i .lt. 9 +$ then +$ cparm = f$edit(p'i',"upcase") +$! +$! Check if parameter actually contains something +$! +$ if f$edit(cparm,"trim") .nes. "" +$ then +$ if cparm .eqs. "DEBUG" +$ then +$ ccopt = ccopt + "/noopt/deb" +$ lopts = lopts + "/deb" +$ endif +$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ ccopt = ccopt + f$extract(start,len,cparm) +$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) - + then s_case = true +$ endif +$ if cparm .eqs. "LINK" then linkonly = true +$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ lopts = lopts + f$extract(start,len,cparm) +$ endif +$ if f$locate("CC=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ cc_com = f$extract(start,len,cparm) + if (cc_com .nes. "DECC") .and. - + (cc_com .nes. "VAXC") .and. - + (cc_com .nes. "GNUC") +$ then +$ write sys$output "Unsupported compiler choice ''cc_com' ignored" +$ write sys$output "Use DECC, VAXC, or GNUC instead" +$ else +$ if cc_com .eqs. "DECC" then its_decc = true +$ if cc_com .eqs. "VAXC" then its_vaxc = true +$ if cc_com .eqs. "GNUC" then its_gnuc = true +$ endif +$ endif +$ if f$locate("MAKE=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ mmks = f$extract(start,len,cparm) +$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS") +$ then +$ make = mmks +$ else +$ write sys$output "Unsupported make choice ''mmks' ignored" +$ write sys$output "Use MMK or MMS instead" +$ endif +$ endif +$ if cparm .eqs. "HELP" then gosub bhelp +$ endif +$ i = i + 1 +$ goto opt_loop +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Look for the compiler used +$! +$! Version history +$! 0.01 20040223 First version to receive a number +$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists +$! 0.03 20060202 Extend handling of GNU C +$! 0.04 20090402 Compaq -> hp +$CHECK_COMPILER: +$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) +$ then +$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "") +$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "") +$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "") +$ endif +$! +$! Exit if no compiler available +$! +$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) +$ then goto CC_ERR +$ else +$ if its_decc +$ then +$ write sys$output "CC compiler check ... hp C" +$ if f$trnlnm("decc$no_rooted_search_lists") .nes. "" +$ then +$ dnrsl = f$trnlnm("decc$no_rooted_search_lists") +$ endif +$ define/nolog decc$no_rooted_search_lists 1 +$ else +$ if its_vaxc then write sys$output "CC compiler check ... VAX C" +$ if its_gnuc +$ then +$ write sys$output "CC compiler check ... GNU C" +$ if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib" +$ if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib" +$ cc = "gcc" +$ endif +$ if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share" +$ if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share" +$ endif +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! If MMS/MMK are available dump out the descrip.mms if required +$! +$CREA_MMS: +$ write sys$output "Creating descrip.mms..." +$ create descrip.mms +$ open/append out descrip.mms +$ copy sys$input: out +$ deck +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser +# + +OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\ + gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, \ + inftrees.obj, inffast.obj + +$ eod +$ write out "CFLAGS=", ccopt +$ write out "LOPTS=", lopts +$ copy sys$input: out +$ deck + +all : example.exe minigzip.exe libz.olb + @ write sys$output " Example applications available" + +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link $(LOPTS) example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link $(LOPTS) minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib + +clean : + delete *.obj;*,libz.olb;*,*.opt;*,*.exe;* + + +# Other dependencies. +adler32.obj : adler32.c zutil.h zlib.h zconf.h +compress.obj : compress.c zlib.h zconf.h +crc32.obj : crc32.c zutil.h zlib.h zconf.h +deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h +example.obj : test/example.c zlib.h zconf.h +gzclose.obj : gzclose.c zutil.h zlib.h zconf.h +gzlib.obj : gzlib.c zutil.h zlib.h zconf.h +gzread.obj : gzread.c zutil.h zlib.h zconf.h +gzwrite.obj : gzwrite.c zutil.h zlib.h zconf.h +inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h +inflate.obj : inflate.c zutil.h zlib.h zconf.h +inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h +minigzip.obj : test/minigzip.c zlib.h zconf.h +trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h +uncompr.obj : uncompr.c zlib.h zconf.h +zutil.obj : zutil.c zutil.h zlib.h zconf.h +infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h +$ eod +$ close out +$ return +$!------------------------------------------------------------------------------ +$! +$! Read list of core library sources from makefile.in and create options +$! needed to build shareable image +$! +$CREA_OLIST: +$ open/read min makefile.in +$ open/write mod modules.opt +$ src_check = "OBJC =" +$MRLOOP: +$ read/end=mrdone min rec +$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop +$ rec = rec - src_check +$ gosub extra_filnam +$ if (f$element(1,"\",rec) .eqs. "\") then goto mrdone +$MRSLOOP: +$ read/end=mrdone min rec +$ gosub extra_filnam +$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop +$MRDONE: +$ close min +$ close mod +$ return +$!------------------------------------------------------------------------------ +$! +$! Take record extracted in crea_olist and split it into single filenames +$! +$EXTRA_FILNAM: +$ myrec = f$edit(rec - "\", "trim,compress") +$ i = 0 +$FELOOP: +$ srcfil = f$element(i," ", myrec) +$ if (srcfil .nes. " ") +$ then +$ write mod f$parse(srcfil,,,"NAME"), ".obj" +$ i = i + 1 +$ goto feloop +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Find current Zlib version number +$! +$FIND_VERSION: +$ open/read h_in 'v_file' +$hloop: +$ read/end=hdone h_in rec +$ rec = f$edit(rec,"TRIM") +$ if (f$extract(0,1,rec) .nes. "#") then goto hloop +$ rec = f$edit(rec - "#", "TRIM") +$ if f$element(0," ",rec) .nes. "define" then goto hloop +$ if f$element(1," ",rec) .eqs. v_string +$ then +$ version = 'f$element(2," ",rec)' +$ goto hdone +$ endif +$ goto hloop +$hdone: +$ close h_in +$ return +$!------------------------------------------------------------------------------ +$! +$CHECK_CONFIG: +$! +$ in_ldef = f$locate(cdef,libdefs) +$ if (in_ldef .lt. f$length(libdefs)) +$ then +$ write aconf "#define ''cdef' 1" +$ libdefs = f$extract(0,in_ldef,libdefs) + - + f$extract(in_ldef + f$length(cdef) + 1, - + f$length(libdefs) - in_ldef - f$length(cdef) - 1, - + libdefs) +$ else +$ if (f$type('cdef') .eqs. "INTEGER") +$ then +$ write aconf "#define ''cdef' ", 'cdef' +$ else +$ if (f$type('cdef') .eqs. "STRING") +$ then +$ write aconf "#define ''cdef' ", """", '''cdef'', """" +$ else +$ gosub check_cc_def +$ endif +$ endif +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Check if this is a define relating to the properties of the C/C++ +$! compiler +$! +$ CHECK_CC_DEF: +$ if (cdef .eqs. "_LARGEFILE64_SOURCE") +$ then +$ copy sys$input: 'tc' +$ deck +#include "tconfig" +#define _LARGEFILE +#include + +int main(){ +FILE *fp; + fp = fopen("temp.txt","r"); + fseeko(fp,1,SEEK_SET); + fclose(fp); +} + +$ eod +$ test_inv = false +$ comm_h = false +$ gosub cc_prop_check +$ return +$ endif +$ write aconf "/* ", line, " */" +$ return +$!------------------------------------------------------------------------------ +$! +$! Check for properties of C/C++ compiler +$! +$! Version history +$! 0.01 20031020 First version to receive a number +$! 0.02 20031022 Added logic for defines with value +$! 0.03 20040309 Make sure local config file gets not deleted +$! 0.04 20041230 Also write include for configure run +$! 0.05 20050103 Add processing of "comment defines" +$CC_PROP_CHECK: +$ cc_prop = true +$ is_need = false +$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true) +$ if f$search(th) .eqs. "" then create 'th' +$ set message/nofac/noident/nosever/notext +$ on error then continue +$ cc 'tmpnam' +$ if .not. ($status) then cc_prop = false +$ on error then continue +$! The headers might lie about the capabilities of the RTL +$ link 'tmpnam',tmp.opt/opt +$ if .not. ($status) then cc_prop = false +$ set message/fac/ident/sever/text +$ on error then goto err_exit +$ delete/nolog 'tmpnam'.*;*/exclude='th' +$ if (cc_prop .and. .not. is_need) .or. - + (.not. cc_prop .and. is_need) +$ then +$ write sys$output "Checking for ''cdef'... yes" +$ if f$type('cdef_val'_yes) .nes. "" +$ then +$ if f$type('cdef_val'_yes) .eqs. "INTEGER" - + then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes) +$ if f$type('cdef_val'_yes) .eqs. "STRING" - + then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes) +$ else +$ call write_config f$fao("#define !AS 1",cdef) +$ endif +$ if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. - + (cdef .eqs. "_LARGEFILE64_SOURCE") then - + call write_config f$string("#define _LARGEFILE 1") +$ else +$ write sys$output "Checking for ''cdef'... no" +$ if (comm_h) +$ then + call write_config f$fao("/* !AS */",line) +$ else +$ if f$type('cdef_val'_no) .nes. "" +$ then +$ if f$type('cdef_val'_no) .eqs. "INTEGER" - + then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no) +$ if f$type('cdef_val'_no) .eqs. "STRING" - + then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no) +$ else +$ call write_config f$fao("#undef !AS",cdef) +$ endif +$ endif +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Check for properties of C/C++ compiler with multiple result values +$! +$! Version history +$! 0.01 20040127 First version +$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05 +$CC_MPROP_CHECK: +$ cc_prop = true +$ i = 1 +$ idel = 1 +$ MT_LOOP: +$ if f$type(result_'i') .eqs. "STRING" +$ then +$ set message/nofac/noident/nosever/notext +$ on error then continue +$ cc 'tmpnam'_'i' +$ if .not. ($status) then cc_prop = false +$ on error then continue +$! The headers might lie about the capabilities of the RTL +$ link 'tmpnam'_'i',tmp.opt/opt +$ if .not. ($status) then cc_prop = false +$ set message/fac/ident/sever/text +$ on error then goto err_exit +$ delete/nolog 'tmpnam'_'i'.*;* +$ if (cc_prop) +$ then +$ write sys$output "Checking for ''cdef'... ", mdef_'i' +$ if f$type(mdef_'i') .eqs. "INTEGER" - + then call write_config f$fao("#define !AS !UL",cdef,mdef_'i') +$ if f$type('cdef_val'_yes) .eqs. "STRING" - + then call write_config f$fao("#define !AS !AS",cdef,mdef_'i') +$ goto msym_clean +$ else +$ i = i + 1 +$ goto mt_loop +$ endif +$ endif +$ write sys$output "Checking for ''cdef'... no" +$ call write_config f$fao("#undef !AS",cdef) +$ MSYM_CLEAN: +$ if (idel .le. msym_max) +$ then +$ delete/sym mdef_'idel' +$ idel = idel + 1 +$ goto msym_clean +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Analyze Object files for OpenVMS AXP to extract Procedure and Data +$! information to build a symbol vector for a shareable image +$! All the "brains" of this logic was suggested by Hartmut Becker +$! (Hartmut.Becker@compaq.com). All the bugs were introduced by me +$! (zinser@zinser.no-ip.info), so if you do have problem reports please do not +$! bother Hartmut/HP, but get in touch with me +$! +$! Version history +$! 0.01 20040406 Skip over shareable images in option file +$! 0.02 20041109 Fix option file for shareable images with case_sensitive=YES +$! 0.03 20050107 Skip over Identification labels in option file +$! 0.04 20060117 Add uppercase alias to code compiled with /name=as_is +$! +$ ANAL_OBJ_AXP: Subroutine +$ V = 'F$Verify(0) +$ SAY := "WRITE_ SYS$OUTPUT" +$ +$ IF F$SEARCH("''P1'") .EQS. "" +$ THEN +$ SAY "ANAL_OBJ_AXP-E-NOSUCHFILE: Error, inputfile ''p1' not available" +$ goto exit_aa +$ ENDIF +$ IF "''P2'" .EQS. "" +$ THEN +$ SAY "ANAL_OBJ_AXP: Error, no output file provided" +$ goto exit_aa +$ ENDIF +$ +$ open/read in 'p1 +$ create a.tmp +$ open/append atmp a.tmp +$ loop: +$ read/end=end_loop in line +$ if f$locate("/SHARE",f$edit(line,"upcase")) .lt. f$length(line) +$ then +$ write sys$output "ANAL_SKP_SHR-i-skipshare, ''line'" +$ goto loop +$ endif +$ if f$locate("IDENTIFICATION=",f$edit(line,"upcase")) .lt. f$length(line) +$ then +$ write sys$output "ANAL_OBJ_AXP-i-ident: Identification ", - + f$element(1,"=",line) +$ goto loop +$ endif +$ f= f$search(line) +$ if f .eqs. "" +$ then +$ write sys$output "ANAL_OBJ_AXP-w-nosuchfile, ''line'" +$ goto loop +$ endif +$ define/user sys$output nl: +$ define/user sys$error nl: +$ anal/obj/gsd 'f /out=x.tmp +$ open/read xtmp x.tmp +$ XLOOP: +$ read/end=end_xloop xtmp xline +$ xline = f$edit(xline,"compress") +$ write atmp xline +$ goto xloop +$ END_XLOOP: +$ close xtmp +$ goto loop +$ end_loop: +$ close in +$ close atmp +$ if f$search("a.tmp") .eqs. "" - + then $ exit +$ ! all global definitions +$ search a.tmp "symbol:","EGSY$V_DEF 1","EGSY$V_NORM 1"/out=b.tmp +$ ! all procedures +$ search b.tmp "EGSY$V_NORM 1"/wind=(0,1) /out=c.tmp +$ search c.tmp "symbol:"/out=d.tmp +$ define/user sys$output nl: +$ edito/edt/command=sys$input d.tmp +sub/symbol: "/symbol_vector=(/whole +sub/"/=PROCEDURE)/whole +exit +$ ! all data +$ search b.tmp "EGSY$V_DEF 1"/wind=(0,1) /out=e.tmp +$ search e.tmp "symbol:"/out=f.tmp +$ define/user sys$output nl: +$ edito/edt/command=sys$input f.tmp +sub/symbol: "/symbol_vector=(/whole +sub/"/=DATA)/whole +exit +$ sort/nodupl d.tmp,f.tmp g.tmp +$ open/read raw_vector g.tmp +$ open/write case_vector 'p2' +$ RAWLOOP: +$ read/end=end_rawloop raw_vector raw_element +$ write case_vector raw_element +$ if f$locate("=PROCEDURE)",raw_element) .lt. f$length(raw_element) +$ then +$ name = f$element(1,"=",raw_element) - "(" +$ if f$edit(name,"UPCASE") .nes. name then - + write case_vector f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)", - + f$edit(name,"UPCASE"), name) +$ endif +$ if f$locate("=DATA)",raw_element) .lt. f$length(raw_element) +$ then +$ name = f$element(1,"=",raw_element) - "(" +$ if f$edit(name,"UPCASE") .nes. name then - + write case_vector f$fao(" symbol_vector=(!AS/!AS=DATA)", - + f$edit(name,"UPCASE"), name) +$ endif +$ goto rawloop +$ END_RAWLOOP: +$ close raw_vector +$ close case_vector +$ delete a.tmp;*,b.tmp;*,c.tmp;*,d.tmp;*,e.tmp;*,f.tmp;*,g.tmp;* +$ if f$search("x.tmp") .nes. "" - + then $ delete x.tmp;* +$! +$ EXIT_AA: +$ if V then set verify +$ endsubroutine +$!------------------------------------------------------------------------------ +$! +$! Write configuration to both permanent and temporary config file +$! +$! Version history +$! 0.01 20031029 First version to receive a number +$! +$WRITE_CONFIG: SUBROUTINE +$ write aconf 'p1' +$ open/append confh 'th' +$ write confh 'p1' +$ close confh +$ENDSUBROUTINE +$!------------------------------------------------------------------------------ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.bor b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.bor new file mode 100644 index 00000000..3d12a2c2 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.bor @@ -0,0 +1,115 @@ +# Makefile for zlib +# Borland C++ +# Last updated: 15-Mar-2003 + +# To use, do "make -fmakefile.bor" +# To compile in small model, set below: MODEL=s + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------ Turbo C++, Borland C++ ------------ + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# memory model: one of s, m, c, l (small, medium, compact, large) +MODEL=l + +# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version +CC=bcc +LD=bcc +AR=tlib + +# compiler flags +# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0 +CFLAGS=-O2 -Z -m$(MODEL) $(LOC) + +LDFLAGS=-m$(MODEL) -f- + + +# variables +ZLIB_LIB = zlib_$(MODEL).lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + -del *.obj + -del *.lib + -del *.exe + -del zlib_*.bak + -del foo.gz diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.dj2 b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.dj2 new file mode 100644 index 00000000..29b03954 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.dj2 @@ -0,0 +1,104 @@ +# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.dj2; make test -fmakefile.dj2 +# +# To install libz.a, zconf.h and zlib.h in the djgpp directories, type: +# +# make install -fmakefile.dj2 +# +# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as +# in the sample below if the pattern of the DJGPP distribution is to +# be followed. Remember that, while 'es around <=> are ignored in +# makefiles, they are *not* in batch files or in djgpp.env. +# - - - - - +# [make] +# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include +# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib +# BUTT=-m486 +# - - - - - +# Alternately, these variables may be defined below, overriding the values +# in djgpp.env, as +# INCLUDE_PATH=c:\usr\include +# LIBRARY_PATH=c:\usr\lib + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lz +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +OBJA = +# to use the asm code: make OBJA=match.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +check: test +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +libz.a: $(OBJS) $(OBJA) + $(AR) $@ $(OBJS) $(OBJA) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + +# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env . + +.PHONY : uninstall clean + +install: $(INCL) $(LIBS) + -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH) + -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH) + $(INSTALL) zlib.h $(INCLUDE_PATH) + $(INSTALL) zconf.h $(INCLUDE_PATH) + $(INSTALL) libz.a $(LIBRARY_PATH) + +uninstall: + $(RM) $(INCLUDE_PATH)\zlib.h + $(RM) $(INCLUDE_PATH)\zconf.h + $(RM) $(LIBRARY_PATH)\libz.a + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) libz.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.emx b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.emx new file mode 100644 index 00000000..9c1b57a5 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.emx @@ -0,0 +1,69 @@ +# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.msc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.msc new file mode 100644 index 00000000..ae837861 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.msc @@ -0,0 +1,112 @@ +# Makefile for zlib +# Microsoft C 5.1 or later +# Last updated: 19-Mar-2003 + +# To use, do "make makefile.msc" +# To compile in small model, set below: MODEL=S + +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Microsoft C 5.1 and later ------------- + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Memory model: one of S, M, C, L (small, medium, compact, large) +MODEL=L + +CC=cl +CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC) +#-Ox generates bad code with MSC 5.1 +LIB_CFLAGS=-Zl $(CFLAGS) + +LD=link +LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode +# "/farcall/packcode" are only useful for `large code' memory models +# but should be a "no-op" for small code models. + + +# variables +ZLIB_LIB = zlib_$(MODEL).lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(LIB_CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: test/minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + + +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + if exist $(ZLIB_LIB) del $(ZLIB_LIB) + lib $(ZLIB_LIB) $(OBJ1); + lib $(ZLIB_LIB) $(OBJ2); + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB); + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB); + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + -del *.obj + -del *.lib + -del *.exe + -del *.map + -del zlib_*.bak + -del foo.gz diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.tc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.tc new file mode 100644 index 00000000..5aec82a9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/msdos/Makefile.tc @@ -0,0 +1,100 @@ +# Makefile for zlib +# Turbo C 2.01, Turbo C++ 1.01 +# Last updated: 15-Mar-2003 + +# To use, do "make -fmakefile.tc" +# To compile in small model, set below: MODEL=s + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------ +MODEL=l +CC=tcc +LD=tcc +AR=tlib +# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +CFLAGS=-O2 -G -Z -m$(MODEL) +LDFLAGS=-m$(MODEL) -f- + + +# variables +ZLIB_LIB = zlib_$(MODEL).lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + -del *.obj + -del *.lib + -del *.exe + -del zlib_*.bak + -del foo.gz diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/nintendods/Makefile b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/nintendods/Makefile new file mode 100644 index 00000000..21337d01 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/nintendods/Makefile @@ -0,0 +1,126 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/ds_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +#--------------------------------------------------------------------------------- +TARGET := $(shell basename $(CURDIR)) +BUILD := build +SOURCES := ../../ +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -mthumb -mthumb-interwork + +CFLAGS := -Wall -O2\ + -march=armv5te -mtune=arm946e-s \ + -fomit-frame-pointer -ffast-math \ + $(ARCH) + +CFLAGS += $(INCLUDE) -DARM9 +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions + +ASFLAGS := $(ARCH) -march=armv5te -mtune=arm946e-s +LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(LIBNDS) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/lib/libz.a + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +.PHONY: $(BUILD) clean all + +#--------------------------------------------------------------------------------- +all: $(BUILD) + @[ -d $@ ] || mkdir -p include + @cp ../../*.h include + +lib: + @[ -d $@ ] || mkdir -p $@ + +$(BUILD): lib + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) lib + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT) : $(OFILES) + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/nintendods/README b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/nintendods/README new file mode 100644 index 00000000..ba7a37db --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/nintendods/README @@ -0,0 +1,5 @@ +This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template. + +Eduardo Costa +January 3, 2009 + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/Makefile.riscos b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/Makefile.riscos new file mode 100644 index 00000000..57e29d3f --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/Makefile.riscos @@ -0,0 +1,151 @@ +# Project: zlib_1_03 +# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430 +# test works out-of-the-box, installs `somewhere' on demand + +# Toolflags: +CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah +C++flags = -c -depend !Depend -IC: -throwback +Linkflags = -aif -c++ -o $@ +ObjAsmflags = -throwback -NoCache -depend !Depend +CMHGflags = +LibFileflags = -c -l -o $@ +Squeezeflags = -o $@ + +# change the line below to where _you_ want the library installed. +libdest = lib:zlib + +# Final targets: +@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ + @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ + @.o.uncompr @.o.zutil + LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ + @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ + @.o.trees @.o.uncompr @.o.zutil +test: @.minigzip @.example @.lib + @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV + @echo running tests: hang on. + @/@.minigzip -f -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -f -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -1 libc + @/@.minigzip -d libc-gz + @diff @.lib @.libc + @echo that should have reported '@.lib and @.libc identical' if you have diff. + @/@.example @.fred @.fred + @echo that will have given lots of hello!'s. + +@.minigzip: @.o.minigzip @.lib C:o.Stubs + Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs +@.example: @.o.example @.lib C:o.Stubs + Link $(Linkflags) @.o.example @.lib C:o.Stubs + +install: @.lib + cdir $(libdest) + cdir $(libdest).h + @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV + @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV + @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV + @echo okay, installed zlib in $(libdest) + +clean:; remove @.minigzip + remove @.example + remove @.libc + -wipe @.o.* F~r~cV + remove @.fred + +# User-editable dependencies: +.c.o: + cc $(ccflags) -o $@ $< + +# Static dependencies: + +# Dynamic dependencies: +o.example: c.example +o.example: h.zlib +o.example: h.zconf +o.minigzip: c.minigzip +o.minigzip: h.zlib +o.minigzip: h.zconf +o.adler32: c.adler32 +o.adler32: h.zlib +o.adler32: h.zconf +o.compress: c.compress +o.compress: h.zlib +o.compress: h.zconf +o.crc32: c.crc32 +o.crc32: h.zlib +o.crc32: h.zconf +o.deflate: c.deflate +o.deflate: h.deflate +o.deflate: h.zutil +o.deflate: h.zlib +o.deflate: h.zconf +o.gzio: c.gzio +o.gzio: h.zutil +o.gzio: h.zlib +o.gzio: h.zconf +o.infblock: c.infblock +o.infblock: h.zutil +o.infblock: h.zlib +o.infblock: h.zconf +o.infblock: h.infblock +o.infblock: h.inftrees +o.infblock: h.infcodes +o.infblock: h.infutil +o.infcodes: c.infcodes +o.infcodes: h.zutil +o.infcodes: h.zlib +o.infcodes: h.zconf +o.infcodes: h.inftrees +o.infcodes: h.infblock +o.infcodes: h.infcodes +o.infcodes: h.infutil +o.infcodes: h.inffast +o.inffast: c.inffast +o.inffast: h.zutil +o.inffast: h.zlib +o.inffast: h.zconf +o.inffast: h.inftrees +o.inffast: h.infblock +o.inffast: h.infcodes +o.inffast: h.infutil +o.inffast: h.inffast +o.inflate: c.inflate +o.inflate: h.zutil +o.inflate: h.zlib +o.inflate: h.zconf +o.inflate: h.infblock +o.inftrees: c.inftrees +o.inftrees: h.zutil +o.inftrees: h.zlib +o.inftrees: h.zconf +o.inftrees: h.inftrees +o.inftrees: h.inffixed +o.infutil: c.infutil +o.infutil: h.zutil +o.infutil: h.zlib +o.infutil: h.zconf +o.infutil: h.infblock +o.infutil: h.inftrees +o.infutil: h.infcodes +o.infutil: h.infutil +o.trees: c.trees +o.trees: h.deflate +o.trees: h.zutil +o.trees: h.zlib +o.trees: h.zconf +o.trees: h.trees +o.uncompr: c.uncompr +o.uncompr: h.zlib +o.uncompr: h.zconf +o.zutil: c.zutil +o.zutil: h.zutil +o.zutil: h.zlib +o.zutil: h.zconf diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/README b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/README new file mode 100644 index 00000000..800bf079 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/README @@ -0,0 +1,3 @@ +This directory contains files that have not been updated for zlib 1.2.x + +(Volunteers are encouraged to help clean this up. Thanks.) diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/descrip.mms b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/descrip.mms new file mode 100644 index 00000000..7066da5b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/descrip.mms @@ -0,0 +1,48 @@ +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser + +cc_defs = +c_deb = + +.ifdef __DECC__ +pref = /prefix=all +.endif + +OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\ + inftrees.obj, infcodes.obj, infutil.obj, inffast.obj + +CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) + +all : example.exe minigzip.exe + @ write sys$output " Example applications available" +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib + +clean : + delete *.obj;*,libz.olb;* + + +# Other dependencies. +adler32.obj : zutil.h zlib.h zconf.h +compress.obj : zlib.h zconf.h +crc32.obj : zutil.h zlib.h zconf.h +deflate.obj : deflate.h zutil.h zlib.h zconf.h +example.obj : zlib.h zconf.h +gzio.obj : zutil.h zlib.h zconf.h +infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.obj : zutil.h zlib.h zconf.h infblock.h +inftrees.obj : zutil.h zlib.h zconf.h inftrees.h +infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.obj : zlib.h zconf.h +trees.obj : deflate.h zutil.h zlib.h zconf.h +uncompr.obj : zlib.h zconf.h +zutil.obj : zutil.h zlib.h zconf.h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/os2/Makefile.os2 b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/os2/Makefile.os2 new file mode 100644 index 00000000..a105aaa5 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/os2/Makefile.os2 @@ -0,0 +1,136 @@ +# Makefile for zlib under OS/2 using GCC (PGCC) +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# cp Makefile.os2 .. +# cd .. +# make -f Makefile.os2 test + +# This makefile will build a static library z.lib, a shared library +# z.dll and a import library zdll.lib. You can use either z.lib or +# zdll.lib by specifying either -lz or -lzdll on gcc's command line + +CC=gcc -Zomf -s + +CFLAGS=-O6 -Wall +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +#################### BUG WARNING: ##################### +## infcodes.c hits a bug in pgcc-1.0, so you have to use either +## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem) +## This bug is reportedly fixed in pgcc >1.0, but this was not tested +CFLAGS+=-fno-force-mem + +LDFLAGS=-s -L. -lzdll -Zcrtdll +LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll + +VER=1.1.0 +ZLIB=z.lib +SHAREDLIB=z.dll +SHAREDLIBIMP=zdll.lib +LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP) + +AR=emxomfar cr +IMPLIB=emximp +RANLIB=echo +TAR=tar +SHELL=bash + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \ + algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ + nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \ + contrib/asm386/*.asm contrib/asm386/*.c \ + contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \ + contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ + contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 + +all: example.exe minigzip.exe + +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +$(ZLIB): $(OBJS) + $(AR) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +$(SHAREDLIB): $(OBJS) os2/z.def + $(LDSHARED) -o $@ $^ + +$(SHAREDLIBIMP): os2/z.def + $(IMPLIB) -o $@ $^ + +example.exe: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip.exe: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +clean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz + +distclean: clean + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/os2/zlib.def b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/os2/zlib.def new file mode 100644 index 00000000..4c753f1a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/os2/zlib.def @@ -0,0 +1,51 @@ +; +; Slightly modified version of ../nt/zlib.dnt :-) +; + +LIBRARY Z +DESCRIPTION "Zlib compression library for OS/2" +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +EXPORTS + adler32 + compress + crc32 + deflate + deflateCopy + deflateEnd + deflateInit2_ + deflateInit_ + deflateParams + deflateReset + deflateSetDictionary + gzclose + gzdopen + gzerror + gzflush + gzopen + gzread + gzwrite + inflate + inflateEnd + inflateInit2_ + inflateInit_ + inflateReset + inflateSetDictionary + inflateSync + uncompress + zlibVersion + gzprintf + gzputc + gzgetc + gzseek + gzrewind + gztell + gzeof + gzsetparams + zError + inflateSyncPoint + get_crc_table + compress2 + gzputs + gzgets diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/visual-basic.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/visual-basic.txt new file mode 100644 index 00000000..57efe581 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/old/visual-basic.txt @@ -0,0 +1,160 @@ +See below some functions declarations for Visual Basic. + +Frequently Asked Question: + +Q: Each time I use the compress function I get the -5 error (not enough + room in the output buffer). + +A: Make sure that the length of the compressed buffer is passed by + reference ("as any"), not by value ("as long"). Also check that + before the call of compress this length is equal to the total size of + the compressed buffer and not zero. + + +From: "Jon Caruana" +Subject: Re: How to port zlib declares to vb? +Date: Mon, 28 Oct 1996 18:33:03 -0600 + +Got the answer! (I haven't had time to check this but it's what I got, and +looks correct): + +He has the following routines working: + compress + uncompress + gzopen + gzwrite + gzread + gzclose + +Declares follow: (Quoted from Carlos Rios , in Vb4 form) + +#If Win16 Then 'Use Win16 calls. +Declare Function compress Lib "ZLIB.DLL" (ByVal compr As + String, comprLen As Any, ByVal buf As String, ByVal buflen + As Long) As Integer +Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr + As String, uncomprLen As Any, ByVal compr As String, ByVal + lcompr As Long) As Integer +Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As + String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As + Long) As Integer +#Else +Declare Function compress Lib "ZLIB32.DLL" + (ByVal compr As String, comprLen As Any, ByVal buf As + String, ByVal buflen As Long) As Integer +Declare Function uncompress Lib "ZLIB32.DLL" + (ByVal uncompr As String, uncomprLen As Any, ByVal compr As + String, ByVal lcompr As Long) As Long +Declare Function gzopen Lib "ZLIB32.DLL" + (ByVal file As String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzwrite Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzclose Lib "ZLIB32.DLL" + (ByVal file As Long) As Long +#End If + +-Jon Caruana +jon-net@usa.net +Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member + + +Here is another example from Michael that he +says conforms to the VB guidelines, and that solves the problem of not +knowing the uncompressed size by storing it at the end of the file: + +'Calling the functions: +'bracket meaning: [optional] {Range of possible values} +'Call subCompressFile( [, , [level of compression {1..9}]]) +'Call subUncompressFile() + +Option Explicit +Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller' +Private Const SUCCESS As Long = 0 +Private Const strFilExt As String = ".cpr" +Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef +dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long, +ByVal level As Integer) As Long +Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef +dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long) +As Long + +Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal +strargCprFilPth As String, Optional ByVal intLvl As Integer = 9) + Dim strCprPth As String + Dim lngOriSiz As Long + Dim lngCprSiz As Long + Dim bytaryOri() As Byte + Dim bytaryCpr() As Byte + lngOriSiz = FileLen(strargOriFilPth) + ReDim bytaryOri(lngOriSiz - 1) + Open strargOriFilPth For Binary Access Read As #1 + Get #1, , bytaryOri() + Close #1 + strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth) +'Select file path and name + strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) = +strFilExt, "", strFilExt) 'Add file extension if not exists + lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit +more space then original file size + ReDim bytaryCpr(lngCprSiz - 1) + If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) = +SUCCESS Then + lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100 + ReDim Preserve bytaryCpr(lngCprSiz - 1) + Open strCprPth For Binary Access Write As #1 + Put #1, , bytaryCpr() + Put #1, , lngOriSiz 'Add the the original size value to the end +(last 4 bytes) + Close #1 + Else + MsgBox "Compression error" + End If + Erase bytaryCpr + Erase bytaryOri +End Sub + +Public Sub subUncompressFile(ByVal strargFilPth As String) + Dim bytaryCpr() As Byte + Dim bytaryOri() As Byte + Dim lngOriSiz As Long + Dim lngCprSiz As Long + Dim strOriPth As String + lngCprSiz = FileLen(strargFilPth) + ReDim bytaryCpr(lngCprSiz - 1) + Open strargFilPth For Binary Access Read As #1 + Get #1, , bytaryCpr() + Close #1 + 'Read the original file size value: + lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _ + + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _ + + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _ + + bytaryCpr(lngCprSiz - 4) + ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value + ReDim bytaryOri(lngOriSiz - 1) + If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS +Then + strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt)) + Open strOriPth For Binary Access Write As #1 + Put #1, , bytaryOri() + Close #1 + Else + MsgBox "Uncompression error" + End If + Erase bytaryCpr + Erase bytaryOri +End Sub +Public Property Get lngPercentSmaller() As Long + lngPercentSmaller = lngpvtPcnSml +End Property diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/qnx/package.qpg b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/qnx/package.qpg new file mode 100644 index 00000000..4d7ea6a0 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/qnx/package.qpg @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Library + + Medium + + 2.0 + + + + zlib + zlib + alain.bonnefoy@icbt.com + Public + public + www.gzip.org/zlib + + + Jean-Loup Gailly,Mark Adler + www.gzip.org/zlib + + zlib@gzip.org + + + A massively spiffy yet delicately unobtrusive compression library. + zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system. + http://www.gzip.org/zlib + + + + + 1.2.6 + Medium + Stable + + + + + + + No License + + + + Software Development/Libraries and Extensions/C Libraries + zlib,compression + qnx6 + qnx6 + None + Developer + + + + + + + + + + + + + + Install + Post + No + Ignore + + No + Optional + + + + + + + + + + + + + InstallOver + zlib + + + + + + + + + + + + + InstallOver + zlib-dev + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/test/example.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/test/example.c new file mode 100644 index 00000000..f515a485 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/test/example.c @@ -0,0 +1,601 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2006, 2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" +#include + +#ifdef STDC +# include +# include +#endif + +#if defined(VMS) || defined(RISCOS) +# define TESTFILE "foo-gz" +#else +# define TESTFILE "foo.gz" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +const char hello[] = "hello, hello!"; +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ + +const char dictionary[] = "hello"; +uLong dictId; /* Adler32 value of the dictionary */ + +void test_deflate OF((Byte *compr, uLong comprLen)); +void test_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_deflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_flush OF((Byte *compr, uLong *comprLen)); +void test_sync OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_dict_deflate OF((Byte *compr, uLong comprLen)); +void test_dict_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +int main OF((int argc, char *argv[])); + + +#ifdef Z_SOLO + +void *myalloc OF((void *, unsigned, unsigned)); +void myfree OF((void *, void *)); + +void *myalloc(q, n, m) + void *q; + unsigned n, m; +{ + q = Z_NULL; + return calloc(n, m); +} + +void myfree(void *q, void *p) +{ + q = Z_NULL; + free(p); +} + +static alloc_func zalloc = myalloc; +static free_func zfree = myfree; + +#else /* !Z_SOLO */ + +static alloc_func zalloc = (alloc_func)0; +static free_func zfree = (free_func)0; + +void test_compress OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_gzio OF((const char *fname, + Byte *uncompr, uLong uncomprLen)); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + uLong len = (uLong)strlen(hello)+1; + + err = compress(compr, &comprLen, (const Bytef*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + exit(1); + } else { + printf("uncompress(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(fname, uncompr, uncomprLen) + const char *fname; /* compressed file name */ + Byte *uncompr; + uLong uncomprLen; +{ +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); +#else + int err; + int len = (int)strlen(hello)+1; + gzFile file; + z_off_t pos; + + file = gzopen(fname, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + gzputc(file, 'h'); + if (gzputs(file, "ello") != 4) { + fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); + exit(1); + } + if (gzprintf(file, ", %s!", "hello") != 8) { + fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); + exit(1); + } + gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ + gzclose(file); + + file = gzopen(fname, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + strcpy((char*)uncompr, "garbage"); + + if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); + exit(1); + } else { + printf("gzread(): %s\n", (char*)uncompr); + } + + pos = gzseek(file, -8L, SEEK_CUR); + if (pos != 6 || gztell(file) != pos) { + fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", + (long)pos, (long)gztell(file)); + exit(1); + } + + if (gzgetc(file) != ' ') { + fprintf(stderr, "gzgetc error\n"); + exit(1); + } + + if (gzungetc(' ', file) != ' ') { + fprintf(stderr, "gzungetc error\n"); + exit(1); + } + + gzgets(file, (char*)uncompr, (int)uncomprLen); + if (strlen((char*)uncompr) != 7) { /* " hello!" */ + fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello + 6)) { + fprintf(stderr, "bad gzgets after gzseek\n"); + exit(1); + } else { + printf("gzgets() after gzseek: %s\n", (char*)uncompr); + } + + gzclose(file); +#endif +} + +#endif /* Z_SOLO */ + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + uLong len = (uLong)strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } else { + printf("inflate(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + c_stream.avail_in = (uInt)comprLen/2; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (uInt)uncomprLen; + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + comprLen/2) { + fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); + exit(1); + } else { + printf("large_inflate(): OK\n"); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr, comprLen) + Byte *compr; + uLong *comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + uInt len = (uInt)strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Bytef*)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uInt)*comprLen; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ + err = inflateSync(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + exit(1); + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = deflateSetDictionary(&c_stream, + (const Bytef*)dictionary, (int)sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (Bytef*)hello; + c_stream.avail_in = (uInt)strlen(hello)+1; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, + (int)sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } else { + printf("inflate with dictionary: %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + Byte *compr, *uncompr; + uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + uLong uncomprLen = comprLen; + static const char* myVersion = ZLIB_VERSION; + + if (zlibVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + + printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", + ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); + + compr = (Byte*)calloc((uInt)comprLen, 1); + uncompr = (Byte*)calloc((uInt)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == Z_NULL || uncompr == Z_NULL) { + printf("out of memory\n"); + exit(1); + } + +#ifdef Z_SOLO + argc = strlen(argv[0]); +#else + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + uncompr, uncomprLen); +#endif + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/test/infcover.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/test/infcover.c new file mode 100644 index 00000000..fe3d9203 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/test/infcover.c @@ -0,0 +1,671 @@ +/* infcover.c -- test zlib's inflate routines with full code coverage + * Copyright (C) 2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* to use, do: ./configure --cover && make cover */ + +#include +#include +#include +#include +#include "zlib.h" + +/* get definition of internal structure so we can mess with it (see pull()), + and so we can call inflate_trees() (see cover5()) */ +#define ZLIB_INTERNAL +#include "inftrees.h" +#include "inflate.h" + +#define local static + +/* -- memory tracking routines -- */ + +/* + These memory tracking routines are provided to zlib and track all of zlib's + allocations and deallocations, check for LIFO operations, keep a current + and high water mark of total bytes requested, optionally set a limit on the + total memory that can be allocated, and when done check for memory leaks. + + They are used as follows: + + z_stream strm; + mem_setup(&strm) initializes the memory tracking and sets the + zalloc, zfree, and opaque members of strm to use + memory tracking for all zlib operations on strm + mem_limit(&strm, limit) sets a limit on the total bytes requested -- a + request that exceeds this limit will result in an + allocation failure (returns NULL) -- setting the + limit to zero means no limit, which is the default + after mem_setup() + mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used + mem_high(&strm, "msg") prints to stderr "msg" and the high water mark + mem_done(&strm, "msg") ends memory tracking, releases all allocations + for the tracking as well as leaked zlib blocks, if + any. If there was anything unusual, such as leaked + blocks, non-FIFO frees, or frees of addresses not + allocated, then "msg" and information about the + problem is printed to stderr. If everything is + normal, nothing is printed. mem_done resets the + strm members to Z_NULL to use the default memory + allocation routines on the next zlib initialization + using strm. + */ + +/* these items are strung together in a linked list, one for each allocation */ +struct mem_item { + void *ptr; /* pointer to allocated memory */ + size_t size; /* requested size of allocation */ + struct mem_item *next; /* pointer to next item in list, or NULL */ +}; + +/* this structure is at the root of the linked list, and tracks statistics */ +struct mem_zone { + struct mem_item *first; /* pointer to first item in list, or NULL */ + size_t total, highwater; /* total allocations, and largest total */ + size_t limit; /* memory allocation limit, or 0 if no limit */ + int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */ +}; + +/* memory allocation routine to pass to zlib */ +local void *mem_alloc(void *mem, unsigned count, unsigned size) +{ + void *ptr; + struct mem_item *item; + struct mem_zone *zone = mem; + size_t len = count * (size_t)size; + + /* induced allocation failure */ + if (zone == NULL || (zone->limit && zone->total + len > zone->limit)) + return NULL; + + /* perform allocation using the standard library, fill memory with a + non-zero value to make sure that the code isn't depending on zeros */ + ptr = malloc(len); + if (ptr == NULL) + return NULL; + memset(ptr, 0xa5, len); + + /* create a new item for the list */ + item = malloc(sizeof(struct mem_item)); + if (item == NULL) { + free(ptr); + return NULL; + } + item->ptr = ptr; + item->size = len; + + /* insert item at the beginning of the list */ + item->next = zone->first; + zone->first = item; + + /* update the statistics */ + zone->total += item->size; + if (zone->total > zone->highwater) + zone->highwater = zone->total; + + /* return the allocated memory */ + return ptr; +} + +/* memory free routine to pass to zlib */ +local void mem_free(void *mem, void *ptr) +{ + struct mem_item *item, *next; + struct mem_zone *zone = mem; + + /* if no zone, just do a free */ + if (zone == NULL) { + free(ptr); + return; + } + + /* point next to the item that matches ptr, or NULL if not found -- remove + the item from the linked list if found */ + next = zone->first; + if (next) { + if (next->ptr == ptr) + zone->first = next->next; /* first one is it, remove from list */ + else { + do { /* search the linked list */ + item = next; + next = item->next; + } while (next != NULL && next->ptr != ptr); + if (next) { /* if found, remove from linked list */ + item->next = next->next; + zone->notlifo++; /* not a LIFO free */ + } + + } + } + + /* if found, update the statistics and free the item */ + if (next) { + zone->total -= next->size; + free(next); + } + + /* if not found, update the rogue count */ + else + zone->rogue++; + + /* in any case, do the requested free with the standard library function */ + free(ptr); +} + +/* set up a controlled memory allocation space for monitoring, set the stream + parameters to the controlled routines, with opaque pointing to the space */ +local void mem_setup(z_stream *strm) +{ + struct mem_zone *zone; + + zone = malloc(sizeof(struct mem_zone)); + assert(zone != NULL); + zone->first = NULL; + zone->total = 0; + zone->highwater = 0; + zone->limit = 0; + zone->notlifo = 0; + zone->rogue = 0; + strm->opaque = zone; + strm->zalloc = mem_alloc; + strm->zfree = mem_free; +} + +/* set a limit on the total memory allocation, or 0 to remove the limit */ +local void mem_limit(z_stream *strm, size_t limit) +{ + struct mem_zone *zone = strm->opaque; + + zone->limit = limit; +} + +/* show the current total requested allocations in bytes */ +local void mem_used(z_stream *strm, char *prefix) +{ + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total); +} + +/* show the high water allocation in bytes */ +local void mem_high(z_stream *strm, char *prefix) +{ + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater); +} + +/* release the memory allocation zone -- if there are any surprises, notify */ +local void mem_done(z_stream *strm, char *prefix) +{ + int count = 0; + struct mem_item *item, *next; + struct mem_zone *zone = strm->opaque; + + /* show high water mark */ + mem_high(strm, prefix); + + /* free leftover allocations and item structures, if any */ + item = zone->first; + while (item != NULL) { + free(item->ptr); + next = item->next; + free(item); + item = next; + count++; + } + + /* issue alerts about anything unexpected */ + if (count || zone->total) + fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n", + prefix, zone->total, count); + if (zone->notlifo) + fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo); + if (zone->rogue) + fprintf(stderr, "** %s: %d frees not recognized\n", + prefix, zone->rogue); + + /* free the zone and delete from the stream */ + free(zone); + strm->opaque = Z_NULL; + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; +} + +/* -- inflate test routines -- */ + +/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This + decodes liberally, in that hex digits can be adjacent, in which case two in + a row writes a byte. Or they can delimited by any non-hex character, where + the delimiters are ignored except when a single hex digit is followed by a + delimiter in which case that single digit writes a byte. The returned + data is allocated and must eventually be freed. NULL is returned if out of + memory. If the length is not needed, then len can be NULL. */ +local unsigned char *h2b(const char *hex, unsigned *len) +{ + unsigned char *in; + unsigned next, val; + + in = malloc((strlen(hex) + 1) >> 1); + if (in == NULL) + return NULL; + next = 0; + val = 1; + do { + if (*hex >= '0' && *hex <= '9') + val = (val << 4) + *hex - '0'; + else if (*hex >= 'A' && *hex <= 'F') + val = (val << 4) + *hex - 'A' + 10; + else if (*hex >= 'a' && *hex <= 'f') + val = (val << 4) + *hex - 'a' + 10; + else if (val != 1 && val < 32) /* one digit followed by delimiter */ + val += 240; /* make it look like two digits */ + if (val > 255) { /* have two digits */ + in[next++] = val & 0xff; /* save the decoded byte */ + val = 1; /* start over */ + } + } while (*hex++); /* go through the loop with the terminating null */ + if (len != NULL) + *len = next; + in = reallocf(in, next); + return in; +} + +/* generic inflate() run, where hex is the hexadecimal input data, what is the + text to include in an error message, step is how much input data to feed + inflate() on each call, or zero to feed it all, win is the window bits + parameter to inflateInit2(), len is the size of the output buffer, and err + is the error code expected from the first inflate() call (the second + inflate() call is expected to return Z_STREAM_END). If win is 47, then + header information is collected with inflateGetHeader(). If a zlib stream + is looking for a dictionary, then an empty dictionary is provided. + inflate() is run until all of the input data is consumed. */ +local void inf(char *hex, char *what, unsigned step, int win, unsigned len, + int err) +{ + int ret; + unsigned have; + unsigned char *in, *out; + z_stream strm, copy; + gz_header head; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, win); + if (ret != Z_OK) { + mem_done(&strm, what); + return; + } + out = malloc(len); assert(out != NULL); + if (win == 47) { + head.extra = out; + head.extra_max = len; + head.name = out; + head.name_max = len; + head.comment = out; + head.comm_max = len; + ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK); + } + in = h2b(hex, &have); assert(in != NULL); + if (step == 0 || step > have) + step = have; + strm.avail_in = step; + have -= step; + strm.next_in = in; + do { + strm.avail_out = len; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err); + if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT) + break; + if (ret == Z_NEED_DICT) { + ret = inflateSetDictionary(&strm, in, 1); + assert(ret == Z_DATA_ERROR); + mem_limit(&strm, 1); + ret = inflateSetDictionary(&strm, out, 0); + assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ((struct inflate_state *)strm.state)->mode = DICT; + ret = inflateSetDictionary(&strm, out, 0); + assert(ret == Z_OK); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR); + } + ret = inflateCopy(©, &strm); assert(ret == Z_OK); + ret = inflateEnd(©); assert(ret == Z_OK); + err = 9; /* don't care next time around */ + have += strm.avail_in; + strm.avail_in = step > have ? have : step; + have -= strm.avail_in; + } while (strm.avail_in); + free(in); + free(out); + ret = inflateReset2(&strm, -8); assert(ret == Z_OK); + ret = inflateEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, what); +} + +/* cover all of the lines in inflate.c up to inflate() */ +local void cover_support(void) +{ + int ret; + z_stream strm; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); assert(ret == Z_OK); + mem_used(&strm, "inflate init"); + ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK); + ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK); + ret = inflateSetDictionary(&strm, Z_NULL, 0); + assert(ret == Z_STREAM_ERROR); + ret = inflateEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, "prime"); + + inf("63 0", "force window allocation", 0, -15, 1, Z_OK); + inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK); + inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK); + inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END); + inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR); + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream)); + assert(ret == Z_VERSION_ERROR); + mem_done(&strm, "wrong version"); + + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); assert(ret == Z_OK); + ret = inflateEnd(&strm); assert(ret == Z_OK); + fputs("inflate built-in memory routines\n", stderr); +} + +/* cover all inflate() header and trailer cases and code after inflate() */ +local void cover_wrap(void) +{ + int ret; + z_stream strm, copy; + unsigned char dict[257]; + + ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR); + ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR); + ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflate bad parameters\n", stderr); + + inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR); + inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR); + inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR); + inf("8 99", "set window size from header", 0, 0, 0, Z_OK); + inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR); + inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END); + inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1, + Z_DATA_ERROR); + inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length", + 0, 47, 0, Z_STREAM_END); + inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR); + inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT); + inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK); + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, -8); + strm.avail_in = 2; + strm.next_in = (void *)"\x63"; + strm.avail_out = 1; + strm.next_out = (void *)&ret; + mem_limit(&strm, 1); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + memset(dict, 0, 257); + ret = inflateSetDictionary(&strm, dict, 257); + assert(ret == Z_OK); + mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256); + ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x80"; + ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR); + strm.avail_in = 4; + strm.next_in = (void *)"\0\0\xff\xff"; + ret = inflateSync(&strm); assert(ret == Z_OK); + (void)inflateSyncPoint(&strm); + ret = inflateCopy(©, &strm); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR); + (void)inflateMark(&strm); + ret = inflateEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, "miscellaneous, force memory errors"); +} + +/* input and output functions for inflateBack() */ +local unsigned pull(void *desc, unsigned char **buf) +{ + static unsigned int next = 0; + static unsigned char dat[] = {0x63, 0, 2, 0}; + struct inflate_state *state; + + if (desc == Z_NULL) { + next = 0; + return 0; /* no input (already provided at next_in) */ + } + state = (void *)((z_stream *)desc)->state; + if (state != Z_NULL) + state->mode = SYNC; /* force an otherwise impossible situation */ + return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0; +} + +local int push(void *desc, unsigned char *buf, unsigned len) +{ + buf += len; + return desc != Z_NULL; /* force error if desc not null */ +} + +/* cover inflateBack() up to common deflate data cases and after those */ +local void cover_back(void) +{ + int ret; + z_stream strm; + unsigned char win[32768]; + + ret = inflateBackInit_(Z_NULL, 0, win, 0, 0); + assert(ret == Z_VERSION_ERROR); + ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR); + ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL); + assert(ret == Z_STREAM_ERROR); + ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflateBack bad parameters\n", stderr); + + mem_setup(&strm); + ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x03"; + ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL); + assert(ret == Z_STREAM_END); + /* force output error */ + strm.avail_in = 3; + strm.next_in = (void *)"\x63\x00"; + ret = inflateBack(&strm, pull, Z_NULL, push, &strm); + assert(ret == Z_BUF_ERROR); + /* force mode error by mucking with state */ + ret = inflateBack(&strm, pull, &strm, push, Z_NULL); + assert(ret == Z_STREAM_ERROR); + ret = inflateBackEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, "inflateBack bad state"); + + ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK); + ret = inflateBackEnd(&strm); assert(ret == Z_OK); + fputs("inflateBack built-in memory routines\n", stderr); +} + +/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */ +local int try(char *hex, char *id, int err) +{ + int ret; + unsigned len, size; + unsigned char *in, *out, *win; + char *prefix; + z_stream strm; + + /* convert to hex */ + in = h2b(hex, &len); + assert(in != NULL); + + /* allocate work areas */ + size = len << 3; + out = malloc(size); + assert(out != NULL); + win = malloc(32768); + assert(win != NULL); + prefix = malloc(strlen(id) + 6); + assert(prefix != NULL); + + /* first with inflate */ + strcpy(prefix, id); + strcat(prefix, "-late"); + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, err < 0 ? 47 : -15); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + do { + strm.avail_out = size; + strm.next_out = out; + ret = inflate(&strm, Z_TREES); + assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR); + if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT) + break; + } while (strm.avail_in || strm.avail_out == 0); + if (err) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + inflateEnd(&strm); + mem_done(&strm, prefix); + + /* then with inflateBack */ + if (err >= 0) { + strcpy(prefix, id); + strcat(prefix, "-back"); + mem_setup(&strm); + ret = inflateBackInit(&strm, 15, win); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL); + assert(ret != Z_STREAM_ERROR); + if (err) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + inflateBackEnd(&strm); + mem_done(&strm, prefix); + } + + /* clean up */ + free(prefix); + free(win); + free(out); + free(in); + return ret; +} + +/* cover deflate data cases in both inflate() and inflateBack() */ +local void cover_inflate(void) +{ + try("0 0 0 0 0", "invalid stored block lengths", 1); + try("3 0", "fixed", 0); + try("6", "invalid block type", 1); + try("1 1 0 fe ff 0", "stored", 0); + try("fc 0 0", "too many length or distance symbols", 1); + try("4 0 fe ff", "invalid code lengths set", 1); + try("4 0 24 49 0", "invalid bit length repeat", 1); + try("4 0 24 e9 ff ff", "invalid bit length repeat", 1); + try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1); + try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0", + "invalid literal/lengths set", 1); + try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1); + try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1); + try("2 7e ff ff", "invalid distance code", 1); + try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1); + + /* also trailer mismatch just in inflate() */ + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1); + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1", + "incorrect length check", -1); + try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0); + try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f", + "long code", 0); + try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0); + try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c", + "long distance and extra", 0); + try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0); + inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258, + Z_STREAM_END); + inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK); +} + +/* cover remaining lines in inftrees.c */ +local void cover_trees(void) +{ + int ret; + unsigned bits; + unsigned short lens[16], work[16]; + code *next, table[ENOUGH_DISTS]; + + /* we need to call inflate_table() directly in order to manifest not- + enough errors, since zlib insures that enough is always enough */ + for (bits = 0; bits < 15; bits++) + lens[bits] = (unsigned short)(bits + 1); + lens[15] = 15; + next = table; + bits = 15; + ret = inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + next = table; + bits = 1; + ret = inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + fputs("inflate_table not enough errors\n", stderr); +} + +/* cover remaining inffast.c decoding and window copying */ +local void cover_fast(void) +{ + inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68" + " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR); + inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49" + " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258, + Z_DATA_ERROR); + inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258, + Z_DATA_ERROR); + inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258, + Z_DATA_ERROR); + inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0", + "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR); + inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK); + inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0", + "contiguous and wrap around window", 6, -8, 259, Z_OK); + inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259, + Z_STREAM_END); +} + +int main(void) +{ + fprintf(stderr, "%s\n", zlibVersion()); + cover_support(); + cover_wrap(); + cover_back(); + cover_inflate(); + cover_trees(); + cover_fast(); + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/test/minigzip.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/test/minigzip.c new file mode 100644 index 00000000..83173442 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/test/minigzip.c @@ -0,0 +1,631 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. On MSDOS, use only on file names without extension + * or in pipe mode. + */ + +/* @(#) $Id$ */ + +#include "zlib.h" +#include + +#ifdef STDC +# include +# include +#endif + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# ifdef UNDER_CE +# include +# endif +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fileno */ +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ + extern int unlink OF((const char *)); +#endif +#endif + +#if defined(UNDER_CE) +# include +# define perror(s) pwinerror(s) + +/* Map the Windows error number in ERROR to a locale-dependent error + message string and return a pointer to it. Typically, the values + for ERROR come from GetLastError. + + The string pointed to shall not be modified by the application, + but may be overwritten by a subsequent call to strwinerror + + The strwinerror function does not change the current setting + of GetLastError. */ + +static char *strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +static void pwinerror (s) + const char *s; +{ + if (s && *s) + fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); + else + fprintf(stderr, "%s\n", strwinerror(GetLastError ())); +} + +#endif /* UNDER_CE */ + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 +#define MAX_NAME_LEN 1024 + +#ifdef MAXSEG_64K +# define local static + /* Needed for systems with limitation on stack size. */ +#else +# define local +#endif + +#ifdef Z_SOLO +/* for Z_SOLO, create simplified gz* functions using deflate and inflate */ + +#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE) +# include /* for unlink() */ +#endif + +void *myalloc OF((void *, unsigned, unsigned)); +void myfree OF((void *, void *)); + +void *myalloc(q, n, m) + void *q; + unsigned n, m; +{ + q = Z_NULL; + return calloc(n, m); +} + +void myfree(q, p) + void *q, *p; +{ + q = Z_NULL; + free(p); +} + +typedef struct gzFile_s { + FILE *file; + int write; + int err; + char *msg; + z_stream strm; +} *gzFile; + +gzFile gzopen OF((const char *, const char *)); +gzFile gzdopen OF((int, const char *)); +gzFile gz_open OF((const char *, int, const char *)); + +gzFile gzopen(path, mode) +const char *path; +const char *mode; +{ + return gz_open(path, -1, mode); +} + +gzFile gzdopen(fd, mode) +int fd; +const char *mode; +{ + return gz_open(NULL, fd, mode); +} + +gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gzFile gz; + int ret; + + gz = malloc(sizeof(gzFile)); + if (gz == NULL) + return NULL; + gz->write = strchr(mode, 'w') != NULL; + gz->strm.zalloc = myalloc; + gz->strm.zfree = myfree; + gz->strm.opaque = Z_NULL; + if (gz->write) + ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0); + else { + gz->strm.next_in = 0; + gz->strm.avail_in = Z_NULL; + ret = inflateInit2(&(gz->strm), 15 + 16); + } + if (ret != Z_OK) { + free(gz); + return NULL; + } + gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") : + fopen(path, gz->write ? "wb" : "rb"); + if (gz->file == NULL) { + gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm)); + free(gz); + return NULL; + } + gz->err = 0; + gz->msg = ""; + return gz; +} + +int gzwrite OF((gzFile, const void *, unsigned)); + +int gzwrite(gz, buf, len) + gzFile gz; + const void *buf; + unsigned len; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL || !gz->write) + return 0; + strm = &(gz->strm); + strm->next_in = (void *)buf; + strm->avail_in = len; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_NO_FLUSH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + return len; +} + +int gzread OF((gzFile, void *, unsigned)); + +int gzread(gz, buf, len) + gzFile gz; + void *buf; + unsigned len; +{ + int ret; + unsigned got; + unsigned char in[1]; + z_stream *strm; + + if (gz == NULL || gz->write) + return 0; + if (gz->err) + return 0; + strm = &(gz->strm); + strm->next_out = (void *)buf; + strm->avail_out = len; + do { + got = fread(in, 1, 1, gz->file); + if (got == 0) + break; + strm->next_in = in; + strm->avail_in = 1; + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_DATA_ERROR) { + gz->err = Z_DATA_ERROR; + gz->msg = strm->msg; + return 0; + } + if (ret == Z_STREAM_END) + inflateReset(strm); + } while (strm->avail_out); + return len - strm->avail_out; +} + +int gzclose OF((gzFile)); + +int gzclose(gz) + gzFile gz; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL) + return Z_STREAM_ERROR; + strm = &(gz->strm); + if (gz->write) { + strm->next_in = Z_NULL; + strm->avail_in = 0; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_FINISH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + deflateEnd(strm); + } + else + inflateEnd(strm); + fclose(gz->file); + free(gz); + return Z_OK; +} + +const char *gzerror OF((gzFile, int *)); + +const char *gzerror(gz, err) + gzFile gz; + int *err; +{ + *err = gz->err; + return gz->msg; +} + +#endif + +char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +#ifdef USE_MMAP +int gz_compress_mmap OF((FILE *in, gzFile out)); +#endif +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file, char *mode)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + for (;;) { + len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(in, out) + FILE *in; + gzFile out; +{ + int len; + int err; + int ifd = fileno(in); + caddr_t buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (caddr_t)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = gzwrite(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(gzerror(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file, mode) + char *file; + char *mode; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + strcpy(buf, file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + strcat(infile, GZ_SUFFIX); + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] + * -c : write to standard output + * -d : decompress + * -f : compress with Z_FILTERED + * -h : compress with Z_HUFFMAN_ONLY + * -r : compress with Z_RLE + * -1 to -9 : compression level + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int copyout = 0; + int uncompr = 0; + gzFile file; + char *bname, outmode[20]; + + strcpy(outmode, "wb6 "); + + prog = argv[0]; + bname = strrchr(argv[0], '/'); + if (bname) + bname++; + else + bname = argv[0]; + argc--, argv++; + + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + + while (argc > 0) { + if (strcmp(*argv, "-c") == 0) + copyout = 1; + else if (strcmp(*argv, "-d") == 0) + uncompr = 1; + else if (strcmp(*argv, "-f") == 0) + outmode[3] = 'f'; + else if (strcmp(*argv, "-h") == 0) + outmode[3] = 'h'; + else if (strcmp(*argv, "-r") == 0) + outmode[3] = 'R'; + else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && + (*argv)[2] == 0) + outmode[2] = (*argv)[1]; + else + break; + argc--, argv++; + } + if (outmode[3] == ' ') + outmode[3] = 0; + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } + do { + if (uncompr) { + if (copyout) { + file = gzopen(*argv, "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(*argv); + } + } else { + if (copyout) { + FILE * in = fopen(*argv, "rb"); + + if (in == NULL) { + perror(*argv); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(*argv, outmode); + } + } + } while (argv++, --argc); + } + return 0; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/treebuild.xml b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/treebuild.xml new file mode 100644 index 00000000..89963a0c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/treebuild.xml @@ -0,0 +1,116 @@ + + + + zip compression library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/trees.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/trees.c new file mode 100644 index 00000000..8c32b214 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/trees.c @@ -0,0 +1,1224 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2012 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(s) + deflate_state *s; +{ + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/trees.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/trees.h new file mode 100644 index 00000000..d35639d8 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/uncompr.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/uncompr.c new file mode 100644 index 00000000..ad98be3a --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/uncompr.c @@ -0,0 +1,59 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/watcom/watcom_f.mak b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/watcom/watcom_f.mak new file mode 100644 index 00000000..37f4d74c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/watcom/watcom_f.mak @@ -0,0 +1,43 @@ +# Makefile for zlib +# OpenWatcom flat model +# Last updated: 28-Dec-2005 + +# To use, do "wmake -f watcom_f.mak" + +C_SOURCE = adler32.c compress.c crc32.c deflate.c & + gzclose.c gzlib.c gzread.c gzwrite.c & + infback.c inffast.c inflate.c inftrees.c & + trees.c uncompr.c zutil.c + +OBJS = adler32.obj compress.obj crc32.obj deflate.obj & + gzclose.obj gzlib.obj gzread.obj gzwrite.obj & + infback.obj inffast.obj inflate.obj inftrees.obj & + trees.obj uncompr.obj zutil.obj + +CC = wcc386 +LINKER = wcl386 +CFLAGS = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx +ZLIB_LIB = zlib_f.lib + +.C.OBJ: + $(CC) $(CFLAGS) $[@ + +all: $(ZLIB_LIB) example.exe minigzip.exe + +$(ZLIB_LIB): $(OBJS) + wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj + wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj + wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj + wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj + wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj + +example.exe: $(ZLIB_LIB) example.obj + $(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB) + +minigzip.exe: $(ZLIB_LIB) minigzip.obj + $(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB) + +clean: .SYMBOLIC + del *.obj + del $(ZLIB_LIB) + @echo Cleaning done diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/watcom/watcom_l.mak b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/watcom/watcom_l.mak new file mode 100644 index 00000000..193eed7b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/watcom/watcom_l.mak @@ -0,0 +1,43 @@ +# Makefile for zlib +# OpenWatcom large model +# Last updated: 28-Dec-2005 + +# To use, do "wmake -f watcom_l.mak" + +C_SOURCE = adler32.c compress.c crc32.c deflate.c & + gzclose.c gzlib.c gzread.c gzwrite.c & + infback.c inffast.c inflate.c inftrees.c & + trees.c uncompr.c zutil.c + +OBJS = adler32.obj compress.obj crc32.obj deflate.obj & + gzclose.obj gzlib.obj gzread.obj gzwrite.obj & + infback.obj inffast.obj inflate.obj inftrees.obj & + trees.obj uncompr.obj zutil.obj + +CC = wcc +LINKER = wcl +CFLAGS = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx +ZLIB_LIB = zlib_l.lib + +.C.OBJ: + $(CC) $(CFLAGS) $[@ + +all: $(ZLIB_LIB) example.exe minigzip.exe + +$(ZLIB_LIB): $(OBJS) + wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj + wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj + wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj + wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj + wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj + +example.exe: $(ZLIB_LIB) example.obj + $(LINKER) -fe=example.exe example.obj $(ZLIB_LIB) + +minigzip.exe: $(ZLIB_LIB) minigzip.obj + $(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB) + +clean: .SYMBOLIC + del *.obj + del $(ZLIB_LIB) + @echo Cleaning done diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/DLL_FAQ.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/DLL_FAQ.txt new file mode 100644 index 00000000..12c00901 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/DLL_FAQ.txt @@ -0,0 +1,397 @@ + + Frequently Asked Questions about ZLIB1.DLL + + +This document describes the design, the rationale, and the usage +of the official DLL build of zlib, named ZLIB1.DLL. If you have +general questions about zlib, you should see the file "FAQ" found +in the zlib distribution, or at the following location: + http://www.gzip.org/zlib/zlib_faq.html + + + 1. What is ZLIB1.DLL, and how can I get it? + + - ZLIB1.DLL is the official build of zlib as a DLL. + (Please remark the character '1' in the name.) + + Pointers to a precompiled ZLIB1.DLL can be found in the zlib + web site at: + http://www.zlib.net/ + + Applications that link to ZLIB1.DLL can rely on the following + specification: + + * The exported symbols are exclusively defined in the source + files "zlib.h" and "zlib.def", found in an official zlib + source distribution. + * The symbols are exported by name, not by ordinal. + * The exported names are undecorated. + * The calling convention of functions is "C" (CDECL). + * The ZLIB1.DLL binary is linked to MSVCRT.DLL. + + The archive in which ZLIB1.DLL is bundled contains compiled + test programs that must run with a valid build of ZLIB1.DLL. + It is recommended to download the prebuilt DLL from the zlib + web site, instead of building it yourself, to avoid potential + incompatibilities that could be introduced by your compiler + and build settings. If you do build the DLL yourself, please + make sure that it complies with all the above requirements, + and it runs with the precompiled test programs, bundled with + the original ZLIB1.DLL distribution. + + If, for any reason, you need to build an incompatible DLL, + please use a different file name. + + + 2. Why did you change the name of the DLL to ZLIB1.DLL? + What happened to the old ZLIB.DLL? + + - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required + compilation settings that were incompatible to those used by + a static build. The DLL settings were supposed to be enabled + by defining the macro ZLIB_DLL, before including "zlib.h". + Incorrect handling of this macro was silently accepted at + build time, resulting in two major problems: + + * ZLIB_DLL was missing from the old makefile. When building + the DLL, not all people added it to the build options. In + consequence, incompatible incarnations of ZLIB.DLL started + to circulate around the net. + + * When switching from using the static library to using the + DLL, applications had to define the ZLIB_DLL macro and + to recompile all the sources that contained calls to zlib + functions. Failure to do so resulted in creating binaries + that were unable to run with the official ZLIB.DLL build. + + The only possible solution that we could foresee was to make + a binary-incompatible change in the DLL interface, in order to + remove the dependency on the ZLIB_DLL macro, and to release + the new DLL under a different name. + + We chose the name ZLIB1.DLL, where '1' indicates the major + zlib version number. We hope that we will not have to break + the binary compatibility again, at least not as long as the + zlib-1.x series will last. + + There is still a ZLIB_DLL macro, that can trigger a more + efficient build and use of the DLL, but compatibility no + longer dependents on it. + + + 3. Can I build ZLIB.DLL from the new zlib sources, and replace + an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier? + + - In principle, you can do it by assigning calling convention + keywords to the macros ZEXPORT and ZEXPORTVA. In practice, + it depends on what you mean by "an old ZLIB.DLL", because the + old DLL exists in several mutually-incompatible versions. + You have to find out first what kind of calling convention is + being used in your particular ZLIB.DLL build, and to use the + same one in the new build. If you don't know what this is all + about, you might be better off if you would just leave the old + DLL intact. + + + 4. Can I compile my application using the new zlib interface, and + link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or + earlier? + + - The official answer is "no"; the real answer depends again on + what kind of ZLIB.DLL you have. Even if you are lucky, this + course of action is unreliable. + + If you rebuild your application and you intend to use a newer + version of zlib (post- 1.1.4), it is strongly recommended to + link it to the new ZLIB1.DLL. + + + 5. Why are the zlib symbols exported by name, and not by ordinal? + + - Although exporting symbols by ordinal is a little faster, it + is risky. Any single glitch in the maintenance or use of the + DEF file that contains the ordinals can result in incompatible + builds and frustrating crashes. Simply put, the benefits of + exporting symbols by ordinal do not justify the risks. + + Technically, it should be possible to maintain ordinals in + the DEF file, and still export the symbols by name. Ordinals + exist in every DLL, and even if the dynamic linking performed + at the DLL startup is searching for names, ordinals serve as + hints, for a faster name lookup. However, if the DEF file + contains ordinals, the Microsoft linker automatically builds + an implib that will cause the executables linked to it to use + those ordinals, and not the names. It is interesting to + notice that the GNU linker for Win32 does not suffer from this + problem. + + It is possible to avoid the DEF file if the exported symbols + are accompanied by a "__declspec(dllexport)" attribute in the + source files. You can do this in zlib by predefining the + ZLIB_DLL macro. + + + 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling + convention. Why not use the STDCALL convention? + STDCALL is the standard convention in Win32, and I need it in + my Visual Basic project! + + (For readability, we use CDECL to refer to the convention + triggered by the "__cdecl" keyword, STDCALL to refer to + the convention triggered by "__stdcall", and FASTCALL to + refer to the convention triggered by "__fastcall".) + + - Most of the native Windows API functions (without varargs) use + indeed the WINAPI convention (which translates to STDCALL in + Win32), but the standard C functions use CDECL. If a user + application is intrinsically tied to the Windows API (e.g. + it calls native Windows API functions such as CreateFile()), + sometimes it makes sense to decorate its own functions with + WINAPI. But if ANSI C or POSIX portability is a goal (e.g. + it calls standard C functions such as fopen()), it is not a + sound decision to request the inclusion of , or to + use non-ANSI constructs, for the sole purpose to make the user + functions STDCALL-able. + + The functionality offered by zlib is not in the category of + "Windows functionality", but is more like "C functionality". + + Technically, STDCALL is not bad; in fact, it is slightly + faster than CDECL, and it works with variable-argument + functions, just like CDECL. It is unfortunate that, in spite + of using STDCALL in the Windows API, it is not the default + convention used by the C compilers that run under Windows. + The roots of the problem reside deep inside the unsafety of + the K&R-style function prototypes, where the argument types + are not specified; but that is another story for another day. + + The remaining fact is that CDECL is the default convention. + Even if an explicit convention is hard-coded into the function + prototypes inside C headers, problems may appear. The + necessity to expose the convention in users' callbacks is one + of these problems. + + The calling convention issues are also important when using + zlib in other programming languages. Some of them, like Ada + (GNAT) and Fortran (GNU G77), have C bindings implemented + initially on Unix, and relying on the C calling convention. + On the other hand, the pre- .NET versions of Microsoft Visual + Basic require STDCALL, while Borland Delphi prefers, although + it does not require, FASTCALL. + + In fairness to all possible uses of zlib outside the C + programming language, we choose the default "C" convention. + Anyone interested in different bindings or conventions is + encouraged to maintain specialized projects. The "contrib/" + directory from the zlib distribution already holds a couple + of foreign bindings, such as Ada, C++, and Delphi. + + + 7. I need a DLL for my Visual Basic project. What can I do? + + - Define the ZLIB_WINAPI macro before including "zlib.h", when + building both the DLL and the user application (except that + you don't need to define anything when using the DLL in Visual + Basic). The ZLIB_WINAPI macro will switch on the WINAPI + (STDCALL) convention. The name of this DLL must be different + than the official ZLIB1.DLL. + + Gilles Vollant has contributed a build named ZLIBWAPI.DLL, + with the ZLIB_WINAPI macro turned on, and with the minizip + functionality built in. For more information, please read + the notes inside "contrib/vstudio/readme.txt", found in the + zlib distribution. + + + 8. I need to use zlib in my Microsoft .NET project. What can I + do? + + - Henrik Ravn has contributed a .NET wrapper around zlib. Look + into contrib/dotzlib/, inside the zlib distribution. + + + 9. If my application uses ZLIB1.DLL, should I link it to + MSVCRT.DLL? Why? + + - It is not required, but it is recommended to link your + application to MSVCRT.DLL, if it uses ZLIB1.DLL. + + The executables (.EXE, .DLL, etc.) that are involved in the + same process and are using the C run-time library (i.e. they + are calling standard C functions), must link to the same + library. There are several libraries in the Win32 system: + CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc. + Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that + depend on it should also be linked to MSVCRT.DLL. + + +10. Why are you saying that ZLIB1.DLL and my application should + be linked to the same C run-time (CRT) library? I linked my + application and my DLLs to different C libraries (e.g. my + application to a static library, and my DLLs to MSVCRT.DLL), + and everything works fine. + + - If a user library invokes only pure Win32 API (accessible via + and the related headers), its DLL build will work + in any context. But if this library invokes standard C API, + things get more complicated. + + There is a single Win32 library in a Win32 system. Every + function in this library resides in a single DLL module, that + is safe to call from anywhere. On the other hand, there are + multiple versions of the C library, and each of them has its + own separate internal state. Standalone executables and user + DLLs that call standard C functions must link to a C run-time + (CRT) library, be it static or shared (DLL). Intermixing + occurs when an executable (not necessarily standalone) and a + DLL are linked to different CRTs, and both are running in the + same process. + + Intermixing multiple CRTs is possible, as long as their + internal states are kept intact. The Microsoft Knowledge Base + articles KB94248 "HOWTO: Use the C Run-Time" and KB140584 + "HOWTO: Link with the Correct C Run-Time (CRT) Library" + mention the potential problems raised by intermixing. + + If intermixing works for you, it's because your application + and DLLs are avoiding the corruption of each of the CRTs' + internal states, maybe by careful design, or maybe by fortune. + + Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such + as those provided by Borland, raises similar problems. + + +11. Why are you linking ZLIB1.DLL to MSVCRT.DLL? + + - MSVCRT.DLL exists on every Windows 95 with a new service pack + installed, or with Microsoft Internet Explorer 4 or later, and + on all other Windows 4.x or later (Windows 98, Windows NT 4, + or later). It is freely distributable; if not present in the + system, it can be downloaded from Microsoft or from other + software provider for free. + + The fact that MSVCRT.DLL does not exist on a virgin Windows 95 + is not so problematic. Windows 95 is scarcely found nowadays, + Microsoft ended its support a long time ago, and many recent + applications from various vendors, including Microsoft, do not + even run on it. Furthermore, no serious user should run + Windows 95 without a proper update installed. + + +12. Why are you not linking ZLIB1.DLL to + <> ? + + - We considered and abandoned the following alternatives: + + * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or + LIBCMT.LIB) is not a good option. People are using the DLL + mainly to save disk space. If you are linking your program + to a static C library, you may as well consider linking zlib + in statically, too. + + * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because + CRTDLL.DLL is present on every Win32 installation. + Unfortunately, it has a series of problems: it does not + work properly with Microsoft's C++ libraries, it does not + provide support for 64-bit file offsets, (and so on...), + and Microsoft discontinued its support a long time ago. + + * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied + with the Microsoft .NET platform, and Visual C++ 7.0/7.1, + raises problems related to the status of ZLIB1.DLL as a + system component. According to the Microsoft Knowledge Base + article KB326922 "INFO: Redistribution of the Shared C + Runtime Component in Visual C++ .NET", MSVCR70.DLL and + MSVCR71.DLL are not supposed to function as system DLLs, + because they may clash with MSVCRT.DLL. Instead, the + application's installer is supposed to put these DLLs + (if needed) in the application's private directory. + If ZLIB1.DLL depends on a non-system runtime, it cannot + function as a redistributable system component. + + * Linking ZLIB1.DLL to non-Microsoft runtimes, such as + Borland's, or Cygwin's, raises problems related to the + reliable presence of these runtimes on Win32 systems. + It's easier to let the DLL build of zlib up to the people + who distribute these runtimes, and who may proceed as + explained in the answer to Question 14. + + +13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL, + how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0 + (Visual Studio .NET) or newer? + + - Due to the problems explained in the Microsoft Knowledge Base + article KB326922 (see the previous answer), the C runtime that + comes with the VC7 environment is no longer considered a + system component. That is, it should not be assumed that this + runtime exists, or may be installed in a system directory. + Since ZLIB1.DLL is supposed to be a system component, it may + not depend on a non-system component. + + In order to link ZLIB1.DLL and your application to MSVCRT.DLL + in VC7, you need the library of Visual C++ 6.0 or older. If + you don't have this library at hand, it's probably best not to + use ZLIB1.DLL. + + We are hoping that, in the future, Microsoft will provide a + way to build applications linked to a proper system runtime, + from the Visual C++ environment. Until then, you have a + couple of alternatives, such as linking zlib in statically. + If your application requires dynamic linking, you may proceed + as explained in the answer to Question 14. + + +14. I need to link my own DLL build to a CRT different than + MSVCRT.DLL. What can I do? + + - Feel free to rebuild the DLL from the zlib sources, and link + it the way you want. You should, however, clearly state that + your build is unofficial. You should give it a different file + name, and/or install it in a private directory that can be + accessed by your application only, and is not visible to the + others (i.e. it's neither in the PATH, nor in the SYSTEM or + SYSTEM32 directories). Otherwise, your build may clash with + applications that link to the official build. + + For example, in Cygwin, zlib is linked to the Cygwin runtime + CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. + + +15. May I include additional pieces of code that I find useful, + link them in ZLIB1.DLL, and export them? + + - No. A legitimate build of ZLIB1.DLL must not include code + that does not originate from the official zlib source code. + But you can make your own private DLL build, under a different + file name, as suggested in the previous answer. + + For example, zlib is a part of the VCL library, distributed + with Borland Delphi and C++ Builder. The DLL build of VCL + is a redistributable file, named VCLxx.DLL. + + +16. May I remove some functionality out of ZLIB1.DLL, by enabling + macros like NO_GZCOMPRESS or NO_GZIP at compile time? + + - No. A legitimate build of ZLIB1.DLL must provide the complete + zlib functionality, as implemented in the official zlib source + code. But you can make your own private DLL build, under a + different file name, as suggested in the previous answer. + + +17. I made my own ZLIB1.DLL build. Can I test it for compliance? + + - We prefer that you download the official DLL from the zlib + web site. If you need something peculiar from this DLL, you + can send your suggestion to the zlib mailing list. + + However, in case you do rebuild the DLL yourself, you can run + it with the test programs found in the DLL distribution. + Running these test programs is not a guarantee of compliance, + but a failure can imply a detected problem. + +** + +This document is written and maintained by +Cosmin Truta diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.bor b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.bor new file mode 100644 index 00000000..d152bbb7 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.bor @@ -0,0 +1,110 @@ +# Makefile for zlib +# Borland C++ for Win32 +# +# Usage: +# make -f win32/Makefile.bor +# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj + +# ------------ Borland C++ ------------ + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or +# added to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +CC = bcc32 +AS = bcc32 +LD = bcc32 +AR = tlib +CFLAGS = -a -d -k- -O2 $(LOC) +ASFLAGS = $(LOC) +LDFLAGS = $(LOC) + + +# variables +ZLIB_LIB = zlib.lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +#OBJA = +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj +#OBJPA= + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $< + +.asm.obj: + $(AS) -c $(ASFLAGS) $< + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# For the sake of the old Borland make, +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + $(AR) $(ZLIB_LIB) $(OBJPA) + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + + +# cleanup +clean: + -del $(ZLIB_LIB) + -del *.obj + -del *.exe + -del *.tds + -del zlib.bak + -del foo.gz diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.emx b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.emx new file mode 100644 index 00000000..4d6ab0ef --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.emx @@ -0,0 +1,69 @@ +# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc -Zwin32 + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ + gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.gcc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.gcc new file mode 100644 index 00000000..c4a6589c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.gcc @@ -0,0 +1,180 @@ +# Makefile for zlib, derived from Makefile.dj2. +# Modified for mingw32 by C. Spieler, 6/16/98. +# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003. +# Last updated: 1-Aug-2003. +# Tested under Cygwin and MinGW. + +# Copyright (C) 1995-2003 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.gcc; make test testdll -fmakefile.gcc +# +# To use the asm code, type: +# cp contrib/asm?86/match.S ./match.S +# make LOC=-DASMV OBJA=match.o -fmakefile.gcc +# +# To install libz.a, zconf.h and zlib.h in the system directories, type: +# +# make install -fmakefile.gcc + +# Note: +# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN), +# the DLL name should be changed from "zlib1.dll". + +STATICLIB = libz.a +SHAREDLIB = zlib1.dll +IMPLIB = libz.dll.a + +# +# Set to 1 if shared object needs to be installed +# +SHARED_MODE=0 + +#LOC = -DASMV +#LOC = -DDEBUG -g + +PREFIX = +CC = $(PREFIX)gcc +CFLAGS = $(LOC) -O3 -Wall +EXTRA_CFLAGS = -DNO_VIZ + +AS = $(CC) +ASFLAGS = $(LOC) -Wall + +LD = $(CC) +LDFLAGS = $(LOC) + +AR = $(PREFIX)ar +ARFLAGS = rcs + +RC = $(PREFIX)windres +RCFLAGS = --define GCC_WINDRES + +STRIP = $(PREFIX)strip + +CP = cp -fp +# If GNU install is available, replace $(CP) with install. +INSTALL = $(CP) +RM = rm -f + +prefix ?= /usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ + gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o +OBJA = + +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe + +test: example.exe minigzip.exe + ./example + echo hello world | ./minigzip | ./minigzip -d + +testdll: example_d.exe minigzip_d.exe + ./example_d + echo hello world | ./minigzip_d | ./minigzip_d -d + +.c.o: + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< + +.S.o: + $(AS) $(ASFLAGS) -c -o $@ $< + +$(STATICLIB): $(OBJS) $(OBJA) + $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o + $(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \ + -o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o + $(STRIP) $@ + +example.exe: example.o $(STATICLIB) + $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB) + $(STRIP) $@ + +minigzip.exe: minigzip.o $(STATICLIB) + $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB) + $(STRIP) $@ + +example_d.exe: example.o $(IMPLIB) + $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB) + $(STRIP) $@ + +minigzip_d.exe: minigzip.o $(IMPLIB) + $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB) + $(STRIP) $@ + +example.o: test/example.c zlib.h zconf.h + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -I. -c -o $@ test/example.c + +minigzip.o: test/minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -I. -c -o $@ test/minigzip.c + +zlibrc.o: win32/zlib1.rc + $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc + + +# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set. + +.PHONY: install uninstall clean + +install: zlib.h zconf.h $(STATICLIB) $(IMPLIB) + @if test -z "$(INCLUDE_PATH)" -o -z "$(LIBRARY_PATH)" -o -z "$(BINARY_PATH)"; then \ + echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \ + exit 1; \ + fi + -@mkdir -p $(INCLUDE_PATH) + -@mkdir -p $(LIBRARY_PATH) $(LIBRARY_PATH)/pkgconfig + -if [ "$(SHARED_MODE)" = "1" ]; then \ + mkdir -p $(BINARY_PATH); \ + $(INSTALL) $(SHAREDLIB) $(BINARY_PATH); \ + $(INSTALL) $(IMPLIB) $(LIBRARY_PATH); \ + fi + -$(INSTALL) zlib.h $(INCLUDE_PATH) + -$(INSTALL) zconf.h $(INCLUDE_PATH) + -$(INSTALL) $(STATICLIB) $(LIBRARY_PATH) + sed \ + -e 's|@prefix@|${prefix}|g' \ + -e 's|@exec_prefix@|${exec_prefix}|g' \ + -e 's|@libdir@|$(LIBRARY_PATH)|g' \ + -e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \ + -e 's|@includedir@|$(INCLUDE_PATH)|g' \ + -e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \ + zlib.pc.in > $(LIBRARY_PATH)/pkgconfig/zlib.pc + +uninstall: + -if [ "$(SHARED_MODE)" = "1" ]; then \ + $(RM) $(BINARY_PATH)/$(SHAREDLIB); \ + $(RM) $(LIBRARY_PATH)/$(IMPLIB); \ + fi + -$(RM) $(INCLUDE_PATH)/zlib.h + -$(RM) $(INCLUDE_PATH)/zconf.h + -$(RM) $(LIBRARY_PATH)/$(STATICLIB) + +clean: + -$(RM) $(STATICLIB) + -$(RM) $(SHAREDLIB) + -$(RM) $(IMPLIB) + -$(RM) *.o + -$(RM) *.exe + -$(RM) foo.gz + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: crc32.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +gzclose.o: zlib.h zconf.h gzguts.h +gzlib.o: zlib.h zconf.h gzguts.h +gzread.o: zlib.h zconf.h gzguts.h +gzwrite.o: zlib.h zconf.h gzguts.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.msc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.msc new file mode 100644 index 00000000..59bb0dae --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/Makefile.msc @@ -0,0 +1,160 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.msc (standard build) +# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build) +# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \ +# OBJA="inffas32.obj match686.obj" (use ASM code, x86) +# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \ +# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64) + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib + +CC = cl +AS = ml +LD = link +AR = lib +RC = rc +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE +ASFLAGS = -coff -Zi $(LOC) +LDFLAGS = -nologo -debug -incremental:no -opt:ref +ARFLAGS = -nologo +RCFLAGS = /dWIN32 /r + +OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \ + gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj +OBJA = + + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +$(STATICLIB): $(OBJS) $(OBJA) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlib1.res + $(LD) $(LDFLAGS) -def:win32/zlib.def -dll -implib:$(IMPLIB) \ + -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +{test}.c.obj: + $(CC) -c -I. $(WFLAGS) $(CFLAGS) $< + +{contrib/masmx64}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +{contrib/masmx64}.asm.obj: + $(AS) -c $(ASFLAGS) $< + +{contrib/masmx86}.asm.obj: + $(AS) -c $(ASFLAGS) $< + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +gvmat64.obj: contrib\masmx64\gvmat64.asm + +inffasx64.obj: contrib\masmx64\inffasx64.asm + +inffas8664.obj: contrib\masmx64\inffas8664.c zutil.h zlib.h zconf.h \ + inftrees.h inflate.h inffast.h + +inffas32.obj: contrib\masmx86\inffas32.asm + +match686.obj: contrib\masmx86\match686.asm + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + +zlib1.res: win32/zlib1.rc + $(RC) $(RCFLAGS) /fo$@ win32/zlib1.rc + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + -del foo.gz diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/README-WIN32.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/README-WIN32.txt new file mode 100644 index 00000000..1e4c093c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/README-WIN32.txt @@ -0,0 +1,103 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.4 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). Two compiled +examples are distributed in this package, example and minigzip. The example_d +and minigzip_d flavors validate that the zlib1.dll file is working correctly. + +Questions about zlib should be sent to . The zlib home page +is http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html +before asking for help. + + +Manifest: + +The package zlib-1.2.4-win32-x86.zip contains the following files: + + README-WIN32.txt This document + ChangeLog Changes since previous zlib packages + DLL_FAQ.txt Frequently asked questions about zlib1.dll + zlib.3.pdf Documentation of this library in Adobe Acrobat format + + example.exe A statically-bound example (using zlib.lib, not the dll) + example.pdb Symbolic information for debugging example.exe + + example_d.exe A zlib1.dll bound example (using zdll.lib) + example_d.pdb Symbolic information for debugging example_d.exe + + minigzip.exe A statically-bound test program (using zlib.lib, not the dll) + minigzip.pdb Symbolic information for debugging minigzip.exe + + minigzip_d.exe A zlib1.dll bound test program (using zdll.lib) + minigzip_d.pdb Symbolic information for debugging minigzip_d.exe + + zlib.h Install these files into the compilers' INCLUDE path to + zconf.h compile programs which use zlib.lib or zdll.lib + + zdll.lib Install these files into the compilers' LIB path if linking + zdll.exp a compiled program to the zlib1.dll binary + + zlib.lib Install these files into the compilers' LIB path to link zlib + zlib.pdb into compiled programs, without zlib1.dll runtime dependency + (zlib.pdb provides debugging info to the compile time linker) + + zlib1.dll Install this binary shared library into the system PATH, or + the program's runtime directory (where the .exe resides) + zlib1.pdb Install in the same directory as zlib1.dll, in order to debug + an application crash using WinDbg or similar tools. + +All .pdb files above are entirely optional, but are very useful to a developer +attempting to diagnose program misbehavior or a crash. Many additional +important files for developers can be found in the zlib124.zip source package +available from http://zlib.net/ - review that package's README file for details. + + +Acknowledgments: + +The deflate format used by zlib was defined by Phil Katz. The deflate and +zlib specifications were written by L. Peter Deutsch. Thanks to all the +people who reported problems and suggested various improvements in zlib; they +are too numerous to cite here. + + +Copyright notice: + + (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/VisualC.txt b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/VisualC.txt new file mode 100644 index 00000000..579a5fc9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/VisualC.txt @@ -0,0 +1,3 @@ + +To build zlib using the Microsoft Visual C++ environment, +use the appropriate project from the projects/ directory. diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/zlib.def b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/zlib.def new file mode 100644 index 00000000..d96c18ae --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/zlib.def @@ -0,0 +1,84 @@ +; zlib data compression library +EXPORTS +; basic functions + zlibVersion + deflate + deflateEnd + inflate + inflateEnd +; advanced functions + deflateSetDictionary + deflateCopy + deflateReset + deflateParams + deflateTune + deflateBound + deflatePending + deflatePrime + deflateSetHeader + inflateSetDictionary + inflateSync + inflateCopy + inflateReset + inflateReset2 + inflatePrime + inflateMark + inflateGetHeader + inflateBack + inflateBackEnd + zlibCompileFlags +; utility functions + compress + compress2 + compressBound + uncompress + gzopen + gzdopen + gzbuffer + gzsetparams + gzread + gzwrite + gzprintf + gzputs + gzgets + gzputc + gzgetc + gzungetc + gzflush + gzseek + gzrewind + gztell + gzoffset + gzeof + gzdirect + gzclose + gzclose_r + gzclose_w + gzerror + gzclearerr +; large file functions + gzopen64 + gzseek64 + gztell64 + gzoffset64 + adler32_combine64 + crc32_combine64 +; checksum functions + adler32 + crc32 + adler32_combine + crc32_combine +; various hacks, don't look :) + deflateInit_ + deflateInit2_ + inflateInit_ + inflateInit2_ + inflateBackInit_ + zError + inflateSyncPoint + get_crc_table + inflateUndermine + inflateResetKeep + deflateResetKeep + gzgetc_ + gzflags diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/zlib1.rc b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/zlib1.rc new file mode 100644 index 00000000..0d1d7ffc --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/win32/zlib1.rc @@ -0,0 +1,40 @@ +#include +#include "../zlib.h" + +#ifdef GCC_WINDRES +VS_VERSION_INFO VERSIONINFO +#else +VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE +#endif + FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIB_VERSION "\0" + VALUE "InternalName", "zlib1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2006 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIB_VERSION "\0" + VALUE "Comments", "For more information visit http://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zconf.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zconf.h new file mode 100644 index 00000000..51c80ac1 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zconf.h @@ -0,0 +1,466 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflags z_gzflags +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# endif +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# ifndef Z_SOLO +# define gz_header_s z_gz_header_s +# endif +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define Z_LARGE +#endif + +#if (defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)) && !defined(Z_SOLO) +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && (defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0) +# define z_off64_t off64_t +#else +# if defined(_WIN32) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +#endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zconf.h.cmakein b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zconf.h.cmakein new file mode 100644 index 00000000..3ea5531d --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zconf.h.cmakein @@ -0,0 +1,468 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H +#cmakedefine Z_PREFIX +#cmakedefine Z_HAVE_UNISTD_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflags z_gzflags +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# endif +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# ifndef Z_SOLO +# define gz_header_s z_gz_header_s +# endif +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define Z_LARGE +#endif + +#if (defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)) && !defined(Z_SOLO) +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && (defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0) +# define z_off64_t off64_t +#else +# if defined(_WIN32) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +#endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zconf.h.in b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zconf.h.in new file mode 100644 index 00000000..51c80ac1 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zconf.h.in @@ -0,0 +1,466 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflags z_gzflags +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# endif +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# ifndef Z_SOLO +# define gz_header_s z_gz_header_s +# endif +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define Z_LARGE +#endif + +#if (defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)) && !defined(Z_SOLO) +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && (defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0) +# define z_off64_t off64_t +#else +# if defined(_WIN32) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +#endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.3 b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.3 new file mode 100644 index 00000000..d051c79b --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.3 @@ -0,0 +1,151 @@ +.TH ZLIB 3 "29 Jan 2012" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe, assuming that the standard library functions +used are thread safe, such as memory allocation routines. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms may be added later +with the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.IR gzip (1) +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. +The decoder checks the consistency of the compressed data, +so the library should never crash even in the case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h . +The distribution source includes examples of use of the library +in the files +.I test/example.c +and +.IR test/minigzip.c, +as well as other examples in the +.IR examples/ +directory. +.LP +Changes to this version are documented in the file +.I ChangeLog +that accompanies the source. +.LP +.I zlib +is available in Java using the java.util.zip package: +.IP +http://java.sun.com/developer/technicalArticles/Programming/compression/ +.LP +A Perl interface to +.IR zlib , +written by Paul Marquess (pmqs@cpan.org), +is available at CPAN (Comprehensive Perl Archive Network) sites, +including: +.IP +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ +.LP +A Python interface to +.IR zlib , +written by A.M. Kuchling (amk@magnet.com), +is available in Python 1.5 and later versions: +.IP +http://docs.python.org/library/zlib.html +.LP +.I zlib +is built into +.IR tcl: +.IP +http://wiki.tcl.tk/4610 +.LP +An experimental package to read and write files in .zip format, +written on top of +.I zlib +by Gilles Vollant (info@winimage.com), +is available at: +.IP +http://www.winimage.com/zLibDll/minizip.html +and also in the +.I contrib/minizip +directory of the main +.I zlib +source distribution. +.SH "SEE ALSO" +The +.I zlib +web site can be found at: +.IP +http://zlib.net/ +.LP +The data format used by the zlib library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) +.br +http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) +.br +http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) +.LP +Mark Nelson wrote an article about +.I zlib +for the Jan. 1997 issue of Dr. Dobb's Journal; +a copy of the article is available at: +.IP +http://marknelson.us/1997/01/01/zlib-engine/ +.SH "REPORTING PROBLEMS" +Before reporting a problem, +please check the +.I zlib +web site to verify that you have the latest version of +.IR zlib ; +otherwise, +obtain the latest version and see if the problem still exists. +Please read the +.I zlib +FAQ at: +.IP +http://zlib.net/zlib_faq.html +.LP +before asking for help. +Send questions and/or comments to zlib@gzip.org, +or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). +.SH AUTHORS +Version 1.2.6 +Copyright (C) 1995-2012 Jean-loup Gailly (jloup@gzip.org) +and Mark Adler (madler@alumni.caltech.edu). +.LP +This software is provided "as-is," +without any express or implied warranty. +In no event will the authors be held liable for any damages +arising from the use of this software. +See the distribution directory with respect to requirements +governing redistribution. +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.3.pdf b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.3.pdf new file mode 100644 index 00000000..ffa2a78a Binary files /dev/null and b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.3.pdf differ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.h new file mode 100644 index 00000000..79142d11 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.h @@ -0,0 +1,1732 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.6, January 29th, 2012 + + Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.6" +#define ZLIB_VERNUM 0x1260 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 6 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is not required to perform an + inflation in one step. However it may be used to inform inflate that a + faster approach can be used for the single inflate() call. Z_FINISH also + informs inflate to not maintain a sliding window if the stream completes, + which reduces inflate's memory footprint. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); +#define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc_(g)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#ifndef Z_SOLO + ZEXTERN unsigned long ZEXPORT gzflags OF((void)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.map b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.map new file mode 100644 index 00000000..54fa5538 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.map @@ -0,0 +1,79 @@ +ZLIB_1.2.0 { + global: + compressBound; + deflateBound; + inflateBack; + inflateBackEnd; + inflateBackInit_; + inflateCopy; + local: + deflate_copyright; + inflate_copyright; + inflate_fast; + inflate_table; + zcalloc; + zcfree; + z_errmsg; + gz_error; + gz_intmax; + _*; +}; + +ZLIB_1.2.0.2 { + gzclearerr; + gzungetc; + zlibCompileFlags; +} ZLIB_1.2.0; + +ZLIB_1.2.0.8 { + deflatePrime; +} ZLIB_1.2.0.2; + +ZLIB_1.2.2 { + adler32_combine; + crc32_combine; + deflateSetHeader; + inflateGetHeader; +} ZLIB_1.2.0.8; + +ZLIB_1.2.2.3 { + deflateTune; + gzdirect; +} ZLIB_1.2.2; + +ZLIB_1.2.2.4 { + inflatePrime; +} ZLIB_1.2.2.3; + +ZLIB_1.2.3.3 { + adler32_combine64; + crc32_combine64; + gzopen64; + gzseek64; + gztell64; + inflateUndermine; +} ZLIB_1.2.2.4; + +ZLIB_1.2.3.4 { + inflateReset2; + inflateMark; +} ZLIB_1.2.3.3; + +ZLIB_1.2.3.5 { + gzbuffer; + gzoffset; + gzoffset64; + gzclose_r; + gzclose_w; +} ZLIB_1.2.3.4; + +ZLIB_1.2.5.1 { + deflatePending; +} ZLIB_1.2.3.5; + +ZLIB_1.2.5.2 { + deflateResetKeep; + gzflags; + gzgetc_; + inflateResetKeep; +} ZLIB_1.2.5.1; diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.pc.in b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.pc.in new file mode 100644 index 00000000..7e5acf9c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +sharedlibdir=@sharedlibdir@ +includedir=@includedir@ + +Name: zlib +Description: zlib compression library +Version: @VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz +Cflags: -I${includedir} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib2ansi b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib2ansi new file mode 100644 index 00000000..15e3e165 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zlib2ansi @@ -0,0 +1,152 @@ +#!/usr/bin/perl + +# Transform K&R C function definitions into ANSI equivalent. +# +# Author: Paul Marquess +# Version: 1.0 +# Date: 3 October 2006 + +# TODO +# +# Asumes no function pointer parameters. unless they are typedefed. +# Assumes no literal strings that look like function definitions +# Assumes functions start at the beginning of a line + +use strict; +use warnings; + +local $/; +$_ = <>; + +my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments + +my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ; +my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ; +my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ; + + +while (s/^ + ( # Start $1 + ( # Start $2 + .*? # Minimal eat content + ( ^ \w [\w\s\*]+ ) # $3 -- function name + \s* # optional whitespace + ) # $2 - Matched up to before parameter list + + \( \s* # Literal "(" + optional whitespace + ( [^\)]+ ) # $4 - one or more anythings except ")" + \s* \) # optional whitespace surrounding a Literal ")" + + ( (?: $dList )+ ) # $5 + + $sp ^ { # literal "{" at start of line + ) # Remember to $1 + //xsom + ) +{ + my $all = $1 ; + my $prefix = $2; + my $param_list = $4 ; + my $params = $5; + + StripComments($params); + StripComments($param_list); + $param_list =~ s/^\s+//; + $param_list =~ s/\s+$//; + + my $i = 0 ; + my %pList = map { $_ => $i++ } + split /\s*,\s*/, $param_list; + my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ; + + my @params = split /\s*;\s*/, $params; + my @outParams = (); + foreach my $p (@params) + { + if ($p =~ /,/) + { + my @bits = split /\s*,\s*/, $p; + my $first = shift @bits; + $first =~ s/^\s*//; + push @outParams, $first; + $first =~ /^(\w+\s*)/; + my $type = $1 ; + push @outParams, map { $type . $_ } @bits; + } + else + { + $p =~ s/^\s+//; + push @outParams, $p; + } + } + + + my %tmp = map { /$pMatch/; $_ => $pList{$1} } + @outParams ; + + @outParams = map { " $_" } + sort { $tmp{$a} <=> $tmp{$b} } + @outParams ; + + print $prefix ; + print "(\n" . join(",\n", @outParams) . ")\n"; + print "{" ; + +} + +# Output any trailing code. +print ; +exit 0; + + +sub StripComments +{ + + no warnings; + + # Strip C & C++ coments + # From the perlfaq + $_[0] =~ + + s{ + /\* ## Start of /* ... */ comment + [^*]*\*+ ## Non-* followed by 1-or-more *'s + ( + [^/*][^*]*\*+ + )* ## 0-or-more things which don't start with / + ## but do end with '*' + / ## End of /* ... */ comment + + | ## OR C++ Comment + // ## Start of C++ comment // + [^\n]* ## followed by 0-or-more non end of line characters + + | ## OR various things which aren't comments: + + ( + " ## Start of " ... " string + ( + \\. ## Escaped char + | ## OR + [^"\\] ## Non "\ + )* + " ## End of " ... " string + + | ## OR + + ' ## Start of ' ... ' string + ( + \\. ## Escaped char + | ## OR + [^'\\] ## Non '\ + )* + ' ## End of ' ... ' string + + | ## OR + + . ## Anything other char + [^/"'\\]* ## Chars which doesn't start a comment, string or escape + ) + }{$2}gxs; + +} diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zutil.c b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zutil.c new file mode 100644 index 00000000..8a1d2420 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zutil.c @@ -0,0 +1,301 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010, 2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef Z_SOLO + return flags; +#else + return flags + gzflags(); +#endif +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zutil.h b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zutil.h new file mode 100644 index 00000000..dff1112f --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/FMUSolution/zlib-1.2.6/zutil.h @@ -0,0 +1,248 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/dev-jkauttio/org.simantics.fmu/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.fmu/META-INF/MANIFEST.MF new file mode 100644 index 00000000..21efdee9 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: FMU Simulator +Bundle-SymbolicName: org.simantics.fmu +Bundle-Version: 1.1.0.qualifier +Bundle-Activator: org.simantics.fmu.Activator +Bundle-Vendor: Semantum Oy +Require-Bundle: org.eclipse.core.runtime, + org.simantics.utils;bundle-version="1.1.0", + org.simantics;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: org.simantics.fmu diff --git a/dev-jkauttio/org.simantics.fmu/build.properties b/dev-jkauttio/org.simantics.fmu/build.properties new file mode 100644 index 00000000..41eb6ade --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/dev-jkauttio/org.simantics.fmu/src/org/simantics/fmu/Activator.java b/dev-jkauttio/org.simantics.fmu/src/org/simantics/fmu/Activator.java new file mode 100644 index 00000000..d93e3c55 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/src/org/simantics/fmu/Activator.java @@ -0,0 +1,30 @@ +package org.simantics.fmu; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/dev-jkauttio/org.simantics.fmu/src/org/simantics/fmu/FMUControlJNI.java b/dev-jkauttio/org.simantics.fmu/src/org/simantics/fmu/FMUControlJNI.java new file mode 100644 index 00000000..0ea50c2d --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/src/org/simantics/fmu/FMUControlJNI.java @@ -0,0 +1,688 @@ +package org.simantics.fmu; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.util.UUID; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.simantics.Simantics; +import org.simantics.utils.FileUtils; + + +public class FMUControlJNI { + + /** + * Static variables + */ + private static int ERROR = 0; + private static int OK = 1; + private static String UNSATISFIED_LINK = "Method not found. DLL might not be loaded properly."; + private static String TEMP_FMU_DIRECTORY_NAME = "fmu"; + public static String TEMP_FMU_COMMON_DIRECTORY; + public static String LOCK_FILE_NAME = "fmu.lock"; + + public static Object syncObject = new Object(); + + /** + * Static: load native libraries required for the FMU simulation to work. + */ + static { + File[] libraries = new File[3]; + + Bundle bundle = Platform.getBundle("org.simantics.fmu.me.win32"); + + if (bundle != null) { + try{ + String root = FileLocator.getBundleFile(bundle).getAbsolutePath(); + libraries[0] = new File(root, "libraries/zlibwapi.dll"); + libraries[1] = new File(root, "libraries/miniunz.dll"); + libraries[2] = new File(root, "libraries/FMUSimulator.dll"); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + for(File library : libraries) { + if(library == null) { + System.err.println("FMU library not loaded. FMU simulation not working."); + continue; + } else if(!library.isFile()) { + System.err.println(library.getAbsolutePath() + " not found"); + } else { + try { + System.load(library.getAbsolutePath()); + } catch (Throwable t) { + System.err.println(t.getMessage()); + } + } + } + } + + /** + * Static: initialize fmu temp folder + */ + static { + File dir = Simantics.getTemporaryDirectory(TEMP_FMU_DIRECTORY_NAME); + TEMP_FMU_COMMON_DIRECTORY = dir.getAbsolutePath(); + } + + + private String fmuDir; + + public String TEMP_FOLDER_1; + public String TEMP_FOLDER_2; + public String TEMP_FMU_DIRECTORY; + private String dirName; + + public FMUControlJNI() { + // Create a directory for this control + File tempDir = new File(TEMP_FMU_COMMON_DIRECTORY, UUID.randomUUID().toString()); + tempDir.mkdir(); + TEMP_FMU_DIRECTORY = tempDir.getAbsolutePath(); + + // Create two directories inside the temp directory for this control + dirName = UUID.randomUUID().toString(); + File fmuDir = new File(TEMP_FMU_DIRECTORY, dirName); + fmuDir.mkdir(); + + TEMP_FOLDER_1 = fmuDir.toString(); + TEMP_FOLDER_2 = fmuDir.toString() + "_2"; + + // Lock fmu directory in temp directory + lockFMUDirectory(); + } + + public String getModelID() { + return dirName; + } + + public String getFmuDir() { + return fmuDir; + } + + /** + * Load fmu from a given file path. Releases the (possible) previously + * loaded fmu. + * + * @param path absolute file path for fmu file + * @throws FMUJNIException + */ + private int fmuN = 0; + private boolean fmuLoaded = false; + public void loadFMUFile(String path) throws FMUJNIException { + + synchronized(syncObject) { + + if(fmuN % 2 == 0) { + fmuDir = TEMP_FOLDER_1; + fmuN++; + } else { + fmuDir = TEMP_FOLDER_2; + fmuN = 0; + } + + File tempDir = new File(fmuDir); + if(tempDir.isDirectory()) { + try { + FileUtils.deleteAll(tempDir); + } catch (IOException e) { + throw new FMUJNIException("Could not create temp folder for fmu"); + } + tempDir.mkdir(); + } else { + tempDir.mkdir(); + } + + + try { + String tmpPath = tempDir.getAbsolutePath(); + if(!tmpPath.endsWith("\\")) + tmpPath = tmpPath + "\\"; + int ret = loadFMUFile_(getModelID(), path, tmpPath); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + fmuLoaded = true; + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native int loadFMUFile_(String id, String path, String toDir); + + /** + * Set a step length for simulation + * + * @param step Step length for simulation + * @throws FMUJNIException + */ + public void setStepLength(double step) throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = setStepLength_(getModelID(), step); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native int setStepLength_(String id, double step); + + /** + * Instantiates a simulation. + *

+ * Make sure that an FMU is loaded first. + * @throws FMUJNIException + */ + public void instantiateSimulation() throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = instantiateSimulation_(getModelID()); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native int instantiateSimulation_(String id); + + + /** + * Initializes a simulation. + *

+ * Make sure that simulation is instantiated first! + * @throws FMUJNIException + */ + public void initializeSimulation() throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = initializeSimulation_(getModelID()); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native int initializeSimulation_(String id); + + /** + * Subscribe a set of variables from a loaded simulation. + *

+ * Make sure that an FMU is loaded first. + * @param variables Array of variables + * @throws FMUJNIException + */ + public void subscribe(String[] variables) throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = subscribe_(getModelID(), variables, variables.length); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native int subscribe_(String id, String[] variables, int size); + + + /** + * Set a new (Real, double) value for a variable. If the variable is a + * parameter, the change is effective immediately. + * + * @param name Variable + * @param value New (Real, double) value + * @throws FMUJNIException + */ + public void setRealValue(String name, double value) throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = setRealValue_(getModelID(), name, value); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native int setRealValue_(String id, String name, double value); + + /** + * Set a new (integer) value for a variable. If the variable is a + * parameter, the change is effective immediately. + * + * @param name Variable + * @param value New (integer) value + * @throws FMUJNIException + */ + public void setIntegerValue(String name, int value) throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = setIntegerValue_(getModelID(), name, value); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + private native int setIntegerValue_(String id, String name, int value); + + /** + * Set a new (boolean) value for a variable. If the variable is a + * parameter, the change is effective immediately. + * + * @param name Variable + * @param value New (boolean) value + * @throws FMUJNIException + */ + public void setBooleanValue(String name, boolean value) throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = setBooleanValue_(getModelID(), name, value); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + private native int setBooleanValue_(String id, String name, boolean value); + + public void setTime(double time) throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = setTime_(getModelID(), time); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + private native int setTime_(String id, double time); + + /** + * Simulate one step forward. The step length can be set with + * setStepLength() + * + * @throws FMUJNIException + */ + public void simulateStep() throws FMUJNIException { + synchronized(syncObject) { + + try { + + int ret = simulateStep_(getModelID()); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + private native int simulateStep_(String id); + + /** + * Get an array containing the current values for subscribed variables. The + * values are in the same order as in the subscription. + * + * @param results An array the size of subscribed results + * @return + */ + public double[] getSubscribedResults(double[] results) throws FMUJNIException { + synchronized(syncObject) { + + try { + + return getSubscribedResults_(getModelID(), results); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native double[] getSubscribedResults_(String id, double[] results); + + /** + * Unload FMU and the dll:s that it requires. + *

+ * To be called after all FMU simulations are ended. + * If the fmu is loaded again / changed, call to loadFMUFile is sufficient. loadFMUFile + * releases the previous fmu.dll + * + * @throws FMUJNIException + */ + public void unloadFMU() throws FMUJNIException { + synchronized(syncObject) { + + try { + + unlockFMUDirectory(); + if(fmuLoaded) { + int ret = unloadFMU_(getModelID()); + if(ret == ERROR) + throw new FMUJNIException(getLastErrorMessage()); + } + removeFMUDirectoryContents(); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + private native int unloadFMU_(String id); + + /** + * Checks if fmu has been initialized + * @return current simulation time + */ + public boolean isInitialized() throws FMUJNIException { + synchronized(syncObject) { + try { + return isInitialized_(getModelID()); + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native boolean isInitialized_(String id); + + /** + * Get the current simulation time + * @return current simulation time + */ + public double getTime() throws FMUJNIException { + synchronized(syncObject) { + + try { + + return getTime_(getModelID()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native double getTime_(String id); + + /** + * Get all variables in a loaded model + * @return all variables in a loaded model + */ + public String[] getAllVariables() throws FMUJNIException { + synchronized(syncObject) { + + try { + + return getAllVariables_(getModelID()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native String[] getAllVariables_(String id); + + /** + * Get all variables from model that match the filter (and time variable) + * + * @param regexp Regular expression filter + * @return An array of variable names that match regexp filter (and time-variable) + * @throws FMUJNIException + */ + public String[] filterVariables(String regexp) throws FMUJNIException { + synchronized(syncObject) { + try { + + return filterVariables_(getModelID(), regexp + "|time"); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native String[] filterVariables_(String id, String regexp); + + /** + * Get the last error message + * @return Last error message + */ + public String getLastErrorMessage() throws FMUJNIException { + synchronized(syncObject) { + + try { + + return getLastErrorMessage_(getModelID()); + + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native String getLastErrorMessage_(String id); + + /** + * Get a real (double) value for variable + * @param name Name of the variable + * @return value + * @throws FMUJNIException + */ + public double getRealValue(String name) throws FMUJNIException { + synchronized(syncObject) { + + try { + // TODO: printtaa id ja name, jotta saadaan virheessä kiinni + return getRealValue_(getModelID(), name); + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native double getRealValue_(String id, String name); + + /** + * Get a string value for variable + * @param name Name of the variable + * @return value + * @throws FMUJNIException + */ + public String getStringValue(String name) throws FMUJNIException { + synchronized(syncObject) { + + try { + return getStringValue_(getModelID(), name); + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native String getStringValue_(String id, String name); + + /** + * Get an integer value for variable + * @param name Name of the variable + * @return value + * @throws FMUJNIException + */ + public int getIntegerValue(String name) throws FMUJNIException { + synchronized(syncObject) { + + try { + return getIntegerValue_(getModelID(), name); + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native int getIntegerValue_(String id, String name); + + /** + * Get a real (double) value for variable + * @param name Name of the variable + * @return value + * @throws FMUJNIException + */ + public boolean getBooleanValue(String name) throws FMUJNIException { + synchronized(syncObject) { + + try { + return getBooleanValue_(getModelID(), name); + } catch (UnsatisfiedLinkError err) { + throw new FMUJNIException(UNSATISFIED_LINK); + } catch (Exception e) { + throw new FMUJNIException(e.getMessage()); + } + } + } + + private native boolean getBooleanValue_(String id, String name); + + private FileChannel channel; + private FileLock lock; + + @SuppressWarnings("resource") + private boolean lockFMUDirectory() { + + try { + // Get a file channel for the lock file + File lockFile = new File(TEMP_FMU_DIRECTORY, LOCK_FILE_NAME); + if(!lockFile.isFile()) + lockFile.createNewFile(); + + channel = new RandomAccessFile(lockFile, "rw").getChannel(); + + // Use the file channel to create a lock on the file. + // This method blocks until it can retrieve the lock. + lock = channel.lock(); + + // // Try acquiring the lock without blocking. This method returns + // // null or throws an exception if the file is already locked. + // try { + // lock = channel.tryLock(); + // } catch (OverlappingFileLockException e) { + // // File is already locked in this thread or virtual machine + // } + } catch (IOException e) { + return false; + } + + return true; + } + + private boolean unlockFMUDirectory() { + try { + // Release the lock + if(lock != null) + lock.release(); + + // Close the file + if(channel != null) + channel.close(); + } catch (IOException e) { + return false; + } + return true; + } + + private boolean removeFMUDirectoryContents() { + // Remove contents + try { + File tempDir = new File(TEMP_FMU_DIRECTORY); + FileUtils.deleteAll(tempDir); + tempDir.delete(); + } catch (IOException e) { + return false; + } + return true; + } +} diff --git a/dev-jkauttio/org.simantics.fmu/src/org/simantics/fmu/FMUJNIException.java b/dev-jkauttio/org.simantics.fmu/src/org/simantics/fmu/FMUJNIException.java new file mode 100644 index 00000000..b781bd9c --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/src/org/simantics/fmu/FMUJNIException.java @@ -0,0 +1,14 @@ +package org.simantics.fmu; + +/** + * Exception thrown when native fmu calls fail + * @author Teemu Lempinen + * + */ +public class FMUJNIException extends Exception { + private static final long serialVersionUID = -7164064752664568008L; + + public FMUJNIException(String message) { + super(message); + } +} diff --git a/dev-jkauttio/org.simantics.fmu/src/org_simantics_fmu_FMUControlJNI.h b/dev-jkauttio/org.simantics.fmu/src/org_simantics_fmu_FMUControlJNI.h new file mode 100644 index 00000000..20599879 --- /dev/null +++ b/dev-jkauttio/org.simantics.fmu/src/org_simantics_fmu_FMUControlJNI.h @@ -0,0 +1,181 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_simantics_fmu_FMUControlJNI */ + +#ifndef _Included_org_simantics_fmu_FMUControlJNI +#define _Included_org_simantics_fmu_FMUControlJNI +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: loadFMUFile_ + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_loadFMUFile_1 + (JNIEnv *, jobject, jstring, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setStepLength_ + * Signature: (Ljava/lang/String;D)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setStepLength_1 + (JNIEnv *, jobject, jstring, jdouble); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: instantiateSimulation_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_instantiateSimulation_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: initializeSimulation_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_initializeSimulation_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: subscribe_ + * Signature: (Ljava/lang/String;[Ljava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_subscribe_1 + (JNIEnv *, jobject, jstring, jobjectArray, jint); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setRealValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;D)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setRealValue_1 + (JNIEnv *, jobject, jstring, jstring, jdouble); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setIntegerValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setIntegerValue_1 + (JNIEnv *, jobject, jstring, jstring, jint); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setBooleanValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;Z)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setBooleanValue_1 + (JNIEnv *, jobject, jstring, jstring, jboolean); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: setTime_ + * Signature: (Ljava/lang/String;D)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_setTime_1 + (JNIEnv *, jobject, jstring, jdouble); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: simulateStep_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_simulateStep_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getSubscribedResults_ + * Signature: (Ljava/lang/String;[D)[D + */ +JNIEXPORT jdoubleArray JNICALL Java_org_simantics_fmu_FMUControlJNI_getSubscribedResults_1 + (JNIEnv *, jobject, jstring, jdoubleArray); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: unloadFMU_ + * Signature: (Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_unloadFMU_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: isInitialized_ + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_simantics_fmu_FMUControlJNI_isInitialized_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getTime_ + * Signature: (Ljava/lang/String;)D + */ +JNIEXPORT jdouble JNICALL Java_org_simantics_fmu_FMUControlJNI_getTime_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getAllVariables_ + * Signature: (Ljava/lang/String;)[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmu_FMUControlJNI_getAllVariables_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: filterVariables_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_org_simantics_fmu_FMUControlJNI_filterVariables_1 + (JNIEnv *, jobject, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getLastErrorMessage_ + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_simantics_fmu_FMUControlJNI_getLastErrorMessage_1 + (JNIEnv *, jobject, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getRealValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)D + */ +JNIEXPORT jdouble JNICALL Java_org_simantics_fmu_FMUControlJNI_getRealValue_1 + (JNIEnv *, jobject, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getStringValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_simantics_fmu_FMUControlJNI_getStringValue_1 + (JNIEnv *, jobject, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getIntegerValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_simantics_fmu_FMUControlJNI_getIntegerValue_1 + (JNIEnv *, jobject, jstring, jstring); + +/* + * Class: org_simantics_fmu_FMUControlJNI + * Method: getBooleanValue_ + * Signature: (Ljava/lang/String;Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_simantics_fmu_FMUControlJNI_getBooleanValue_1 + (JNIEnv *, jobject, jstring, jstring); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/dev-jkauttio/org.simantics.h2d/.classpath b/dev-jkauttio/org.simantics.h2d/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.h2d/.hgignore b/dev-jkauttio/org.simantics.h2d/.hgignore new file mode 100644 index 00000000..73df90f6 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/.hgignore @@ -0,0 +1,5 @@ +syntax: regexp +^bin/ + +syntax: glob +*.svn/* \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.h2d/.project b/dev-jkauttio/org.simantics.h2d/.project new file mode 100644 index 00000000..e91c226c --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/.project @@ -0,0 +1,28 @@ + + + org.simantics.h2d + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.h2d/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.h2d/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..aa42399f --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Sun Nov 08 17:02:25 EET 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.h2d/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.h2d/META-INF/MANIFEST.MF new file mode 100644 index 00000000..4dbd46e4 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/META-INF/MANIFEST.MF @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: H2d +Bundle-SymbolicName: org.simantics.h2d +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Require-Bundle: org.simantics.scenegraph;bundle-version="0.9.0", + gnu.trove2;bundle-version="2.0.4", + org.simantics.objmap;bundle-version="0.1.0" +Export-Package: org.simantics.h2d.action, + org.simantics.h2d.canvas, + org.simantics.h2d.diagram, + org.simantics.h2d.editor, + org.simantics.h2d.editor.impl, + org.simantics.h2d.element, + org.simantics.h2d.element.handler, + org.simantics.h2d.event, + org.simantics.h2d.event.handler, + org.simantics.h2d.node diff --git a/dev-jkauttio/org.simantics.h2d/build.properties b/dev-jkauttio/org.simantics.h2d/build.properties new file mode 100644 index 00000000..efa0dd21 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/build.properties @@ -0,0 +1,16 @@ +############################################################################### +# Copyright (c) 2007, 2010 Association for Decentralized Information Management +# in Industry THTH ry. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# VTT Technical Research Centre of Finland - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . +src.includes = doc/ diff --git a/dev-jkauttio/org.simantics.h2d/doc/manual.mediawiki b/dev-jkauttio/org.simantics.h2d/doc/manual.mediawiki new file mode 100644 index 00000000..e69de29b diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/action/IAction.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/action/IAction.java new file mode 100644 index 00000000..2e049846 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/action/IAction.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.action; + +import org.simantics.h2d.event.handler.IEventHandler; +import org.simantics.scenegraph.g2d.G2DParentNode; + +/** + * Action is a non-instantenous user operation on diagram. + * @see org.simantics.h2d.editor.IDiagramEditor#addAction + * @author Hannu Niemistö + */ +public interface IAction extends IEventHandler { + void init(G2DParentNode parent); + void remove(); +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/canvas/EditorCanvas.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/canvas/EditorCanvas.java new file mode 100644 index 00000000..0d0fdab9 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/canvas/EditorCanvas.java @@ -0,0 +1,251 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.canvas; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.geom.Point2D; +import java.awt.image.VolatileImage; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.event.ClickEvent; +import org.simantics.h2d.event.DragEvent; +import org.simantics.h2d.event.DragEventPhase; +import org.simantics.h2d.event.KeyboardEvent; +import org.simantics.h2d.event.Modifiers; +import org.simantics.h2d.event.ReleaseEvent; +import org.simantics.h2d.event.WheelEvent; +import org.simantics.scenegraph.g2d.G2DRenderingHints; + + +public class EditorCanvas extends Canvas { + + private static final long serialVersionUID = -387207508390377519L; + + IDiagramEditor editor; + EventHandler eventHandler = new EventHandler(); + //BufferedImage background; + + public EditorCanvas(IDiagramEditor editor) { + this.editor = editor; + editor.setCanvas(this); + + /*G2DSceneGraph sceneGraph = editor.getSceneGraph(); + addMouseListener(sceneGraph); + addMouseMotionListener(sceneGraph); + addMouseWheelListener(sceneGraph); + addKeyListener(sceneGraph); + */ + addMouseListener(eventHandler); + addMouseMotionListener(eventHandler); + addMouseWheelListener(eventHandler); + addKeyListener(eventHandler); + + addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + repaint(); + } + }); + + /*try { + background = ImageIO.read(new File("c:/paper.png")); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + }*/ + } + + @Override + public void update(Graphics g) { + paint(g); + } + + private VolatileImage doubleBuffer; + @Override + public void paint(Graphics _g) { + do { + if (doubleBuffer == null + || doubleBuffer.getWidth() != getWidth() + || doubleBuffer.getHeight() != getHeight() + || doubleBuffer.validate(getGraphicsConfiguration()) == VolatileImage.IMAGE_INCOMPATIBLE) + { + doubleBuffer = createVolatileImage(getWidth(), getHeight()); + editor.setViewDimensions(new Dimension(getWidth(), getHeight())); + } + + Graphics2D g = (Graphics2D)doubleBuffer.getGraphics(); + + g.setBackground(Color.WHITE); + g.setColor(Color.WHITE); + //g.setPaint(new GradientPaint(0.f, 0.f, Color.white, 2000.f, 1600.f, Color.BLUE, false)); + //g.setPaint(new TexturePaint(background, getBounds())); + g.fillRect(0, 0, doubleBuffer.getWidth(), doubleBuffer.getHeight()); + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + g.setRenderingHint(G2DRenderingHints.KEY_CONTROL_BOUNDS, getBounds()); + + g.setClip(0, 0, getWidth(), getHeight()); + + editor.getSceneGraph().render(g); + g.dispose(); + } while (doubleBuffer.contentsLost()); + + _g.drawImage(doubleBuffer, 0, 0, this); + } + + class EventHandler implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener { + + DragEvent dragEvent; + + @Override + public void mouseClicked(MouseEvent e) { + ClickEvent event = new ClickEvent( + Modifiers.modifierString(e.getButton(), e.isControlDown(), e.isAltDown(), e.isShiftDown()), + editor.screenToDiagram(e.getPoint()), + e.getLocationOnScreen() + ); + event.pickedElements = dragEvent.pickedElements; + editor.handleEvent(event); + } + + @Override + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) { + editor.getSceneGraph().mousePressed(e); + if(e.isConsumed()) + return; + dragEvent = new DragEvent( + Modifiers.modifierString(e.getButton(), e.isControlDown(), e.isAltDown(), e.isShiftDown()), + editor.screenToDiagram(e.getPoint()) + ); + dragEvent.pickedElements = editor.pickElements(dragEvent.start); + } + + @Override + public void mouseReleased(MouseEvent e) { + editor.getSceneGraph().mouseReleased(e); + if(e.isConsumed()) + return; + if(dragEvent != null && dragEvent.phase == DragEventPhase.dragUpdate) { + dragEvent.phase = DragEventPhase.dragEnd; + editor.handleEvent(dragEvent); + } + + if(dragEvent != null) { + ReleaseEvent event = new ReleaseEvent( + Modifiers.modifierString(e.getButton(), e.isControlDown(), e.isAltDown(), e.isShiftDown()), + editor.screenToDiagram(e.getPoint()), + e.getLocationOnScreen() + ); + + event.pickedElements = dragEvent.pickedElements; + editor.handleEvent(event); + } + } + + @Override + public void mouseDragged(MouseEvent e) { + editor.getSceneGraph().mouseDragged(e); + if(e.isConsumed()) + return; + currentPosition = e.getPoint(); + if(dragEvent != null) { // TODO why this is needed? + dragEvent.currentModifiers = + Modifiers.modifierString(e.getButton(), e.isControlDown(), e.isAltDown(), e.isShiftDown()); + dragEvent.current = editor.screenToDiagram(e.getPoint()); + } + editor.handleEvent(dragEvent); + + if(dragEvent != null && dragEvent.phase == DragEventPhase.dragBegin) { + dragEvent.phase = DragEventPhase.dragUpdate; + editor.handleEvent(dragEvent); + } + } + + Point2D currentPosition = new Point2D.Double(0.0, 0.0); + + @Override + public void mouseMoved(MouseEvent e) { + currentPosition = e.getPoint(); + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + editor.handleEvent(new WheelEvent( + Modifiers.modifierString(e.getButton(), e.isControlDown(), e.isAltDown(), e.isShiftDown()), + editor.screenToDiagram(e.getPoint()), + e.getWheelRotation() + )); + } + + @Override + public void keyPressed(KeyEvent e) { + editor.getSceneGraph().keyPressed(e); + if(e.isConsumed()) + return; + + String keyText = KeyEvent.getKeyText(e.getKeyCode()); + if(e.getModifiers() != 0) + keyText = KeyEvent.getKeyModifiersText(e.getModifiers()) + + "+" + keyText; + KeyboardEvent event = new KeyboardEvent( + keyText, + editor.screenToDiagram(currentPosition) + ); + event.pickedElements = editor.pickElements(event.point); + if(editor.handleEvent(event)) + e.consume(); + } + + @Override + public void keyReleased(KeyEvent e) { + editor.getSceneGraph().keyReleased(e); + } + + @Override + public void keyTyped(KeyEvent e) { + editor.getSceneGraph().keyTyped(e); + } + } + + public IDiagramEditor getEditor() { + return editor; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/diagram/Diagram.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/diagram/Diagram.java new file mode 100644 index 00000000..673a5be8 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/diagram/Diagram.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.diagram; + +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + +import org.simantics.h2d.element.IElement; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; + +@GraphType("http://www.simantics.org/Sysdyn-1.0/Configuration") +public class Diagram implements IDiagram { + + @RelatedValue("http://www.simantics.org/Layer0-1.0/ConsistsOf") + public List elements = new Vector(); + ArrayList listeners = new ArrayList(); + + @Override + public void addElement(IElement element) { + elements.add(element); + for(IDiagramListener listener : listeners) + listener.elementAdded(element); + } + + @Override + public List getElements() { + return elements; + } + + @Override + public void addDiagramListener(IDiagramListener listener) { + listeners.add(listener); + } + + @Override + public void removeElement(IElement element) { + elements.remove(element); + for(IDiagramListener listener : listeners) + listener.elementRemoved(element); + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/diagram/IDiagram.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/diagram/IDiagram.java new file mode 100644 index 00000000..8263651b --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/diagram/IDiagram.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.diagram; + +import java.util.List; + +import org.simantics.h2d.element.IElement; + +/** + * Diagram is the whole that is edited in a diagram editor. + * @author Hannu Niemistö + */ +public interface IDiagram { + List getElements(); + void addElement(IElement element); + void removeElement(IElement element); + void addDiagramListener(IDiagramListener listener); +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/diagram/IDiagramListener.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/diagram/IDiagramListener.java new file mode 100644 index 00000000..9f061e00 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/diagram/IDiagramListener.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.diagram; + +import org.simantics.h2d.element.IElement; + +public interface IDiagramListener { + + void elementAdded(IElement element); + void elementRemoved(IElement element); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/IDiagramEditor.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/IDiagramEditor.java new file mode 100644 index 00000000..987f400f --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/IDiagramEditor.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.editor; + +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.geom.AffineTransform; +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.util.List; + +import org.simantics.h2d.action.IAction; +import org.simantics.h2d.diagram.IDiagram; +import org.simantics.h2d.element.IElement; +import org.simantics.h2d.event.IEvent; +import org.simantics.h2d.event.handler.IEventHandler; +import org.simantics.scenegraph.g2d.G2DSceneGraph; + +public interface IDiagramEditor { + + IDiagram getDiagram(); + + /** + * Returns the root of the scenegraph that renders the diagram. + */ + G2DSceneGraph getSceneGraph(); + + /** + * Handles an external event. + * @return True if the event was consumed. + */ + boolean handleEvent(IEvent event); + + /** + * Returns the current view transform (from diagram coordinates to screen coordinates) defined as: + *

diagramToScreen(p) = (p - offset) / scale
+ */ + AffineTransform getViewTransform(); + + /** + * Returns the current view offset. That is the diagram coordinates of the top left point of the canvas. + */ + Point2D getOffset(); + + /** + * Returns the current view scale. That is
lengthInDiagramCoordinates / lengthInScreenCoordinates
. + */ + double getScale(); + + /** + * Maps a point from screen coordinates to diagram coordinates. + */ + Point2D screenToDiagram(Point2D point); + + /** + * Sets a new view transform. + * @param offset New offset + * @param scale New scale + * + * @see #getOffset + * @see #getScale + */ + void setViewTransform(Point2D offset, double scale); + + void setViewDimensions(Dimension2D dimension); + Dimension getViewDimension(); + + // Events + void addEventHandler(int priority, String eventType, IEventHandler handler); + void addEventHandler(int priority, IEventHandler handler); + + void addAction(IAction action); + void removeAction(IAction action); + + void requestRepaint(); + void setCanvas(Canvas canvas); + + /** + * Returns current selection + */ + ISelection getSelection(); + + /** + * Returns all elements at the point. Pick uses a hard coded tolerance that is calculated in screen coordinates. + */ + List pickElements(Point2D point); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/ISelection.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/ISelection.java new file mode 100644 index 00000000..f4f1426c --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/ISelection.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.editor; + +import java.util.Collection; + +import org.simantics.h2d.element.IElement; + +public interface ISelection extends Iterable { + + boolean contains(IElement el); + boolean containsOneOf(Collection els); + void clear(); + void set(Collection els); + void set(IElement el); + boolean add(IElement el); + boolean addAll(Collection els); + boolean toggle(IElement el); + boolean remove(IElement el); + boolean isEmpty(); + int size(); + IElement getSingleElement(); + + void addSelectionListener(ISelectionListener listener); + void removeSelectionListener(ISelectionListener listener); + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/ISelectionListener.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/ISelectionListener.java new file mode 100644 index 00000000..3e6fe056 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/ISelectionListener.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.editor; + +public interface ISelectionListener { + + void selectionChanged(ISelection selection); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/DiagramEditor.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/DiagramEditor.java new file mode 100644 index 00000000..172cf500 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/DiagramEditor.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.editor.impl; + +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.geom.AffineTransform; +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JComponent; + +import org.simantics.h2d.action.IAction; +import org.simantics.h2d.diagram.IDiagram; +import org.simantics.h2d.diagram.IDiagramListener; +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.editor.ISelection; +import org.simantics.h2d.element.IElement; +import org.simantics.h2d.event.IEvent; +import org.simantics.h2d.event.handler.IEventHandler; +import org.simantics.scenegraph.g2d.G2DSceneGraph; + +public class DiagramEditor implements IDiagramEditor { + + public static final double PICK_TOLERANCE = 5.0; + + IDiagram diagram; + + // Viewpoint + Point2D offset; + double scale; + AffineTransform viewTransform = new AffineTransform(); + Dimension dimension = new Dimension(800, 600); + + ISelection selection; + + ArrayList actionStack = new ArrayList(); + + SceneGraphManager sgManager; + EventHandlerManager eventHandlerManager = new EventHandlerManager(); + + Canvas canvas; + + public void setCanvas(Canvas canvas) { + this.canvas = canvas; + } + + public DiagramEditor(JComponent rootPane, IDiagram diagram) { + this.diagram = diagram; + sgManager = new SceneGraphManager(rootPane); + + setViewTransform(new Point2D.Double(), 13.0 / 48.0); + sgManager.setViewTransform(viewTransform); + + selection = new Selection(sgManager.selectionNode); + + for(IElement element : diagram.getElements()) + element.init(sgManager.elementsNode); + diagram.addDiagramListener(new IDiagramListener() { + + @Override + public void elementAdded(IElement element) { + element.init(sgManager.elementsNode); + } + + @Override + public void elementRemoved(IElement element) { + element.remove(); + } + + }); + } + + @Override + public G2DSceneGraph getSceneGraph() { + return sgManager.sceneGraph; + } + + @Override + public boolean handleEvent(IEvent event) { + for(int i=actionStack.size()-1;i>=0;--i) + if(actionStack.get(i).handle(this, event)) + return true; + return eventHandlerManager.handle(this, event); + } + + @Override + public void addEventHandler(int priority, String eventType, IEventHandler handler) { + eventHandlerManager.addEventHandler(priority, eventType, handler); + } + + @Override + public void addEventHandler(int priority, IEventHandler handler) { + eventHandlerManager.addEventHandler(priority, handler); + } + + @Override + public ISelection getSelection() { + return selection; + } + + @Override + public Point2D getOffset() { + return offset; + } + + @Override + public double getScale() { + return scale; + } + + @Override + public AffineTransform getViewTransform() { + return viewTransform; + } + + @Override + public void setViewTransform(Point2D offset, double scale) { + this.offset = offset; + this.scale = scale; + viewTransform.setTransform(1.0/scale, 0.0, 0.0, 1.0/scale, + -offset.getX()/scale, -offset.getY()/scale); + } + + @Override + public Point2D screenToDiagram(Point2D point) { + return new Point2D.Double(point.getX()*scale + offset.getX(), point.getY()*scale + offset.getY()); + } + + @Override + public IDiagram getDiagram() { + return diagram; + } + + @Override + public List pickElements(Point2D point) { + double tolerance = PICK_TOLERANCE*scale; + ArrayList result = new ArrayList(); + for(IElement element : getDiagram().getElements()) { + if(element.hitTest(point.getX(), point.getY(), tolerance)) + result.add(element); + } + return result; + } + + @Override + public void addAction(IAction action) { + actionStack.add(action); + action.init(sgManager.actionNode); + requestRepaint(); + } + + @Override + public void removeAction(IAction action) { + actionStack.remove(action); + action.remove(); + requestRepaint(); + } + + @Override + public Dimension getViewDimension() { + return dimension; + } + + @Override + public void setViewDimensions(Dimension2D dimension) { + this.dimension.setSize(dimension); + } + + @Override + public void requestRepaint() { + canvas.repaint(); + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/EventHandlerManager.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/EventHandlerManager.java new file mode 100644 index 00000000..76880963 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/EventHandlerManager.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.editor.impl; + +import gnu.trove.THashMap; + +import java.util.LinkedList; +import java.util.ListIterator; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.event.IEvent; +import org.simantics.h2d.event.handler.IEventHandler; + +class EventHandlerManager implements IEventHandler { + LinkedList handlers = new LinkedList(); + + public void addEventHandler(int priority, String eventType, IEventHandler handler) { + ListIterator it = handlers.listIterator(); + while(it.hasNext()) { + PrioritizedEventHandler group = it.next(); + if(group.priority == priority) + group.put(eventType, handler); + else if(group.priority < priority) { + it.previous(); + break; + } + } + + // Add a new level + MapEventHandler map = new MapEventHandler(priority); + map.put(eventType, handler); + it.add(map); + } + + public void addEventHandler(int priority, IEventHandler handler) { + ListIterator it = handlers.listIterator(); + while(it.hasNext()) { + PrioritizedEventHandler group = it.next(); + if(group.priority == priority) + throw new IllegalArgumentException("Tried add an event handler of type of priority " + priority + + ", but this conflicts with an event handler(s) with the same priority."); + else if(group.priority < priority) { + it.previous(); + break; + } + } + + // Add a new level + it.add(new SingletonEventHandler(priority, handler)); + } + + static abstract class PrioritizedEventHandler { + public final int priority; + + public PrioritizedEventHandler(int priority) { + this.priority = priority; + } + + public abstract void put(String type, IEventHandler handler); + public abstract boolean handle(String type, IDiagramEditor editor, IEvent event); + + } + + static class SingletonEventHandler extends PrioritizedEventHandler { + + IEventHandler handler; + + public SingletonEventHandler(int priority, IEventHandler handler) { + super(priority); + this.handler = handler; + } + + @Override + public boolean handle(String type, IDiagramEditor editor, IEvent event) { + return handler.handle(editor, event); + } + + @Override + public void put(String type, IEventHandler handler) { + throw new IllegalArgumentException("Tried add an event handler of type " + type + " and priority " + priority + + ", but this conflicts with an event handler with the same priority."); + } + + } + + static class MapEventHandler extends PrioritizedEventHandler { + + THashMap handlers = new THashMap(); + public MapEventHandler(int priority) { + super(priority); + } + + @Override + public void put(String type, IEventHandler handler) { + if(handlers.contains(type)) + throw new IllegalArgumentException("Tried add an event handler of type " + type + " and priority " + priority + + ", but this conflicts with an event handler with the same priority and type."); + handlers.put(type, handler); + } + + @Override + public boolean handle(String type, IDiagramEditor editor, IEvent event) { + IEventHandler handler = handlers.get(type); + return handler != null && handler.handle(editor, event); + } + + } + + @Override + public boolean handle(IDiagramEditor editor, IEvent event) { + String type = event.getType(); + for(PrioritizedEventHandler level : handlers) { + if(level.handle(type, editor, event)) + return true; + } + return false; + } +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/SceneGraphManager.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/SceneGraphManager.java new file mode 100644 index 00000000..cf207c7b --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/SceneGraphManager.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.editor.impl; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import javax.swing.JComponent; + +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.G2DSceneGraph; +import org.simantics.scenegraph.g2d.nodes.PageBorderNode; +import org.simantics.scenegraph.g2d.nodes.TransformNode; + +class SceneGraphManager { + G2DSceneGraph sceneGraph; + TransformNode diagramCoordinatesNode; + G2DParentNode elementsNode; + G2DParentNode selectionNode; + G2DParentNode actionNode; + + public SceneGraphManager(JComponent rootPane) { + sceneGraph = new G2DSceneGraph(); + //sceneGraph.setRootPane(rootPane); + diagramCoordinatesNode = sceneGraph.addNode(TransformNode.class); + + PageBorderNode border = diagramCoordinatesNode.addNode(PageBorderNode.class); + border.init(new Rectangle2D.Double(0.0, 0.0, 297.0, 210.0), new Rectangle2D.Double(10.0, 10.0, 277.0, 190.0), Boolean.TRUE); + + elementsNode = diagramCoordinatesNode.addNode(G2DParentNode.class); + elementsNode.setZIndex(0); + + selectionNode = diagramCoordinatesNode.addNode(G2DParentNode.class); + selectionNode.setZIndex(1); + + actionNode = diagramCoordinatesNode.addNode(G2DParentNode.class); + actionNode.setZIndex(2); + } + + void setViewTransform(AffineTransform viewTransform) { + diagramCoordinatesNode.setTransform(viewTransform); + } +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/Selection.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/Selection.java new file mode 100644 index 00000000..632d454a --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/editor/impl/Selection.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.editor.impl; + +import gnu.trove.THashSet; + +import java.awt.Color; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.simantics.h2d.editor.ISelection; +import org.simantics.h2d.editor.ISelectionListener; +import org.simantics.h2d.element.IElement; +import org.simantics.h2d.element.IElementListener; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.nodes.SelectionNode; + +class Selection implements ISelection { + static final AffineTransform IDENTITY = new AffineTransform(); + + THashSet elements = new THashSet(); + G2DParentNode selectionParentNode; + + CopyOnWriteArrayList listeners = + new CopyOnWriteArrayList(); + + static class SelectionUpdater implements IElementListener { + SelectionNode node; + IElement element; + + public SelectionUpdater(SelectionNode node, IElement element) { + this.node = node; + this.element = element; + + elementUpdated(element); + element.addListener(this); + } + + @Override + public void elementUpdated(IElement element) { + Rectangle2D bounds = new Rectangle2D.Double(); + element.getBounds(bounds); + node.init(IDENTITY, bounds, Color.GRAY); + } + + public void remove() { + element.removeListener(this); + } + + @Override + public void elementRemoved(IElement element) { + // TODO ? + } + + } + + ArrayList updaters = new ArrayList(); + + public Selection(G2DParentNode selectionParentNode) { + this.selectionParentNode = selectionParentNode; + } + + private void updateSceneGraph() { + // Clear old selection + selectionParentNode.removeNodes(); + for(SelectionUpdater updater : updaters) + updater.remove(); + updaters.clear(); + + // Create new selection + //System.out.println("selection: " + elements.size()); + for(IElement element : elements) + updaters.add(new SelectionUpdater(selectionParentNode.addNode(SelectionNode.class), element)); + + // Notify listeners + // TODO this is in wrong place + for(ISelectionListener listener : listeners) + listener.selectionChanged(this); + } + + public boolean contains(IElement el) { + return elements.contains(el); + } + + public boolean containsOneOf(Collection els) { + for(IElement el : els) + if(elements.contains(el)) + return true; + return false; + } + + public void clear() { + if(!elements.isEmpty()) { + elements.clear(); + updateSceneGraph(); + } + } + + public void set(Collection els) { + elements.clear(); + elements.addAll(els); + updateSceneGraph(); + } + + public void set(IElement el) { + elements.clear(); + elements.add(el); + updateSceneGraph(); + } + + public boolean add(IElement el) { + boolean result = elements.add(el); + updateSceneGraph(); + return result; + } + + public boolean addAll(Collection els) { + boolean result = elements.addAll(els); + updateSceneGraph(); + return result; + } + + public boolean toggle(IElement el) { + if(elements.contains(el)) { + elements.remove(el); + updateSceneGraph(); + return false; + } + else { + elements.add(el); + updateSceneGraph(); + return true; + } + } + + public boolean remove(IElement el) { + boolean result = elements.remove(el); + updateSceneGraph(); + return result; + } + + @Override + public Iterator iterator() { + return elements.iterator(); + } + + @Override + public boolean isEmpty() { + return elements.isEmpty(); + } + + @Override + public int size() { + return elements.size(); + } + + @Override + public IElement getSingleElement() { + for(IElement element : elements) + return element; + return null; + } + + @Override + public void addSelectionListener(ISelectionListener listener) { + listeners.add(listener); + } + + @Override + public void removeSelectionListener(ISelectionListener listener) { + listeners.remove(listener); + } +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/ChainingElementListener.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/ChainingElementListener.java new file mode 100644 index 00000000..ce5bc99e --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/ChainingElementListener.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.element; + + +class ChainingElementListener implements IElementListener { + IElementListener listener1; + IElementListener listener2; + + ChainingElementListener(IElementListener listener1, + IElementListener listener2) { + this.listener1 = listener1; + this.listener2 = listener2; + } + + @Override + public void elementUpdated(IElement element) { + listener1.elementUpdated(element); + listener2.elementUpdated(element); + } + + @Override + public void elementRemoved(IElement element) { + listener1.elementRemoved(element); + listener2.elementRemoved(element); + } + + static IElementListener addListener(IElementListener currentListener, IElementListener newListener) { + if(currentListener == null) + return newListener; + else + return new ChainingElementListener(currentListener, newListener); + } + + static IElementListener removeListener(IElementListener currentListener, IElementListener listenerToRemove) { + if(currentListener == null || currentListener == listenerToRemove) + return null; + else if(currentListener instanceof ChainingElementListener) { + ChainingElementListener chain = (ChainingElementListener)currentListener; + if(chain.listener2 == listenerToRemove) + return chain.listener1; + else { + IElementListener l = removeListener(chain.listener1, listenerToRemove); + if(l == null) + return chain.listener2; + chain.listener1 = l; + } + } + return currentListener; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/Element.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/Element.java new file mode 100644 index 00000000..96bc2250 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/Element.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.element; + + +public abstract class Element implements IElement { + + IElementListener listener; + + @SuppressWarnings("unchecked") + @Override + public T getInterface(Class clazz) { + if(clazz.isInstance(this)) + return (T) this; + return null; + } + + protected void fireElementUpdated() { + if(listener != null) + listener.elementUpdated(this); + } + + @Override + public void addListener(IElementListener listener) { + this.listener = ChainingElementListener.addListener(this.listener, listener); + } + + @Override + public void removeListener(IElementListener listener) { + this.listener = ChainingElementListener.removeListener(this.listener, listener); + } + + @Override + public void remove() { + if(listener != null) + listener.elementRemoved(this); + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/IElement.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/IElement.java new file mode 100644 index 00000000..5a2e39ac --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/IElement.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.element; + +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DParentNode; + +/** + * Element is a part of a diagram that has its own type and properties. + * @author Hannu Niemistö + */ +public interface IElement { + T getInterface(Class clazz); + + void init(G2DParentNode parent); + void remove(); + + /** + * Updates the parameter bounds so that it contains + * the bounding box of the element. + */ + void getBounds(Rectangle2D bounds); + + /** + * Returns true, if the interior of the element intersects + * a circle at (x,y) with radius tolerance. + * Returns false, if the element and a circle at (x,y) with + * radius sqrt(2)*tolerance are disjoint. Otherwise may return true + * or false depending on the implementation. + */ + boolean hitTest(double x, double y, double tolerance); + + void addListener(IElementListener listener); + void removeListener(IElementListener listener); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/IElementListener.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/IElementListener.java new file mode 100644 index 00000000..438629dd --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/IElementListener.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.element; + + +public interface IElementListener { + /** + * Called when the publicy available properties of the elements are changed. + * @param element + */ + public void elementUpdated(IElement element); + + public void elementRemoved(IElement element); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/Connectable.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/Connectable.java new file mode 100644 index 00000000..5d03f160 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/Connectable.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.element.handler; + +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.h2d.element.IElement; + + + +public interface Connectable extends IElementHandler, IElement { + + void getBounds(Rectangle2D bounds); + Point2D getOrigo(); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/IElementHandler.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/IElementHandler.java new file mode 100644 index 00000000..93c6a697 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/IElementHandler.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.element.handler; + +/** + * The base interface of all element handler interfaces. Needed only for + * documenting purposes. + * @author Hannu Niemistö + */ +public interface IElementHandler { +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/Movable.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/Movable.java new file mode 100644 index 00000000..e8722c73 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/Movable.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.element.handler; + + + +public interface Movable extends IElementHandler { + + /** + * Moves the element by the given delta. + */ + void move(double deltaX, double deltaY); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/Rotatable.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/Rotatable.java new file mode 100644 index 00000000..386a97d1 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/Rotatable.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.element.handler; + + + +public interface Rotatable extends IElementHandler { + + /** + * Rotates the element amount times 90 degrees clockwise. + */ + void rotate(int amount); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/ShadowDrawable.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/ShadowDrawable.java new file mode 100644 index 00000000..d9245a00 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/element/handler/ShadowDrawable.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.element.handler; + +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; + +public interface ShadowDrawable { + + /** + * Draws the shadow of the element. + */ + void draw(Graphics2D g, AffineTransform transform); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/ClickEvent.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/ClickEvent.java new file mode 100644 index 00000000..34957cd5 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/ClickEvent.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event; + +import java.awt.geom.Point2D; +import java.util.List; + +import org.simantics.h2d.element.IElement; + + +public class ClickEvent implements ILocatableEvent { + final public String modifiers; + + // Click location in diagram coordinates + final public Point2D point; + final public Point2D dispPoint; + + public List pickedElements; + + public ClickEvent(String modifiers, Point2D point, Point2D dispPoint) { + this.modifiers = modifiers; + this.dispPoint = dispPoint; + this.point = point; + } + + @Override + public String getType() { + return getType(modifiers); + } + + public static String getType(String modifiers) { + return "click(" + modifiers + ")"; + } + + @Override + public Point2D getLocation() { + return point; + } + + @Override + public List getPickedElements() { + return pickedElements; + } +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/DragEvent.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/DragEvent.java new file mode 100644 index 00000000..11bf28c5 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/DragEvent.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event; + +import java.awt.geom.Point2D; +import java.util.List; + +import org.simantics.h2d.element.IElement; + + +public class DragEvent implements ILocatableEvent { + public DragEventPhase phase; + + public String startModifiers; + public String currentModifiers; + + public Point2D start; + public Point2D current; + + public List pickedElements; + + public DragEvent(String startModifiers, Point2D start) { + this.phase = DragEventPhase.dragBegin; + this.startModifiers = startModifiers; + this.currentModifiers = startModifiers; + this.start = start; + this.current = start; + } + + @Override + public String getType() { + return getType(startModifiers); + } + + public static String getType(String modifiers) { + return "drag(" + modifiers + ")"; + } + + @Override + public Point2D getLocation() { + return start; + } + + @Override + public List getPickedElements() { + return pickedElements; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/DragEventPhase.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/DragEventPhase.java new file mode 100644 index 00000000..714c9ad3 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/DragEventPhase.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event; + +public enum DragEventPhase { + dragBegin, dragUpdate, dragEnd +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/IDragHandler.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/IDragHandler.java new file mode 100644 index 00000000..07ef210c --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/IDragHandler.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event; + +public interface IDragHandler { + public void handleMove(); + public void handleRelease(); +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/IEvent.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/IEvent.java new file mode 100644 index 00000000..fa29389b --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/IEvent.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event; + +public interface IEvent { + String getType(); +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/ILocatableEvent.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/ILocatableEvent.java new file mode 100644 index 00000000..cbb0330e --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/ILocatableEvent.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event; + +import java.awt.geom.Point2D; +import java.util.List; + +import org.simantics.h2d.element.IElement; + +public interface ILocatableEvent extends IEvent { + Point2D getLocation(); + List getPickedElements(); +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/KeyboardEvent.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/KeyboardEvent.java new file mode 100644 index 00000000..26a7cccc --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/KeyboardEvent.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event; + +import java.awt.geom.Point2D; +import java.util.List; + +import org.simantics.h2d.element.IElement; + + +public class KeyboardEvent implements ILocatableEvent { + final public String key; + + // Click location in diagram coordinates + final public Point2D point; + + public List pickedElements; + + + public KeyboardEvent(String key, Point2D point) { + this.key = key; + this.point = point; + } + + + @Override + public String getType() { + return getType(key); + } + + public static String getType(String key) { + return "key(" + key + ")"; + } + + @Override + public Point2D getLocation() { + return point; + } + + @Override + public List getPickedElements() { + return pickedElements; + } +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/Modifiers.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/Modifiers.java new file mode 100644 index 00000000..d6005e6b --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/Modifiers.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event; + +import java.awt.event.MouseEvent; + +public class Modifiers { + + public static String modifierString( + int button, + boolean ctrl, + boolean alt, + boolean shift + ) { + StringBuilder b = new StringBuilder(); + if(ctrl) + b.append("ctrl+"); + if(alt) + b.append("alt+"); + if(shift) + b.append("shift+"); + if(button == MouseEvent.BUTTON1) + b.append("left"); + else if(button == MouseEvent.BUTTON2) + b.append("middle"); + else if(button == MouseEvent.BUTTON3) + b.append("right"); + return b.toString(); + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/ReleaseEvent.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/ReleaseEvent.java new file mode 100644 index 00000000..c6d57de3 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/ReleaseEvent.java @@ -0,0 +1,42 @@ +package org.simantics.h2d.event; + +import java.awt.geom.Point2D; +import java.util.List; + +import org.simantics.h2d.element.IElement; + +public class ReleaseEvent implements ILocatableEvent { + final public String modifiers; + + // Release location in diagram coordinates + final public Point2D point; + final public Point2D dispPoint; + + public List pickedElements; + + public ReleaseEvent(String modifiers, Point2D point, Point2D dispPoint) { + this.modifiers = modifiers; + this.dispPoint = dispPoint; + this.point = point; + } + + @Override + public Point2D getLocation() { + return point; + } + + @Override + public List getPickedElements() { + return pickedElements; + } + + @Override + public String getType() { + return getType(modifiers); + } + + public static String getType(String modifiers) { + return "release(" + modifiers + ")"; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/WheelEvent.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/WheelEvent.java new file mode 100644 index 00000000..ee2de8a8 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/WheelEvent.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event; + +import java.awt.geom.Point2D; + + +public class WheelEvent implements IEvent { + final public String modifiers; + + // Click location in diagram coordinates + final public Point2D point; + + final public int amount; + + public WheelEvent(String modifiers, Point2D point, int amount) { + this.modifiers = modifiers; + this.point = point; + this.amount = amount; + } + + @Override + public String getType() { + return getType(modifiers); + } + + public static String getType(String modifiers) { + return "wheel(" + modifiers + ")"; + } +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/BoxSelection.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/BoxSelection.java new file mode 100644 index 00000000..ae5f9bbe --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/BoxSelection.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.editor.ISelection; +import org.simantics.h2d.element.IElement; +import org.simantics.h2d.event.DragEvent; +import org.simantics.h2d.node.RectangleNode; +import org.simantics.scenegraph.g2d.G2DParentNode; + +public class BoxSelection extends DragEventHandler { + + Rectangle2D rectangle = new Rectangle2D.Double(); + RectangleNode selectionNode; + + @Override + protected void update(IDiagramEditor editor, DragEvent event) { + rectangle.setFrameFromDiagonal(event.start, event.current); + editor.requestRepaint(); + } + + @Override + protected void end(IDiagramEditor editor, DragEvent event) { + Rectangle2D.Double elementBounds = new Rectangle2D.Double(); + ISelection selection = editor.getSelection(); + System.out.println(event.currentModifiers); + + Collection toBeSelected = new ArrayList(); + for(IElement element : editor.getDiagram().getElements()) { + element.getBounds(elementBounds); + if(rectangle.contains(elementBounds)) + toBeSelected.add(element); + } + + if(event.currentModifiers.equals("ctrl+")) + selection.addAll(toBeSelected); + else + selection.set(toBeSelected); + editor.requestRepaint(); + } + + @Override + public void init(G2DParentNode parent) { + selectionNode = parent.addNode(RectangleNode.class); + selectionNode.init(rectangle); + } + + @Override + public void remove() { + selectionNode.remove(); + selectionNode = null; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/DefaultEventHandlers.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/DefaultEventHandlers.java new file mode 100644 index 00000000..cdf1af95 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/DefaultEventHandlers.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import org.simantics.h2d.editor.IDiagramEditor; + +public class DefaultEventHandlers { + + private DefaultEventHandlers() {} + + public static void configure(IDiagramEditor editor) { + editor.addEventHandler(1, "click(left)", new PickSelection()); + editor.addEventHandler(1, "click(ctrl+left)", new ToggleSelection()); + editor.addEventHandler(1, "drag(shift+left)", new Pan()); + editor.addEventHandler(1, "drag(alt+shift+middle)", new Pan()); + editor.addEventHandler(1, "drag(alt+middle)", new Pan()); + editor.addEventHandler(1, "drag(shift+right)", new Pan()); + editor.addEventHandler(1, "wheel()", new Zoom()); + editor.addEventHandler(1, "key(1)", new ZoomToFit()); + editor.addEventHandler(1, "key(Period)", new RotateCounterclockwise()); + editor.addEventHandler(1, "key(Comma)", new RotateClockwise()); + editor.addEventHandler(1, "key(Ctrl+D)", new Delete()); + + editor.addEventHandler(0, new ElementEventDelegator()); + + editor.addEventHandler(-1, "drag(left)", new MoveSelected()); + editor.addEventHandler(-2, "drag(left)", new BoxSelection()); + editor.addEventHandler(-2, "drag(ctrl+left)", new BoxSelection()); + + // Prints all unhandled events + //editor.addEventHandler(-1000, new EventPrinter()); + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/Delete.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/Delete.java new file mode 100644 index 00000000..713d5650 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/Delete.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import org.simantics.h2d.diagram.IDiagram; +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.element.IElement; +import org.simantics.h2d.event.IEvent; + +public class Delete implements IEventHandler { + + @Override + public boolean handle(IDiagramEditor editor, IEvent event) { + IDiagram diagram = editor.getDiagram(); + for(IElement element : editor.getSelection()) { + diagram.removeElement(element); + } + editor.getSelection().clear(); + editor.requestRepaint(); + return true; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/DragEventHandler.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/DragEventHandler.java new file mode 100644 index 00000000..1cf9af72 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/DragEventHandler.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import org.simantics.h2d.action.IAction; +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.event.DragEvent; +import org.simantics.h2d.event.IEvent; +import org.simantics.scenegraph.g2d.G2DParentNode; + +public abstract class DragEventHandler implements IAction { + + boolean isActive = false; + + protected boolean begin(IDiagramEditor editor, DragEvent event) { + return true; + } + + protected void update(IDiagramEditor editor, DragEvent event) { + } + + protected void end(IDiagramEditor editor, DragEvent event) { + } + + @Override + public boolean handle(IDiagramEditor editor, IEvent _event) { + if(_event instanceof DragEvent) { + DragEvent event = (DragEvent)_event; + + switch(event.phase) { + case dragBegin: + if(isActive) + return true; + if(begin(editor, event)) { + isActive = true; + editor.addAction(this); + return true; + } + else + return false; + + case dragUpdate: + if(!isActive) + return false; + update(editor, event); + return true; + + case dragEnd: + if(!isActive) + return false; + isActive = false; + editor.removeAction(this); + end(editor, event); + return true; + } + + } + return false; + } + + @Override + public void init(G2DParentNode parent) { + } + + @Override + public void remove() { + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/ElementEventDelegator.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/ElementEventDelegator.java new file mode 100644 index 00000000..21177468 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/ElementEventDelegator.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.element.IElement; +import org.simantics.h2d.event.IEvent; +import org.simantics.h2d.event.ILocatableEvent; +import org.simantics.h2d.event.KeyboardEvent; + +public class ElementEventDelegator implements IEventHandler { + + @Override + public boolean handle(IDiagramEditor editor, IEvent _event) { + if(_event instanceof KeyboardEvent) { + IEventHandler uniqueHandler = null; + for(IElement element : editor.getSelection()) { + IEventHandler handler = element.getInterface(IEventHandler.class); + if(handler != null) { + if(uniqueHandler != null) + return true; // nobody cannot consume the event + uniqueHandler = handler; + } + } + if(uniqueHandler != null) + return uniqueHandler.handle(editor, _event); + } + else if(_event instanceof ILocatableEvent) { + ILocatableEvent event = (ILocatableEvent)_event; + for(IElement element : event.getPickedElements()) { + IEventHandler handler = element.getInterface(IEventHandler.class); + if(handler != null && handler.handle(editor, event)) + return true; + } + } + return false; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/EventPrinter.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/EventPrinter.java new file mode 100644 index 00000000..8dbf80a8 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/EventPrinter.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.event.IEvent; + +public class EventPrinter implements IEventHandler { + + @Override + public boolean handle(IDiagramEditor editor, IEvent event) { + System.out.println(event.getType()); + return false; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/IEventHandler.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/IEventHandler.java new file mode 100644 index 00000000..d30f61b2 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/IEventHandler.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.event.IEvent; + +public interface IEventHandler { + + boolean handle(IDiagramEditor editor, IEvent event); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/MoveSelected.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/MoveSelected.java new file mode 100644 index 00000000..5726b8c2 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/MoveSelected.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.List; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.editor.ISelection; +import org.simantics.h2d.element.IElement; +import org.simantics.h2d.element.handler.Movable; +import org.simantics.h2d.event.DragEvent; +import org.simantics.h2d.node.RectangleNode; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.nodes.TransformNode; + +public class MoveSelected extends DragEventHandler { + + double deltaX, deltaY; + TransformNode shadowNode; + ISelection selection; + + @Override + protected boolean begin(IDiagramEditor editor, DragEvent event) { + List pick = event.pickedElements; + if(pick.isEmpty()) + return false; + selection = editor.getSelection(); + boolean pickContainsSelected = false; + for(IElement element : pick) + if(selection.contains(element)) { + pickContainsSelected = true; + break; + } + if(!pickContainsSelected) { + selection.clear(); + selection.add(pick.get(0)); + } + return true; + } + + @Override + protected void update(IDiagramEditor editor, DragEvent event) { + deltaX = event.current.getX() - event.start.getX(); + deltaY = event.current.getY() - event.start.getY(); + shadowNode.setTransform(new AffineTransform(1.0, 0.0, 0.0, 1.0, deltaX, deltaY)); + editor.requestRepaint(); + } + + @Override + protected void end(IDiagramEditor editor, DragEvent event) { + for(IElement element : selection) + if(element instanceof Movable) { + ((Movable)element).move(deltaX, deltaY); + } + selection = null; + editor.requestRepaint(); + } + + @Override + public void init(G2DParentNode parent) { + shadowNode = parent.addNode(TransformNode.class); + + for(IElement element : selection) { + Rectangle2D elementBounds = new Rectangle2D.Double(); + element.getBounds(elementBounds); + RectangleNode shadow = shadowNode.addNode(RectangleNode.class); + shadow.init(elementBounds); + } + } + + @Override + public void remove() { + shadowNode.remove(); + shadowNode = null; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/Pan.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/Pan.java new file mode 100644 index 00000000..a490e580 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/Pan.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import java.awt.geom.Point2D; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.event.DragEvent; + +public class Pan extends DragEventHandler { + + @Override + protected void update(IDiagramEditor editor, DragEvent event) { + Point2D offset = editor.getOffset(); + double scale = editor.getScale(); + editor.setViewTransform( + new Point2D.Double( + offset.getX() + event.start.getX() - event.current.getX(), + offset.getY() + event.start.getY() - event.current.getY() + ), + scale); + editor.requestRepaint(); + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/PickSelection.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/PickSelection.java new file mode 100644 index 00000000..199e0de0 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/PickSelection.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import java.util.List; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.editor.ISelection; +import org.simantics.h2d.element.IElement; +import org.simantics.h2d.event.ClickEvent; +import org.simantics.h2d.event.IEvent; + +public class PickSelection implements IEventHandler { + + @Override + public boolean handle(IDiagramEditor editor, IEvent _event) { + ClickEvent event = (ClickEvent)_event; + List pick = event.pickedElements; + ISelection selection = editor.getSelection(); + if(pick.isEmpty()) { + selection.clear(); + editor.requestRepaint(); + } + else { + if(selection.containsOneOf(pick)) { + if(pick.size() > 1 && selection.size()==1) { + /* + * If there are multiple elements under mouse and the current + * selection is exactly one of them then rotate thru all one + * element selection possibilities. + */ + IElement s = selection.getSingleElement(); + for(int i=0;i pick = event.pickedElements; + if(!pick.isEmpty()) { + editor.getSelection().toggle(pick.get(0)); + editor.requestRepaint(); + } + return true; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/Zoom.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/Zoom.java new file mode 100644 index 00000000..0113bdfb --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/Zoom.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import java.awt.geom.Point2D; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.event.IEvent; +import org.simantics.h2d.event.WheelEvent; + +public class Zoom implements IEventHandler { + + public final static double ZOOM_PER_CLICK = 1.2; + + @Override + public boolean handle(IDiagramEditor editor, IEvent _event) { + final WheelEvent event = (WheelEvent)_event; + Point2D offset = editor.getOffset(); + double scale = editor.getScale(); + double scaleRatio = Math.pow(ZOOM_PER_CLICK, event.amount); + + editor.setViewTransform( + new Point2D.Double( + offset.getX() * scaleRatio + event.point.getX() * (1.0 - scaleRatio), + offset.getY() * scaleRatio + event.point.getY() * (1.0 - scaleRatio) + ), + scale * scaleRatio); + editor.requestRepaint(); + return true; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/ZoomToFit.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/ZoomToFit.java new file mode 100644 index 00000000..7d0378b0 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/event/handler/ZoomToFit.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.event.handler; + +import java.awt.Dimension; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.h2d.editor.IDiagramEditor; +import org.simantics.h2d.element.IElement; +import org.simantics.h2d.event.IEvent; + +public class ZoomToFit implements IEventHandler { + + @Override + public boolean handle(IDiagramEditor editor, IEvent event) { + Rectangle2D diagramBounds = null; + Rectangle2D elementBounds = new Rectangle2D.Double(); + for(IElement element : editor.getDiagram().getElements()) { + element.getBounds(elementBounds); + if(diagramBounds == null) { + diagramBounds = new Rectangle2D.Double(); + diagramBounds.setFrame(elementBounds); + } + else { + Rectangle2D.union(diagramBounds, elementBounds, diagramBounds); + } + } + if(diagramBounds != null) { + Dimension dimension = editor.getViewDimension(); + + double scale = Math.max( + diagramBounds.getWidth() / dimension.getWidth(), + diagramBounds.getHeight() / dimension.getHeight() + ); + + Point2D offset = new Point2D.Double( + diagramBounds.getCenterX() - dimension.getWidth() * scale * 0.5, + diagramBounds.getCenterY() - dimension.getHeight() * scale * 0.5 + ); + editor.setViewTransform(offset, scale); + } + editor.requestRepaint(); + return true; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/FilledShapeNode.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/FilledShapeNode.java new file mode 100644 index 00000000..1732270a --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/FilledShapeNode.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.node; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DNode; + +public class FilledShapeNode extends G2DNode { + + private static final long serialVersionUID = -7540487222025677413L; + + protected Shape shape = null; + protected Color color = Color.BLACK; + + @SyncField("shape") + public void setShape(Shape shape) { + this.shape = shape; + } + + @SyncField("color") + public void setColor(Color color) { + this.color = color; + } + + @Override + public void render(Graphics2D g2d) { + if(shape == null) return; + if(color != null) g2d.setColor(color); + + g2d.fill(shape); + } + + @Override + public Rectangle2D getBoundsInLocal() { + if(shape == null) + return null; + return shape.getBounds2D(); + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/ITextListener.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/ITextListener.java new file mode 100644 index 00000000..0dcd7681 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/ITextListener.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.node; + +public interface ITextListener { + + void textChanged(); + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/LineNode.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/LineNode.java new file mode 100644 index 00000000..d7ebb069 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/LineNode.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.node; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DNode; + +public class LineNode extends G2DNode { + + private static final long serialVersionUID = 654692698101485672L; + + Point2D begin; + Point2D end; + protected Path2D path; + + @SyncField({"begin","end"}) + public void init(Point2D begin, Point2D end) { + this.begin = begin; + this.end = end; + update(); + } + + protected void update() { + path = new Path2D.Double(); + path.moveTo(begin.getX(), begin.getY()); + path.lineTo(end.getX(), end.getY()); + } + + @Override + public void render(Graphics2D g) { + if(path == null) return; + g.setColor(Color.BLACK); + double scale = g.getTransform().getScaleX(); + g.setStroke(new BasicStroke( (float)(1.0 / scale) )); + g.draw(path); + } + + @Override + public Rectangle2D getBoundsInLocal() { + Rectangle2D bounds = new Rectangle2D.Double(); + bounds.setFrameFromDiagonal(begin, end); + return bounds; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/RectangleNode.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/RectangleNode.java new file mode 100644 index 00000000..da8daaa4 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/RectangleNode.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.node; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DNode; + +public class RectangleNode extends G2DNode { + + private static final long serialVersionUID = 654692698101485672L; + + protected Rectangle2D bounds = null; + + @SyncField("bounds") + public void init(Rectangle2D bounds) { + this.bounds = bounds; + } + + @Override + public void render(Graphics2D g) { + if(bounds == null) return; + g.transform(transform); + g.setColor(Color.BLACK); + double scale = g.getTransform().getScaleX(); + g.setStroke(new BasicStroke( (float)(1.0 / scale) )); + + g.draw(bounds); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return bounds; + } + +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/ShapeNode.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/ShapeNode.java new file mode 100644 index 00000000..495fb614 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/ShapeNode.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.node; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.utils.GeometryUtils; + +public class ShapeNode extends G2DNode { + + /** + * + */ + private static final long serialVersionUID = 8508750881358776559L; + + protected Shape shape = null; + protected Stroke stroke = new BasicStroke(1); + protected Color color = Color.BLACK; + protected boolean fill = false; + protected boolean scaleStroke = false; + protected boolean scaleShape = false; + + @SyncField("shape") + public void setShape(Shape shape) { + this.shape = shape; + repaint(); + } + + @SyncField("stroke") + public void setStroke(Stroke stroke) { + this.stroke = stroke; + } + + @SyncField("color") + public void setColor(Color color) { + this.color = color; + } + + @SyncField("fill") + public void setFill(boolean fill) { + this.fill = fill; + } + + @SyncField("scaleStroke") + public void setScaleStroke(boolean scaleStroke) { + this.scaleStroke = scaleStroke; + } + + @SyncField("scaleShape") + public void setScaleShape(boolean scaleShape) { + this.scaleShape = scaleShape; + } + + @Override + public void render(Graphics2D g2d) { + if(shape == null) return; + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // FIXME + if(color != null) g2d.setColor(color); + if(stroke != null) { + if(scaleStroke && stroke instanceof BasicStroke) { + BasicStroke bs = GeometryUtils.scaleStroke(stroke, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform()))); + g2d.setStroke(bs); + } else { + g2d.setStroke(stroke); + } + } + if(scaleShape) { + double xs = g2d.getTransform().getScaleX(); + double ys = g2d.getTransform().getScaleY(); + g2d.scale(1/xs, 1/ys); + } + + if(fill) { + g2d.fill(shape); + } else { + g2d.draw(shape); + } + + } + + @Override + public Rectangle2D getBoundsInLocal() { + return shape.getBounds2D(); + } +} diff --git a/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/TextNode.java b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/TextNode.java new file mode 100644 index 00000000..6575c352 --- /dev/null +++ b/dev-jkauttio/org.simantics.h2d/src/org/simantics/h2d/node/TextNode.java @@ -0,0 +1,276 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.h2d.node; + +import java.awt.AWTEvent; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.font.FontRenderContext; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DNode; + +public class TextNode extends G2DNode { + + //static final FontRenderContext FRC = new FontRenderContext( + // new AffineTransform(1.0,0.0,0.0,1.0,0.0,0.0), true, true); + + private static final long serialVersionUID = 654692698101485672L; + + protected String text = null; + protected Font font = null; + protected Color color = null; + protected double x; + protected double y; + protected double scale; + + boolean editAllowed; + int caret = 0; + int selectionTail = 0; + + ITextListener textListener; + + /** + * Enables or disables edit mode. It also sets + * the caret at the end of text all selects the + * whole text (this is the usual convention when + * beginning to edit one line texts). + * @param editAllowed + */ + public void setEditMode(boolean editAllowed) { + this.editAllowed = editAllowed; + caret = text.length(); + selectionTail = 0; + } + + @SyncField({"text", "font", "color", "x", "y", "scale"}) + public void init(String text, Font font, Color color, double x, double y, double scale) { + this.text = text; + this.font = font; + this.color = color; + this.x = x; + this.y = y; + this.scale = scale; + } + + @SyncField({"color"}) + public void setColor(Color color) { + this.color = color; + } + + public String getText() { + return text; + } + + private double getLength(FontRenderContext frc, String str) { + Rectangle2D bounds = font.getStringBounds(str, frc); + return bounds.getWidth(); + } + + @Override + public void render(Graphics2D g) { + if(text == null || font == null || color == null) return; + g.setFont(font); + g.translate(x, y); + g.scale(scale, scale); + + if(editAllowed) { + FontRenderContext frc = g.getFontRenderContext(); + + int selectionMin = Math.min(caret, selectionTail); + int selectionMax = Math.max(caret, selectionTail); + double selectionMinPos = getLength(frc, text.substring(0, selectionMin)); + double selectionMaxPos = getLength(frc, text.substring(0, selectionMax)); + + // Selection background + g.setColor(new Color(0x316ac5)); + g.fill(new Rectangle2D.Double(selectionMinPos, -12.0, + selectionMaxPos-selectionMinPos, 12.0)); + + // Text + g.setColor(color); + g.drawString(text.substring(0, selectionMin), 0f, 0f); + g.drawString(text.substring(selectionMax), (float)selectionMaxPos, 0f); + + g.setColor(Color.WHITE); + g.drawString(text.substring(selectionMin, selectionMax), (float)selectionMinPos, 0f); + + // Caret + double caretPos = getLength(frc, text.substring(0, caret)); + //g.setXORMode(Color.BLACK); + g.setColor(Color.BLACK); + g.draw(new Line2D.Double(caretPos, 0, caretPos, -12.0)); + } + else { + g.setColor(color); + g.drawString(text, 0f, 0f); + } + } + + /** + * Replaces the current selection with the content or inserts + * the content at caret. After the insertion the caret + * will be at the end of inserted text and selection will + * be empty. + * @param content + */ + @SyncField("text") + protected void insert(String content) { + if(!content.contains(" ")) { + int selectionMin = Math.min(caret, selectionTail); + int selectionMax = Math.max(caret, selectionTail); + + String begin = text.substring(0, selectionMin); + String end = text.substring(selectionMax); + text = begin + content + end; + caret = selectionMin + content.length(); + selectionTail = caret; + } + } + + + @ServerSide + protected void fireTextChanged() { + if(textListener != null) + textListener.textChanged(); + } + + public void setTextListener(ITextListener listener) { + this.textListener = listener; + } + + private void handleKeyPressed(KeyEvent event) { + char c = event.getKeyChar(); + //System.out.println("Key pressed " + c + " " + event.getKeyCode()); + if(event.isControlDown()) + switch(event.getKeyCode()) { + case KeyEvent.VK_C: + if(caret != selectionTail) { + int selectionMin = Math.min(caret, selectionTail); + int selectionMax = Math.max(caret, selectionTail); + setCliboardContent(text.substring(selectionMin, selectionMax)); + } + break; + + case KeyEvent.VK_V: + { + String content = getCliboardContent(); + if(content != null) + insert(content); + } + break; + default: + return; + } + else if(event.isAltDown()) + return; + else + switch(event.getKeyCode()) { + case KeyEvent.VK_LEFT: + if(caret > 0) { + --caret; + if(!event.isShiftDown()) + selectionTail = caret; + } + break; + case KeyEvent.VK_RIGHT: + if(caret < text.length()) { + ++caret; + if(!event.isShiftDown()) + selectionTail = caret; + } + break; + case KeyEvent.VK_HOME: + caret = 0; + if(!event.isShiftDown()) + selectionTail = caret; + break; + case KeyEvent.VK_END: + caret = text.length(); + if(!event.isShiftDown()) + selectionTail = caret; + break; + + case KeyEvent.VK_BACK_SPACE: + if(caret == selectionTail && caret > 0) + --caret; + insert(""); + break; + + case KeyEvent.VK_DELETE: + if(caret == selectionTail && caret < text.length()) + ++caret; + insert(""); + break; + + default: + if(c == 65535 || Character.getType(c) == Character.CONTROL) + return; + //System.out.println("Char " + (int)c + " " + Character.getType(c)); + insert(new String(new char[] {c})); + } + // FIXME This is called even if just caret was moved. + // This is currently necessary for repaints. + fireTextChanged(); + event.consume(); + } + + private void handleMousePressed(MouseEvent event) { + // TODO + } + + @Override + public void handleEvent(AWTEvent event) { + if(editAllowed) { + if(caret > text.length()) + caret = text.length(); + switch(event.getID()) { + case KeyEvent.KEY_PRESSED: + handleKeyPressed((KeyEvent)event); + break; + case MouseEvent.MOUSE_PRESSED: + handleMousePressed((MouseEvent)event); + break; + } + } + } + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + + public String getCliboardContent() { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + Transferable clipData = clipboard.getContents(this); + try { + return (String) (clipData.getTransferData(DataFlavor.stringFlavor)); + } catch (Exception ee) { + return null; + } + } + + public void setCliboardContent(String content) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringSelection data = new StringSelection(content); + clipboard.setContents(data, data); + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart.ontology/.classpath b/dev-jkauttio/org.simantics.jfreechart.ontology/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart.ontology/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.jfreechart.ontology/.project b/dev-jkauttio/org.simantics.jfreechart.ontology/.project new file mode 100644 index 00000000..36a196b0 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart.ontology/.project @@ -0,0 +1,34 @@ + + + org.simantics.jfreechart.ontology + + + + + + org.simantics.graph.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.simantics.graph.nature + + diff --git a/dev-jkauttio/org.simantics.jfreechart.ontology/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.jfreechart.ontology/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..8fdbeb77 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart.ontology/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Nov 14 12:29:34 EET 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.jfreechart.ontology/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.jfreechart.ontology/META-INF/MANIFEST.MF new file mode 100644 index 00000000..68f6c52a --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart.ontology/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: JFreeChart +Bundle-SymbolicName: org.simantics.jfreechart.ontology +Bundle-Version: 1.0.0.qualifier +Require-Bundle: org.simantics.layer0, + org.simantics.layer0x.ontology;bundle-version="1.0.0", + org.simantics.g2d.ontology;bundle-version="1.0.0", + org.simantics.diagram.ontology;bundle-version="2.1.0", + org.simantics.structural.ontology;bundle-version="1.1.0", + org.simantics.modeling.ontology;bundle-version="1.1.0", + org.simantics.project.ontology;bundle-version="1.2.0", + org.simantics.image2.ontology;bundle-version="1.2.0", + org.simantics.action.ontology;bundle-version="1.1.0", + org.simantics.viewpoint.ontology;bundle-version="1.2.0", + org.simantics.color.ontology;bundle-version="1.1.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Export-Package: org.simantics.sysdyn diff --git a/dev-jkauttio/org.simantics.jfreechart.ontology/build.properties b/dev-jkauttio/org.simantics.jfreechart.ontology/build.properties new file mode 100644 index 00000000..022de173 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart.ontology/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + graph.tg diff --git a/dev-jkauttio/org.simantics.jfreechart.ontology/graph.tg b/dev-jkauttio/org.simantics.jfreechart.ontology/graph.tg new file mode 100644 index 00000000..5a57c746 Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart.ontology/graph.tg differ diff --git a/dev-jkauttio/org.simantics.jfreechart.ontology/graph/ChartViewpoints.pgraph b/dev-jkauttio/org.simantics.jfreechart.ontology/graph/ChartViewpoints.pgraph new file mode 100644 index 00000000..e0cb5e3a --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart.ontology/graph/ChartViewpoints.pgraph @@ -0,0 +1,117 @@ +L0 = +VP = +PROJECT = +MOD = +IMAGE = +COLOR = +ACT = +JFREE = + + +/////////////////////////////////////////////// +// XY Line axis: axis and variables viewpoint +/////////////////////////////////////////////// +CBC = JFREE.ChartAxisAndVariablesBrowseContext : VP.BrowseContext +CAC = JFREE.ChartAxisAndVariablesActionContext : VP.BrowseContext + +CBC.AxisChildRule : VP.ChildRule +CBC.VariableChildRule : VP.ChildRule +CBC.SeriesLabelRule : VP.LabelRule +CBC.AxisLabelRule : VP.LabelRule +CBC.SeriesLabelDecorationRule : VP.LabelDecorationRule + +CBC + @VP.customChildRule JFREE.Chart CBC.AxisChildRule + JFREE.Axis : VP.ResourceNodeType + @VP.customChildRule JFREE.Axis CBC.VariableChildRule + JFREE.Series : VP.ResourceNodeType + +CBC + @VP.customLabelRule JFREE.Axis CBC.AxisLabelRule + @VP.customLabelRule JFREE.Series CBC.SeriesLabelRule + +CBC + @VP.customLabelDecorationRule JFREE.Series CBC.SeriesLabelDecorationRule + +CBC + @VP.dropActionContribution JFREE.Axis CAC.Actions.SeriesDropAction 1.0 + @VP.dropActionContribution JFREE.Series CAC.Actions.SeriesDropAction 1.0 + @VP.dropActionContribution JFREE.Axis CAC.Actions.AxisDropAction 2.0 + @VP.dropActionContribution JFREE.Series CAC.Actions.AxisDropAction 2.0 + +CBC + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType JFREE.Chart + VP.VisualsContribution.HasRule VP.PassThruSorterRule + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType JFREE.Axis + VP.VisualsContribution.HasRule VP.PassThruSorterRule + + +CAC.Actions : L0.Library +CAC.Actions.SeriesDropAction : ACT.DropAction +CAC.Actions.AxisDropAction : ACT.DropAction + + +/////////////////////////////////////////////// +// Bar chart: Variables viewpoint +/////////////////////////////////////////////// +BSBC = JFREE.BarSeriesBrowseContext : VP.BrowseContext +BSAC = JFREE.BarSeriesActionContext : VP.BrowseContext + +BSBC.SeriesChildRule : VP.ChildRule +BSBC.SeriesLabelRule : VP.LabelRule +BSBC.SeriesLabelDecorationRule : VP.LabelDecorationRule + +BSBC + @VP.customChildRule JFREE.Chart BSBC.SeriesChildRule + JFREE.Series + +BSBC + @VP.customLabelRule JFREE.Series BSBC.SeriesLabelRule + +BSBC + @VP.customLabelDecorationRule JFREE.Series BSBC.SeriesLabelDecorationRule + +BSBC + @VP.dropActionContribution JFREE.Series BSAC.Actions.SeriesDropAction 1.0 + +BSBC + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType JFREE.Chart + VP.VisualsContribution.HasRule VP.PassThruSorterRule + +BSAC.Actions : L0.Library +BSAC.Actions.SeriesDropAction : ACT.DropAction + + +/////////////////////////////////////////////// +// Pie chart: Variables viewpoint +/////////////////////////////////////////////// +PSBC = JFREE.PieSeriesBrowseContext : VP.BrowseContext +PSAC = JFREE.PieSeriesActionContext : VP.BrowseContext + +PSBC.SeriesChildRule : VP.ChildRule +PSBC.SeriesLabelRule : VP.LabelRule +PSBC.SeriesLabelDecorationRule : VP.LabelDecorationRule + +PSBC + @VP.customChildRule JFREE.Chart PSBC.SeriesChildRule + JFREE.Series + +PSBC + @VP.customLabelRule JFREE.Series PSBC.SeriesLabelRule + +PSBC + @VP.customLabelDecorationRule JFREE.Series PSBC.SeriesLabelDecorationRule + +PSBC + @VP.dropActionContribution JFREE.Series PSAC.Actions.SeriesDropAction 1.0 + +PSBC + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType JFREE.Chart + VP.VisualsContribution.HasRule VP.PassThruSorterRule + +PSAC.Actions : L0.Library +PSAC.Actions.SeriesDropAction : ACT.DropAction diff --git a/dev-jkauttio/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph b/dev-jkauttio/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph new file mode 100644 index 00000000..f185b412 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart.ontology/graph/JFreeChart.pgraph @@ -0,0 +1,141 @@ +L0 = +L0X = +G2D = +DIA = +MOD = +STR = + +//##################################################################### +// Ontology for defining JFreeChart charts +//##################################################################### + +JFREE = : L0.Ontology + @L0.new + L0.HasResourceClass "org.simantics.sysdyn.JFreeChartResource" + +//##################################################################### +// Charts +//##################################################################### +JFREE.Chart -- JFREE.title --> JFREE.Title -- JFREE.subtitles --> L0.List -- JFREE.Chart.borderColor --> G2D.Color -- JFREE.Chart.visibleBorder --> L0.Boolean -- JFREE.Chart.borderWidth --> L0.Double -- JFREE.Chart.visibleLegend --> L0.Boolean -- JFREE.Chart.time --> L0.Double -- JFREE.visible --> L0.Boolean -- JFREE.Title.position --> L0.Boolean -- JFREE.Plot.domainAxis --> JFREE.Axis -- JFREE.Plot.rangeAxis --> JFREE.Axis -- JFREE.backgroundColor --> G2D.Color -- JFREE.Plot.visibleGrid --> L0.Boolean -- JFREE.Plot.rangeAxisList --> L0.List -- JFREE.Plot.visibleLabels --> L0.Boolean -- JFREE.Plot.orientation --> L0.Boolean -- JFREE.color --> G2D.Color -- JFREE.Axis.min --> L0.Double -- JFREE.Axis.max --> L0.Double -- JFREE.Axis.visibleTickLabels --> L0.Boolean -- JFREE.Axis.visibleTickMarks --> L0.Boolean -- JFREE.Axis.visibleAxisLine --> L0.Boolean -- JFREE.Axis.visibleLabel --> L0.Boolean -- JFREE.Axis.rotateLabelDegrees --> L0.Double -- JFREE.Dataset.seriesList --> L0.List -- JFREE.Dataset.renderer --> JFREE.Renderer -- JFREE.Dataset.mapToDomainAxis --> JFREE.Axis -- JFREE.Dataset.mapToRangeAxis --> JFREE.Axis -- JFREE.color + >-- JFREE.variableRVI --> L0.String -- JFREE.variableFilter --> L0.StringArray -- JFREE.Series.rangeList --> L0.List -- JFREE.Series.lineWidth --> L0.Integer -- JFREE.Series.exploded --> L0.Boolean -- JFREE.Series.time --> L0.Double -- JFREE.ChartElement.component --> JFREE.Chart () { + public JFreeChartResource perform(ReadGraph graph) throws DatabaseException { + QueryControl qc = graph.getService(QueryControl.class); + return new JFreeChartResource(qc.getIndependentGraph(graph)); + } + }); + session.registerService(JFreeChartResource.class, ret); + } + return ret; + } + +} + diff --git a/dev-jkauttio/org.simantics.jfreechart/.classpath b/dev-jkauttio/org.simantics.jfreechart/.classpath new file mode 100644 index 00000000..ed5bcd8e --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/.classpath @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.jfreechart/.project b/dev-jkauttio/org.simantics.jfreechart/.project new file mode 100644 index 00000000..9c948e2d --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/.project @@ -0,0 +1,28 @@ + + + org.simantics.jfreechart + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.jfreechart/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.jfreechart/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..f287d53c --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.jfreechart/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.jfreechart/META-INF/MANIFEST.MF new file mode 100644 index 00000000..fb0ab09c --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/META-INF/MANIFEST.MF @@ -0,0 +1,45 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Jfreechart +Bundle-SymbolicName: org.simantics.jfreechart;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.jfreechart.internal.Activator +Bundle-Vendor: VTT +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.jfree.jchart;bundle-version="1.0.13", + org.jfree.jcommon;bundle-version="1.0.16", + org.simantics.jfreechart.ontology;bundle-version="1.0.0", + org.simantics.db;bundle-version="1.1.0", + org.simantics.db.layer0;bundle-version="1.1.0", + org.simantics.layer0;bundle-version="1.1.0", + org.simantics.diagram;bundle-version="1.1.1", + org.simantics.diagram.ontology;bundle-version="2.2.0", + org.simantics.modeling;bundle-version="1.1.1", + org.simantics.ui;bundle-version="1.0.0", + org.simantics.browsing.ui.common;bundle-version="1.1.0", + org.simantics.browsing.ui.ontology;bundle-version="1.1.0", + org.simantics.browsing.ui.swt;bundle-version="1.1.0", + org.simantics.modeling.ui;bundle-version="1.1.1", + org.simantics.layer0.utils;bundle-version="1.1.0", + org.simantics.scenegraph.swing;bundle-version="1.0.0", + org.simantics.browsing.ui.model;bundle-version="1.0.0", + org.simantics.selectionview;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: org.simantics.jfreechart, + org.simantics.jfreechart.chart, + org.simantics.jfreechart.chart.element, + org.simantics.jfreechart.chart.ge, + org.simantics.jfreechart.chart.properties, + org.simantics.jfreechart.chart.properties.bar, + org.simantics.jfreechart.chart.properties.pie, + org.simantics.jfreechart.chart.properties.xyline +Bundle-ClassPath: batik/batik-awt-util.jar, + batik/batik-dom.jar, + batik/batik-ext.jar, + batik/batik-svg-dom.jar, + batik/batik-svggen.jar, + batik/batik-util.jar, + batik/batik-xml.jar, + . diff --git a/dev-jkauttio/org.simantics.jfreechart/adapters.xml b/dev-jkauttio/org.simantics.jfreechart/adapters.xml new file mode 100644 index 00000000..54fd841c --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/adapters.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.jfreechart/batik/batik-1.7.zip b/dev-jkauttio/org.simantics.jfreechart/batik/batik-1.7.zip new file mode 100644 index 00000000..b1f32e7d Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/batik/batik-1.7.zip differ diff --git a/dev-jkauttio/org.simantics.jfreechart/batik/batik-awt-util.jar b/dev-jkauttio/org.simantics.jfreechart/batik/batik-awt-util.jar new file mode 100644 index 00000000..e64605af Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/batik/batik-awt-util.jar differ diff --git a/dev-jkauttio/org.simantics.jfreechart/batik/batik-dom.jar b/dev-jkauttio/org.simantics.jfreechart/batik/batik-dom.jar new file mode 100644 index 00000000..32d5b46d Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/batik/batik-dom.jar differ diff --git a/dev-jkauttio/org.simantics.jfreechart/batik/batik-ext.jar b/dev-jkauttio/org.simantics.jfreechart/batik/batik-ext.jar new file mode 100644 index 00000000..8c904e1f Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/batik/batik-ext.jar differ diff --git a/dev-jkauttio/org.simantics.jfreechart/batik/batik-src-1.7.zip b/dev-jkauttio/org.simantics.jfreechart/batik/batik-src-1.7.zip new file mode 100644 index 00000000..77478cd3 Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/batik/batik-src-1.7.zip differ diff --git a/dev-jkauttio/org.simantics.jfreechart/batik/batik-svg-dom.jar b/dev-jkauttio/org.simantics.jfreechart/batik/batik-svg-dom.jar new file mode 100644 index 00000000..b4c8a620 Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/batik/batik-svg-dom.jar differ diff --git a/dev-jkauttio/org.simantics.jfreechart/batik/batik-svggen.jar b/dev-jkauttio/org.simantics.jfreechart/batik/batik-svggen.jar new file mode 100644 index 00000000..4d6bb144 Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/batik/batik-svggen.jar differ diff --git a/dev-jkauttio/org.simantics.jfreechart/batik/batik-util.jar b/dev-jkauttio/org.simantics.jfreechart/batik/batik-util.jar new file mode 100644 index 00000000..86d75e70 Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/batik/batik-util.jar differ diff --git a/dev-jkauttio/org.simantics.jfreechart/batik/batik-xml.jar b/dev-jkauttio/org.simantics.jfreechart/batik/batik-xml.jar new file mode 100644 index 00000000..d05eb25f Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/batik/batik-xml.jar differ diff --git a/dev-jkauttio/org.simantics.jfreechart/build.properties b/dev-jkauttio/org.simantics.jfreechart/build.properties new file mode 100644 index 00000000..3806e2b7 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/build.properties @@ -0,0 +1,14 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + adapters.xml,\ + icons/,\ + batik/batik-awt-util.jar,\ + batik/batik-dom.jar,\ + batik/batik-ext.jar,\ + batik/batik-svg-dom.jar,\ + batik/batik-svggen.jar,\ + batik/batik-util.jar,\ + batik/batik-xml.jar diff --git a/dev-jkauttio/org.simantics.jfreechart/icons/chart_bar_light.png b/dev-jkauttio/org.simantics.jfreechart/icons/chart_bar_light.png new file mode 100644 index 00000000..6069b5c9 Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/icons/chart_bar_light.png differ diff --git a/dev-jkauttio/org.simantics.jfreechart/icons/chart_line_light.png b/dev-jkauttio/org.simantics.jfreechart/icons/chart_line_light.png new file mode 100644 index 00000000..2a77b242 Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/icons/chart_line_light.png differ diff --git a/dev-jkauttio/org.simantics.jfreechart/icons/chart_pie_light.png b/dev-jkauttio/org.simantics.jfreechart/icons/chart_pie_light.png new file mode 100644 index 00000000..fa553c29 Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/icons/chart_pie_light.png differ diff --git a/dev-jkauttio/org.simantics.jfreechart/icons/close.gif b/dev-jkauttio/org.simantics.jfreechart/icons/close.gif new file mode 100644 index 00000000..1aca259d Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/icons/close.gif differ diff --git a/dev-jkauttio/org.simantics.jfreechart/icons/maximize.gif b/dev-jkauttio/org.simantics.jfreechart/icons/maximize.gif new file mode 100644 index 00000000..5e5999be Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/icons/maximize.gif differ diff --git a/dev-jkauttio/org.simantics.jfreechart/icons/minimize.gif b/dev-jkauttio/org.simantics.jfreechart/icons/minimize.gif new file mode 100644 index 00000000..7402dc9f Binary files /dev/null and b/dev-jkauttio/org.simantics.jfreechart/icons/minimize.gif differ diff --git a/dev-jkauttio/org.simantics.jfreechart/plugin.xml b/dev-jkauttio/org.simantics.jfreechart/plugin.xml new file mode 100644 index 00000000..9db7546b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/plugin.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartDropTarget.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartDropTarget.java new file mode 100644 index 00000000..a218ada3 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartDropTarget.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.simantics.db.Resource; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Drop target for dropping charts in chart panel + * @author Teemu Lempinen + * + */ +public class ChartDropTarget extends DropTargetAdapter { + + private Composite separator; + private ChartPanelElement element; + private Display display; + private ChartPanel panel; + + public ChartDropTarget(Composite separator, ChartPanelElement element, ChartPanel panel) { + this.separator = separator; + this.display = separator.getDisplay(); + this.element = element; + this.panel = panel; + } + + + + /** + * Display effect on the composite when drag entered + */ + @Override + public void dragEnter(DropTargetEvent event) { + if ((event.operations & DND.DROP_COPY) != 0) { + event.detail = DND.DROP_COPY; + } else if ((event.operations & DND.DROP_MOVE) != 0) { + event.detail = DND.DROP_MOVE; + } else { + event.detail = DND.DROP_NONE; + } + separator.setBackground(display.getSystemColor(SWT.COLOR_DARK_GRAY)); + } + + /** + * Revert effect when drag leaves + */ + @Override + public void dragLeave(DropTargetEvent event) { + separator.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + } + + /** + * Drop the data to chart panel + */ + @Override + public void drop(DropTargetEvent event) { + Resource chartResource = AdaptionUtils.adaptToSingle(event.data, Resource.class); + if(chartResource != null) + panel.addChart(chartResource, element); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanel.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanel.java new file mode 100644 index 00000000..a698efe8 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanel.java @@ -0,0 +1,471 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart; + +import java.util.ArrayList; +import java.util.LinkedHashMap; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.AsyncListener; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.internal.Activator; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.dnd.LocalObjectTransfer; +import org.simantics.utils.RunnableWithObject; + +/** + * Chart panel displays multiple charts in a single view. The view can be oriented + * vertically or horizontally, the default is vertical. Charts can be added, removed + * minimized or expanded. The order of the charts can be changed by dragging the charts. + * + * @author Teemu Lempinen + * + */ +public class ChartPanel extends ViewPart { + + private Composite body; + private ScrolledComposite sc; + + private IDialogSettings settings; + private LinkedHashMap charts; + private ArrayList minimizedResources; + + private ArrayList chartElements; + + public static final String CHART_PANEL_SETTINGS = "CHART_PANEL_SETTINGS"; + public static final String CHARTS = "CHART_PANEL_CHARTS"; + public static final String MINIMIZED_CHARTS = "CHART_PANEL_MINIMIZED_CHARTS"; + public static final String CHART_PANEL_ORIENTATION = "CHART_PANEL_ORIENTATION"; + + public static final String CHART_PANEL_VERTICAL = "CHART_PANEL_ORIENTATION_VERTICAL"; + public static final String CHART_PANEL_HORIZONTAL = "CHART_PANEL_ORIENTATION_HORIZONTAL"; + + private boolean vertical = true; + + /** + * Initialize the view. Load charts that have previously been open (if there are any). + */ + @Override + public void init(IViewSite site, IMemento memento) throws PartInitException { + super.init(site, memento); + + minimizedResources = new ArrayList(); + + settings = Activator.getDefault().getDialogSettings().getSection(CHART_PANEL_SETTINGS); + + // Initialize settings if there are no settings + if (settings == null) { + settings = Activator.getDefault().getDialogSettings().addNewSection(CHART_PANEL_SETTINGS); + } + + if(settings.getArray(CHARTS) == null) { + String[] chartUris = new String[] {}; + settings.put(CHARTS, chartUris); + } + + if(settings.getArray(MINIMIZED_CHARTS) == null) { + String[] minimizedChartUris = new String[] {}; + settings.put(MINIMIZED_CHARTS, minimizedChartUris); + } + + // initialize chart lists + charts = new LinkedHashMap(); + + // add chart resources to chart lists from settings + try { + SimanticsUI.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Resource chart = null; + String[] chartURIs = settings.getArray(CHARTS); + for(String uri : chartURIs) { + chart = graph.getPossibleResource(uri); + if(chart != null && graph.isInstanceOf(chart, jfree.Chart)) { + charts.put(chart, null); + setChartExistingListener(chart); + } + } + + String[] minimizedUris = settings.getArray(MINIMIZED_CHARTS); + for(String uri : minimizedUris) { + chart = graph.getPossibleResource(uri); + if(chart != null && graph.isInstanceOf(chart, jfree.Chart)) { + minimizedResources.add(chart); + } + } + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + // set the orientation of the panel + String orientation = settings.get(CHART_PANEL_ORIENTATION); + if(CHART_PANEL_VERTICAL.equals(orientation)) + this.vertical = true; + else if(CHART_PANEL_HORIZONTAL.equals(orientation)) + this.vertical = false; + + } + + /** + * Create a scrolled composite that will contain all the charts, then call the actual + * content creator. + */ + @Override + public void createPartControl(Composite parent) { + sc = new ScrolledComposite(parent, SWT.NONE | SWT.H_SCROLL | SWT.V_SCROLL); + GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(sc); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + sc.getVerticalBar().setIncrement(sc.getVerticalBar().getIncrement()*3); + sc.getHorizontalBar().setIncrement(sc.getHorizontalBar().getIncrement()*3); + + body = new Composite(sc, SWT.NONE); + GridLayoutFactory.fillDefaults().margins(3, 0).spacing(0, 0).applyTo(body); + GridDataFactory.fillDefaults().grab(true, true).applyTo(body); + + sc.setContent(body); + createContents(); + + setupDropTarget(); + + } + + /** + * Creates the contents of this chart panel. + * Removes all old contents before creating new content + */ + private void createContents() { + chartElements = new ArrayList(); + + for(Control child : body.getChildren()) { + child.dispose(); + } + + // Set the initial layout + ElementContainer elementHolder; + for(Resource e : charts.keySet()) { + elementHolder = new ElementContainer(body, SWT.NONE); + elementHolder.setBackground(new Color(elementHolder.getDisplay(), 255, 0, 0)); + ChartPanelElement element = new ChartPanelElement(elementHolder, this, e, SWT.NONE); + elementHolder.setLayout(GridLayoutFactory.copyLayout((GridLayout)element.getLayout())); + chartElements.add(element); + charts.put(e, element); + if(minimizedResources.contains(e)) { + element.toggleMinimize(); + } + } + + elementHolder = new ElementContainer(body, SWT.NONE); + elementHolder.setBackground(new Color(elementHolder.getDisplay(), 0, 255, 0)); + ChartPanelElement element = new ChartPanelElement(elementHolder, this, null, SWT.NONE); // Last element is empty -> only the separator + elementHolder.setLayout(GridLayoutFactory.copyLayout((GridLayout)element.getLayout())); + chartElements.add(element); + + layout(); + saveState(); + + } + + /** + * Lays out this panel (the body composite) + */ + public void layout() { + if(vertical) { + GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(body); + GridDataFactory.fillDefaults().grab(true, true).applyTo(body); + } else { + // Need to calculate horizontal elements for gridLayout + int chartPanels = chartElements.size(); + GridLayoutFactory.fillDefaults().spacing(0, 0).numColumns(chartPanels).applyTo(body); + GridDataFactory.fillDefaults().grab(true, true).applyTo(body); + } + body.layout(); + sc.setMinSize(body.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + + @Override + public void setFocus() { + if(!sc.isDisposed()) + sc.setFocus(); + } + + @Override + public void saveState(IMemento memento) { + super.saveState(memento); + saveState(); + } + + /** + * Save the current state of the view to IDialogSettings + */ + public void saveState() { + try { + SimanticsUI.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + if (settings != null) { + String[] uris = new String[chartElements.size() - 1]; + ArrayList minimized = new ArrayList(); + minimizedResources.clear(); + for(int i = 0; i < uris.length; i++) { + ChartPanelElement e = chartElements.get(i); + Resource r = e.getResource(); + if(r != null) { + uris[i] = graph.getURI(r); + if(e.isMinimized()) { + minimized.add(uris[i]); + minimizedResources.add(r); + } + } else { + uris[i] = ""; + } + } + settings.put(CHARTS, uris); + if(!minimized.isEmpty()) + settings.put(MINIMIZED_CHARTS, minimized.toArray(new String[minimized.size()])); + else + settings.put(MINIMIZED_CHARTS, new String[0]); + + if(vertical) + settings.put(CHART_PANEL_ORIENTATION, CHART_PANEL_VERTICAL); + else + settings.put(CHART_PANEL_ORIENTATION, CHART_PANEL_HORIZONTAL); + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + /** + * Set the orientation for this chart panel. + * + * @param orientation Orientation (ChartPanel.CHART_PANEL_VERTICAL or ChartPanel.CHART_PANEL_HORIZONTAL) + */ + public void setOrientation(String orientation) { + if(CHART_PANEL_VERTICAL.equals(orientation)) + this.vertical = true; + else { + this.vertical = false; + } + createContents(); + } + + /** + * Removes a chart from this panel + * + * @param chart The chart to be removed + */ + public void removeChart(Resource chart) { + ChartPanelElement element = charts.get(chart); + chartElements.remove(element); + element.getParent().dispose(); + charts.remove(chart); + minimizedResources.remove(chart); + saveState(); + layout(); + } + + /** + * Sets up drag-scrolling for a scrolled composite + * + * @param control + */ + protected void setupDropTarget() { + DropTarget target = new DropTarget(sc, DND.DROP_MOVE); + target.setTransfer(new Transfer[] { LocalObjectTransfer.getTransfer() }); + + target.addDropListener(new DropTargetAdapter() { + + private int activeMargin = 20; + private int moveAmount = 1; + + @Override + public void dragOver(DropTargetEvent event) { + Point original = sc.getOrigin(); + Point origin = sc.getOrigin(); + Point pointer = sc.toControl(event.x, event.y); + Rectangle bounds = sc.getBounds(); + + if(pointer.y < activeMargin) + origin.y = origin.y - moveAmount; + else if(bounds.height - pointer.y < activeMargin) + origin.y = origin.y + moveAmount; + if(pointer.x < activeMargin) + origin.x = origin.x - moveAmount; + else if(bounds.width - pointer.x < activeMargin) + origin.x = origin.x + moveAmount; + + if(origin != original) { + sc.setOrigin (origin.x, origin.y); + sc.redraw(); + } + } + + }); + + DropTarget target2 = new DropTarget(body, DND.DROP_COPY | DND.DROP_MOVE); + target2.setTransfer(new Transfer[] { LocalObjectTransfer.getTransfer() }); + target2.addDropListener(new ChartDropTarget(body, null, this)); + + } + + /** + * Is the panel vertically oriented + * @return Is the panel vertically oriented + */ + public boolean isVertical() { + return vertical; + } + + /** + * Adds chart after given element. If element == null, adds chart to the top. + * + * @param element To which place the chart will be placed. (null allowed) + */ + public void addChart(Resource chartResource, ChartPanelElement element) { + addChart(chartResource, element, true); + } + + /** + * Adds chart after given element. If element == null, adds chart to the top. + * + * @param element To which place the chart will be placed. (null allowed) + * @param layout refresh layout. use with vertical layout. + */ + public void addChart(Resource chartResource, ChartPanelElement element, boolean layout) { + if(element == null) + element = chartElements.get(chartElements.size() - 1); + int index = chartElements.indexOf(element); + if(index >= 0) { + ChartPanelElement e = chartElements.get(index); + ChartPanelElement newElement; + + if(charts.containsKey(chartResource)) { + // Old element being moved to a new place + newElement = charts.get(chartResource); + int oldIndex = chartElements.indexOf(newElement); + if(newElement.equals(element) || oldIndex == index - 1) + return; // Not moving anywhere, do nothing + Composite oldParent = newElement.getParent(); + newElement.setParent(e.getParent()); + oldParent.dispose(); + if(oldIndex < index) + index--; + chartElements.remove(newElement); + } else { + newElement = new ChartPanelElement(e.getParent(), this, chartResource, SWT.NONE); + } + + // Add a new chart element to the location of the old element + chartElements.add(index, newElement); + charts.put(chartResource, newElement); + + ElementContainer elementHolder; + // Move elements back after index + for(int i = index + 1 /*indexes after the new element*/; i < chartElements.size(); i++) { + e = chartElements.get(i); + if(i == chartElements.size() - 1) { + // last element (the empty element) element to a new container + elementHolder = new ElementContainer(body, SWT.NONE); + elementHolder.setBackground(new Color(elementHolder.getDisplay(), 0, 0, 255)); + elementHolder.setLayout(GridLayoutFactory.copyLayout((GridLayout)e.getLayout())); + e.setParent(elementHolder); + } else { + // element to the next elements container + elementHolder = (ElementContainer)chartElements.get(i + 1).getParent(); + e.setParent(elementHolder); + } + } + + layout(); + saveState(); + } + } + + /** + * Set a listener to listen if the chart resource has been removed. + * If the resource has been removed, close also the chart element in this panel. + * + * @param chart Listened chart resource + */ + private void setChartExistingListener(final Resource chart) { + SimanticsUI.getSession().asyncRequest(new Read() { + + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + return graph.hasStatement(chart); + } + }, new AsyncListener() { + + boolean disposed = false; + + @Override + public void execute(AsyncReadGraph graph, Boolean result) { + if(result != null && result == false && body != null && !body.isDisposed()) { + body.getDisplay().asyncExec(new RunnableWithObject(chart){ + public void run() { + removeChart((Resource)getObject()); + } + }) ; + disposed = true; + } + } + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return !disposed && !charts.containsKey(chart); + } + }); + } + + public ArrayList getElements() { + return chartElements; + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanelElement.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanelElement.java new file mode 100644 index 00000000..3102514d --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanelElement.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.simantics.db.Resource; +import org.simantics.jfreechart.chart.ChartComposite; +import org.simantics.ui.dnd.LocalObjectTransfer; + +/** + * This class represents an expanded chart element in {@link ChartPanel}. It contains + * a header {@link ChartPanelHeader} and the actual chart. + * + * @author Teemu Lempinen + * + */ +public class ChartPanelElement extends Composite { + + public static int CHART_MINIMUM_WIDTH = 300; + public static int CHART_MINIMUM_HEIGHT = 200; + + private ChartPanel panel; + private ChartComposite chartComposite; + private Resource chartResource; + private boolean minimized = false; + + public Resource getResource() { + return chartResource; + } + + @Override + public Object getLayoutData () { + checkWidget(); + Object oldData = super.getLayoutData(); + if(oldData == null || !(oldData instanceof GridData)) { + oldData = GridDataFactory.fillDefaults().create(); + } + + int size = panel.getElements().size(); + GridData data = (GridData) oldData; + // Horizontal data + data.widthHint = CHART_MINIMUM_WIDTH; + if(getResource() == null && size == 1) { + data.grabExcessHorizontalSpace = true; + } else if(getResource() == null && !panel.isVertical()){ + data.grabExcessHorizontalSpace = false; + data.widthHint = SWT.DEFAULT; + } else if(minimized && !panel.isVertical()) { + data.grabExcessHorizontalSpace = false; + data.widthHint = SWT.DEFAULT; + } else { + data.grabExcessHorizontalSpace = true; + } + + // Vertical data + if(getResource() == null && size == 1) { + data.grabExcessVerticalSpace = true; + } else if(!minimized && getResource() != null) { + data.grabExcessVerticalSpace = true; + data.heightHint = CHART_MINIMUM_HEIGHT; + } else if(!panel.isVertical()){ + data.grabExcessVerticalSpace = true; + } else { + data.grabExcessVerticalSpace = false; + data.heightHint = SWT.DEFAULT; + } + return data; + } + + /** + * Creates an expanded chart panel element into parent composite. + * + * @param parent The parent composite where the chart element is created + * @param panel The {@link ChartPanel} containing the chart element + * @param name The name of the chart + * @param style The Style of the created chart element + */ + public ChartPanelElement(Composite parent, ChartPanel panel, Resource chartResource, int style) { + this(parent, panel, chartResource, false, style); + } + + /** + * Creates a chart panel element into parent composite. + * @param parent The parent composite where the chart element is created + * @param panel The {@link ChartPanel} containing the chart element + * @param name The name of the chart + * @param minimized Is the chart-section minimized + * @param style The Style of the created chart element + */ + public ChartPanelElement(Composite parent, ChartPanel panel, Resource chartResource, boolean minimized, int style) { + super(parent, style | SWT.NONE ); + + this.panel = panel; + this.chartResource = chartResource; + this.minimized = minimized; + + if(panel.isVertical() || getResource() == null) + GridLayoutFactory.fillDefaults().spacing(0,0).applyTo(this); + else + GridLayoutFactory.fillDefaults().numColumns(2).spacing(0,0).applyTo(this); + + GridDataFactory.fillDefaults().applyTo(this); + + // Separator for dropping other elements + ChartPanelSeparator separator = new ChartPanelSeparator(this, panel, this, SWT.NONE); + + if (chartResource != null) { + Composite c = new Composite(this, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(c); + GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(c); + // Header + new ChartPanelHeader(c, this, chartResource, SWT.BORDER); + + // Chart + chartComposite = new ChartComposite(c, chartResource, SWT.BORDER); + } + + DropTarget target = new DropTarget(this, DND.DROP_COPY | DND.DROP_MOVE); + target.setTransfer(new Transfer[] { LocalObjectTransfer.getTransfer() }); + target.addDropListener(new ChartDropTarget(separator, this, panel)); + + } + + /** + * Returns the chart resource associated with this element + * @return chart resource + */ + public Resource getChartResource() { + return this.chartResource; + } + + /** + * Returns the minimized state of this element + * @return is the element minimized + */ + public boolean isMinimized() { + return minimized; + } + + /** + * Change the minimized state of this element + */ + public void toggleMinimize() { + toggleMinimize(false); + } + /** + * Change the minimized state of this element + */ + public void toggleMinimize(boolean callSave) { + minimized = Boolean.FALSE.equals(minimized); + GridData data = (GridData) chartComposite.getLayoutData(); + if(panel.isVertical()) + data.exclude = minimized; + else + data.exclude = false; + chartComposite.setVisible(!minimized); + + Composite parent = getParent(); + data = (GridData) getLayoutData(); + GridData parentData = (GridData)parent.getLayoutData(); + parentData.grabExcessHorizontalSpace = data.grabExcessHorizontalSpace; + parentData.grabExcessVerticalSpace = data.grabExcessVerticalSpace; + parentData.heightHint = data.heightHint; + + if(callSave) { + panel.saveState(); + } + panel.layout(); + } + + /** + * Remove this chart panel element from its panel + */ + public void remove() { + panel.removeChart(chartResource); + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanelHeader.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanelHeader.java new file mode 100644 index 00000000..5935c34f --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanelHeader.java @@ -0,0 +1,397 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.internal.Activator; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.dnd.LocalObjectTransfer; +import org.simantics.utils.datastructures.Pair; + +/** + * Header of a chart element in {@link ChartPanel}. Only this header is + * shown if a chart is minimized. If a chart is expanded, this header is added + * to the charts {@link ChartPanelElement}. + * + * @author Teemu Lempinen + * + */ +public class ChartPanelHeader extends Composite { + + public static int HEADER_MINIMUM_WIDTH = 250; + private ChartPanelElement element; + private Resource resource; + private Label name; + private Canvas iconCanvas; + private Image icon; + private ToolItem minimize, remove; + private Color defaultColor, darker, evenDarker; + private Image gradientBackgroundImage, borderImage; + + private static ImageDescriptor closeDescriptor = ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/close.gif")); + private static Image closeImage = closeDescriptor.createImage(); + + private static ImageDescriptor minimizeDescriptor = ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/minimize.gif")); + private static Image minimizeImage = minimizeDescriptor.createImage(); + + private static ImageDescriptor maximizeDescriptor = ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/maximize.gif")); + private static Image maximizeImage = maximizeDescriptor.createImage(); + + private static ImageDescriptor lineChartDescriptor = ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_line_light.png")); + private static Image lineChartImage = lineChartDescriptor.createImage(); + + private static ImageDescriptor barChartDescriptor = ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar_light.png")); + private static Image barChartImage = barChartDescriptor.createImage(); + + private static ImageDescriptor pieChartDescriptor = ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_pie_light.png")); + private static Image pieChartImage = pieChartDescriptor.createImage(); + + + /** + * Chart panel header with minimize and close buttons. + * + * @param parent The composite where the header is added + * @param panel The {@link ChartPanel} containing the header + * @param name The name of the chart + * @param style he Style of the created chart element + */ + public ChartPanelHeader(Composite c, ChartPanelElement element, Resource chartResource, int style) { + super(c, style); + this.resource = chartResource; + this.element = element; + + GridLayoutFactory.fillDefaults().margins(3, 0).numColumns(3).applyTo(this); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this); + + // Colors + + // Chart icon + iconCanvas = new Canvas (this, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).hint(16, 16).applyTo(iconCanvas); + iconCanvas.addPaintListener (new PaintListener() { + + @Override + public void paintControl(PaintEvent e) { + if(icon != null) + e.gc.drawImage (icon, 0, 0); + } + }); + + // Label for the chart name (also minimize/expand) + name = new Label(this, SWT.NONE); + + try { + // name updater + Pair result = SimanticsUI.getSession().syncRequest(new Read>() { + + @Override + public Pair perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + String label = graph.getPossibleRelatedValue(resource, l0.HasLabel); + Image image = null; + Resource plot = graph.syncRequest(new PossibleObjectWithType(resource, l0.ConsistsOf, jfree.Plot)); + if(plot != null) { + if(graph.isInstanceOf(plot, jfree.CategoryPlot)) + image = barChartImage; + else if(graph.isInstanceOf(plot, jfree.PiePlot)) + image = pieChartImage; + else + image = lineChartImage; + } + return new Pair(label, image); + } + + }, new Listener>() { + + @Override + public void execute(final Pair result) { + if(result == null) + return; + + name.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(!name.isDisposed() && result.first != null) + name.setText(result.first); + + if(!iconCanvas.isDisposed() && result.second != null) { + icon = result.second; + iconCanvas.redraw(); + ChartPanelHeader.this.layout(); + } + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return name.isDisposed(); + } + + }); + name.setText(result.first); + } catch (DatabaseException e) { + e.printStackTrace(); + name.setText("No label"); + } + GridDataFactory.fillDefaults().grab(true, false).applyTo(name); + + ToolBar toolbar = new ToolBar(this, SWT.FLAT); + // item for minimizing/expanding chart + minimize = new ToolItem(toolbar, SWT.PUSH); + minimize.addSelectionListener(new MinimizeListener()); + if(isMinimized()) { + minimize.setToolTipText("Expand"); + minimize.setImage(maximizeImage); + } else { + minimize.setToolTipText("Minimize"); + minimize.setImage(minimizeImage); + } + + // item for closing/removing the chart + remove = new ToolItem(toolbar, SWT.PUSH); + remove.setImage(closeImage); + remove.addSelectionListener(new RemoveChartListener()); + remove.setToolTipText("Remove"); + + + /* ******************************** + * DnD + * ********************************/ + + // Allow data to be copied or moved from the drag source + int operations = DND.DROP_MOVE; + source = new DragSource(name, operations); + + // Provide data in Text format + Transfer[] types = new Transfer[] { LocalObjectTransfer.getTransfer() }; + source.setTransfer(types); + dragSourceListener = new DragSourceListener() { + + @Override + public void dragStart(DragSourceEvent event) { + if(name.isDisposed()) + event.doit = false; + event.detail = DND.DROP_LINK; + + } + + @Override + public void dragSetData(DragSourceEvent event) { + event.data = new StructuredSelection(resource); + } + + @Override + public void dragFinished(DragSourceEvent event) { + } + }; + source.addDragListener(dragSourceListener); + + name.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + if(dragSourceListener != null && source != null && !source.isDisposed()) { + source.removeDragListener(dragSourceListener); + } + } + }); + this.setBackgroundImage(getGradientBackgroundImage()); + this.setBackgroundMode(SWT.INHERIT_FORCE); + + this.addListener(SWT.MouseEnter, new EnterListener()); + this.addListener(SWT.MouseExit, new ExitListener()); + + for(Control child : this.getChildren()) { + child.addListener(SWT.MouseEnter, new EnterListener()); + child.addListener(SWT.MouseExit, new ExitListener()); + + } + } + + private class EnterListener implements org.eclipse.swt.widgets.Listener { + public void handleEvent(Event event) { + ChartPanelHeader.this.setBackgroundImage(getHighlightedGradientBackgroundImage()); + } + } + + private class ExitListener implements org.eclipse.swt.widgets.Listener { + public void handleEvent(Event event) { + ChartPanelHeader.this.setBackgroundImage(getGradientBackgroundImage()); + } + } + + private void createColors() { + if(defaultColor == null) { + defaultColor = getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); + try { + defaultColor = new Color(getDisplay(), defaultColor.getRed() + 500, defaultColor.getGreen() + 10, defaultColor.getBlue() + 10); + } catch (IllegalArgumentException e) { + // Do nothing, use the default color + } + } + + if(darker == null) { + try { + darker = new Color(getDisplay(), defaultColor.getRed() - 30, defaultColor.getGreen() - 30, defaultColor.getBlue() - 30); + } catch (IllegalArgumentException e) { + // Do nothing, use the default color + darker = defaultColor; + } + } + + if(evenDarker == null) { + try { + evenDarker = new Color(getDisplay(), defaultColor.getRed() - 50, defaultColor.getGreen() - 50, defaultColor.getBlue() - 50); + } catch (IllegalArgumentException e) { + // Do nothing, use the default color + evenDarker = defaultColor; + } + } + + } + + private Image getHighlightedGradientBackgroundImage() { + createColors(); + this.layout(); + Point size = this.getSize(); + + borderImage = new Image(this.getDisplay(), 1, Math.max(1, size.y)); + GC gc = new GC(borderImage); + gc.setForeground(defaultColor); + gc.setBackground(evenDarker); + gc.fillGradientRectangle(0, 0, 1, size.y, true); + gc.dispose(); + + return borderImage; + } + + private Image getGradientBackgroundImage() { + createColors(); + this.layout(); + Point size = this.computeSize(SWT.DEFAULT, SWT.DEFAULT); + if(gradientBackgroundImage == null) { + gradientBackgroundImage = new Image(this.getDisplay(), 1, Math.max(1, size.y)); + GC gc = new GC(gradientBackgroundImage); + gc.setForeground(defaultColor); + gc.setBackground(darker); + gc.fillGradientRectangle(0, 0, 1, size.y, true); + gc.dispose(); + } + + return gradientBackgroundImage; + } + + private DragSourceListener dragSourceListener; + private DragSource source; + + /** + * Return true if this element is minimized, false if expanded + * @return true if this element is minimized, false if expanded + */ + private boolean isMinimized() { + return element.isMinimized(); + } + + /** + * Listener to minimize chart button. Expands and minimizes + * the chart of this header. + * + * @author Teemu Lempinen + * + */ + private class MinimizeListener implements SelectionListener { + @Override + public void widgetSelected(SelectionEvent e) { + if(ChartPanelHeader.this.isDisposed()) + return; + + element.toggleMinimize(true); + + if(!name.isDisposed() && !minimize.isDisposed()) { + if(isMinimized()) { + minimize.setToolTipText("Expand"); + } else { + minimize.setToolTipText("Minimize"); + } + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + + } + + /** + * Listener for removing this chart from the chart panel. + * + * @author Teemu Lempinen + * + */ + private class RemoveChartListener implements SelectionListener { + @Override + public void widgetSelected(SelectionEvent e) { + if(!ChartPanelHeader.this.isDisposed()) { + element.remove(); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanelSeparator.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanelSeparator.java new file mode 100644 index 00000000..5f7e5e0b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPanelSeparator.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; + +/** + * Class for separating charts in {@link ChartPanel}. Acts as a drop participant for adding + * and moving charts in {@link ChartPanel}. + * + * @author Teemu Lempinen + * + */ +public class ChartPanelSeparator extends Composite { + + private ChartPanel panel; + + @Override + public Object getLayoutData() { + checkWidget(); + Object oldData = super.getLayoutData(); + if(oldData == null || !(oldData instanceof GridData)) { + oldData = GridDataFactory.fillDefaults().create(); + } + GridData data = (GridData) oldData; + // Empty panel -> drop area the size of the whole panel + if(panel.getElements().size() == 1 && panel.getElements().get(0).getResource() == null) { + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = true; + } + else { + if(panel.isVertical()) { + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = false; + } else { + data.grabExcessHorizontalSpace = false; + data.grabExcessVerticalSpace = true; + } + } + return data; + } + + /** + * Set up a small horizontal or vertical separator depending on SWT style + * + * @param parent + * @param style + */ + public ChartPanelSeparator(Composite parent, ChartPanel panel, ChartPanelElement element, int style) { + super(parent, style); + GridLayoutFactory.fillDefaults().margins(2, 2).applyTo(this); + GridDataFactory.fillDefaults().applyTo(this); + this.panel = panel; + addMouseListener(new SCFocusListener(panel)); + } + + + /** + * Listener for directing focus to scrollableComposite + * @author Teemu Lempinen + * + */ + private class SCFocusListener extends MouseAdapter { + ChartPanel panel; + public SCFocusListener(ChartPanel panel) { + this.panel = panel; + } + public void mouseDown(MouseEvent e) { + panel.setFocus(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPropertyOptions.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPropertyOptions.java new file mode 100644 index 00000000..4b6314ed --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartPropertyOptions.java @@ -0,0 +1,8 @@ +package org.simantics.jfreechart; + +public class ChartPropertyOptions { + + public static final int SHOW_TIME = 1 << 0; + public static final int SHOW_FILTER = 1 << 1; + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartSelectionTabContributor.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartSelectionTabContributor.java new file mode 100644 index 00000000..f8b0d764 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ChartSelectionTabContributor.java @@ -0,0 +1,162 @@ +package org.simantics.jfreechart; + +import java.util.Collection; +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.jfreechart.chart.properties.ChartTab; +import org.simantics.jfreechart.chart.properties.bar.BarAxisTab; +import org.simantics.jfreechart.chart.properties.bar.BarGeneralPropertiesTab; +import org.simantics.jfreechart.chart.properties.bar.BarSeriesTab; +import org.simantics.jfreechart.chart.properties.bar.BarSeriesTab2; +import org.simantics.jfreechart.chart.properties.pie.PieGeneralPropertiesTab; +import org.simantics.jfreechart.chart.properties.pie.PieSeriesTab; +import org.simantics.jfreechart.chart.properties.pie.PieSeriesTab2; +import org.simantics.jfreechart.chart.properties.xyline.XYLineAxisAndVariablesTab; +import org.simantics.jfreechart.chart.properties.xyline.XYLineGeneralPropertiesTab; +import org.simantics.layer0.Layer0; +import org.simantics.selectionview.ComparableTabContributor; +import org.simantics.sysdyn.JFreeChartResource; + +public class ChartSelectionTabContributor { + + public static boolean contibuteTabs(ReadGraph backend, Resource r, List tabs) throws DatabaseException{ + return contibuteTabs(backend, r, tabs, ChartPropertyOptions.SHOW_TIME); + } + public static boolean contibuteTabs(ReadGraph backend, Resource r, List tabs, int options) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(backend); + if(backend.isInstanceOf(r, jfree.ChartElement)) { + if(backend.hasStatement(r, jfree.ChartElement_component)) + r = backend.getSingleObject(r, jfree.ChartElement_component); + } + + if (backend.isInstanceOf(r, jfree.Chart)) { + + Collection plots = backend.syncRequest(new ObjectsWithType(r, Layer0.getInstance(backend).ConsistsOf, jfree.Plot)); + if(!plots.isEmpty()) { + Resource plot = plots.iterator().next(); + + if(backend.isInstanceOf(plot, jfree.XYPlot)) { + tabs.add(new ComparableTabContributor( + new XYLineGeneralPropertiesTab(), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new XYLineAxisAndVariablesTab(), + 9, + r, + "Axis and Variables")); + } else if(backend.isInstanceOf(plot, jfree.CategoryPlot)) { + tabs.add(new ComparableTabContributor( + new BarGeneralPropertiesTab(options), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new BarSeriesTab(options), + 9, + r, + "Variables")); + tabs.add(new ComparableTabContributor( + new BarAxisTab(), + 8, + r, + "Axis")); + } else if(backend.isInstanceOf(plot, jfree.PiePlot)) { + tabs.add(new ComparableTabContributor( + new PieGeneralPropertiesTab(options), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new PieSeriesTab(options), + 9, + r, + "Variables")); + } + + tabs.add(new ComparableTabContributor( + new ChartTab(), + 1, + r, + "Chart")); + + return true; + } + } + return false; + } + + public static boolean contibuteTabs2(ReadGraph backend, Resource r, List tabs) throws DatabaseException{ + return contibuteTabs2(backend, r, tabs, ChartPropertyOptions.SHOW_TIME); + } + + public static boolean contibuteTabs2(ReadGraph backend, Resource r, List tabs, int options) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(backend); + if(backend.isInstanceOf(r, jfree.ChartElement)) { + if(backend.hasStatement(r, jfree.ChartElement_component)) + r = backend.getSingleObject(r, jfree.ChartElement_component); + } + + if (backend.isInstanceOf(r, jfree.Chart)) { + + Collection plots = backend.syncRequest(new ObjectsWithType(r, Layer0.getInstance(backend).ConsistsOf, jfree.Plot)); + if(!plots.isEmpty()) { + Resource plot = plots.iterator().next(); + + if(backend.isInstanceOf(plot, jfree.XYPlot)) { + tabs.add(new ComparableTabContributor( + new XYLineGeneralPropertiesTab(), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new XYLineAxisAndVariablesTab(), + 9, + r, + "Axis and Variables")); + } else if(backend.isInstanceOf(plot, jfree.CategoryPlot)) { + tabs.add(new ComparableTabContributor( + new BarGeneralPropertiesTab(options), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new BarSeriesTab2(options), + 9, + r, + "Variables")); + tabs.add(new ComparableTabContributor( + new BarAxisTab(), + 8, + r, + "Axis")); + } else if(backend.isInstanceOf(plot, jfree.PiePlot)) { + tabs.add(new ComparableTabContributor( + new PieGeneralPropertiesTab(options), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new PieSeriesTab2(options), + 9, + r, + "Variables")); + } + + tabs.add(new ComparableTabContributor( + new ChartTab(), + 1, + r, + "Chart")); + + return true; + } + } + return false; + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ElementContainer.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ElementContainer.java new file mode 100644 index 00000000..37753607 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/ElementContainer.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** + * Container for a chart panel element. Needed for + * moving chart panel elements around using setParent() + * @author Teemu Lempinen + * + */ +public class ElementContainer extends Composite { + + @Override + public Object getLayoutData () { + Control[] children = getChildren(); + if(children.length == 1) { + if(children[0] instanceof ChartPanelElement) { + ChartPanelElement element = (ChartPanelElement)children[0]; + return element.getLayoutData(); + } + } + return super.getLayoutData(); + } + + public ElementContainer(Composite parent, int style) { + super(parent, style); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractAxis.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractAxis.java new file mode 100644 index 00000000..4439a9ca --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractAxis.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import java.awt.Color; + +import org.jfree.chart.axis.Axis; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.G2DUtils; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Abstract axis class for all JFreeChart axis + * @author Teemu Lempinen + * + */ +public abstract class AbstractAxis implements IAxis { + + protected Axis axis; + protected String label; + protected Boolean tMarksVisible, tLabelsVisible, labelVisible, lineVisible; + protected Color color; + protected Double min, max, rotate; + + /** + * Creates a new axis + * @param graph ReadGraph + * @param axisResource resource of type JFreeChart.NumberAxis + */ + public AbstractAxis(ReadGraph graph, Resource axisResource) { + try { + /* + * Axis is practically always called from a listener, + * so it is safe to always create a new axis every time. + * + * The parent listener takes care that the axis is updated. + * (And the code stays much more readable) + */ + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + label = graph.getPossibleRelatedValue(axisResource, l0.HasLabel); + tMarksVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleTickMarks, Bindings.BOOLEAN); + tLabelsVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleTickLabels, Bindings.BOOLEAN); + labelVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleLabel, Bindings.BOOLEAN); + lineVisible = graph.getPossibleRelatedValue(axisResource, jfree.Axis_visibleAxisLine, Bindings.BOOLEAN); + Resource c = graph.getPossibleObject(axisResource, jfree.color); + color = c == null ? null : G2DUtils.getColor(graph, c); + min = graph.getPossibleRelatedValue(axisResource, jfree.Axis_min, Bindings.DOUBLE); + max = graph.getPossibleRelatedValue(axisResource, jfree.Axis_max, Bindings.DOUBLE); + rotate = graph.getPossibleRelatedValue(axisResource, jfree.Axis_rotateLabelDegrees, Bindings.DOUBLE); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void dispose() { + + } + + @Override + public Axis getAxis() { + if(tMarksVisible != null && tMarksVisible == false) + axis.setTickMarksVisible(false); + if(tLabelsVisible != null && tLabelsVisible == false) + axis.setTickLabelsVisible(false); + if(lineVisible != null && lineVisible == false) + axis.setAxisLineVisible(false); + + if(color != null) { + axis.setAxisLinePaint(color); + axis.setLabelPaint(color); + axis.setTickLabelPaint(color); + axis.setTickMarkPaint(color); + } + // label exists and its visibility == null or true + if((labelVisible == null || labelVisible == true) && label != null) + axis.setLabel(label); + return axis; + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractDataset.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractDataset.java new file mode 100644 index 00000000..22072597 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractDataset.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; + + +/** + * Abstract dataset class for all JFreeChart datasets + * + * @author Teemu Lempinen + * + */ +public abstract class AbstractDataset implements IDataset { + + protected Resource resource; + + public AbstractDataset(ReadGraph graph, Resource resource) throws DatabaseException { + this.resource = resource; + } + + @Override + public void dispose() { + + } + + @Override + public Resource getResource() { + return resource; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractPlot.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractPlot.java new file mode 100644 index 00000000..ebfba892 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractPlot.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import java.util.ArrayList; +import java.util.HashMap; + +import javax.swing.SwingUtilities; + +import org.jfree.chart.axis.Axis; +import org.jfree.chart.plot.Plot; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; + +/** + * Abstract plot class for all JFreeChart plots + * + * @author Teemu Lempinen + * + */ +public abstract class AbstractPlot implements IPlot { + + protected Resource resource; + protected Plot plot; + protected PlotProperties currentProperties; + private PlotPropertyListener listener; + + + public AbstractPlot(ReadGraph graph, Resource resource) { + this.resource = resource; + } + + @Override + public void dispose() { + if(currentProperties != null) { + for(IAxis axis : currentProperties.ranges) + axis.dispose(); + + for(IAxis axis : currentProperties.domains) + axis.dispose(); + + for(IDataset dataset : currentProperties.datasets) + dataset.dispose(); + } + if(listener != null) + listener.dispose(); + } + + @Override + public Resource getResource() { + return resource; + } + + protected abstract Plot newPlot(); + protected abstract void setPlotProperties(PlotProperties properties); + protected abstract void getOtherProperties(ReadGraph graph, PlotProperties properties) throws DatabaseException; + + @Override + public Plot getPlot() { + if(plot == null) + plot = newPlot(); + + if(listener == null || listener.isDisposed()) { + listener = new PlotPropertyListener(); + SimanticsUI.getSession().asyncRequest(new Read() { + + @Override + public PlotProperties perform(ReadGraph graph) throws DatabaseException { + + PlotProperties properties = new PlotProperties(); + + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + HashMap axisMap = new HashMap(); + + // Get all range axis + Resource rangeList = graph.getPossibleObject(resource, jfree.Plot_rangeAxisList); + if(rangeList != null) { + for(Resource axisResource : ListUtils.toList(graph, rangeList)) { + IAxis axis = graph.adapt(axisResource, IAxis.class); + if(axis.getAxis() instanceof Axis) { + properties.ranges.add(axis); + axisMap.put(axisResource, axis); + } + } + } + + // Get all domain axis + // There usually is only one domain axis, but this supports also multiple domain axis + for(Resource axisResource : graph.syncRequest(new ObjectsWithType(resource, jfree.Plot_domainAxis, jfree.Axis))) { + IAxis axis = graph.adapt(axisResource, IAxis.class); + if(axis.getAxis() instanceof Axis) { + properties.domains.add(axis); + axisMap.put(axisResource, axis); + } + } + + // Get all datasets and map them to axis + for(Resource datasetResource : graph.syncRequest(new ObjectsWithType(resource, l0.ConsistsOf, jfree.Dataset))) { + IDataset dataset = graph.adapt(datasetResource, IDataset.class); + if(dataset != null) { + properties.datasets.add(dataset); + Resource axisResource = graph.getPossibleObject(datasetResource, jfree.Dataset_mapToRangeAxis); + IAxis axis; + if(axisMap.containsKey(axisResource)) { + axis = axisMap.get(axisResource); + properties.rangeMappings.put(dataset, axis); + } + + axisResource = graph.getPossibleObject(datasetResource, jfree.Dataset_mapToDomainAxis); + if(axisMap.containsKey(axisResource)) { + axis = axisMap.get(axisResource); + properties.domainMappings.put(dataset, axis); + } + } + } + getOtherProperties(graph, properties); + return properties; + + } + }, listener); + } + + return plot; + } + + @Override + public void configurePlot() { + // TODO Auto-generated method stub + + } + + protected class PlotProperties { + public ArrayList ranges; + public ArrayList domains; + public ArrayList datasets; + public HashMap rangeMappings; + public HashMap domainMappings; + public HashMap otherProperties; + + public PlotProperties() { + datasets = new ArrayList(); + rangeMappings = new HashMap(); + domainMappings = new HashMap(); + ranges = new ArrayList(); + domains = new ArrayList(); + otherProperties = new HashMap(); + } + + @Override + public boolean equals(Object other) { + if(!this.getClass().equals(other.getClass())) + return false; + PlotProperties p = (PlotProperties)other; + if(!ranges.equals(p.ranges)) + return false; + if(!domains.equals(p.domains)) + return false; + if(!datasets.equals(p.datasets)) + return false; + if(!rangeMappings.equals(p.rangeMappings)) + return false; + if(!domainMappings.equals(p.domainMappings)) + return false; + if(!otherProperties.equals(p.otherProperties)) + return false; + return true; + } + } + + private class PlotPropertyListener implements Listener { + + private boolean disposed = false; + + public void dispose() { + disposed = true; + } + @Override + public void execute(final PlotProperties result) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + setPlotProperties(result); + configurePlot(); + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractRenderer.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractRenderer.java new file mode 100644 index 00000000..7621c357 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/AbstractRenderer.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Abstract renderer class for all JFreeChart renderers + * @author Teemu Lempinen + * + */ +public abstract class AbstractRenderer implements IRenderer { + + protected Resource resource; + + public AbstractRenderer(ReadGraph graph, Resource resource) { + this.resource = resource; + } + + @Override + public void dispose() { + } + + @Override + public Resource getResource() { + return resource; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/BarRenderer.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/BarRenderer.java new file mode 100644 index 00000000..30430d3b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/BarRenderer.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.labels.StandardCategoryToolTipGenerator; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + + +/** + * Normal bar renderer + * @author Teemu Lempinen + * + */ +public class BarRenderer extends AbstractRenderer { + + public BarRenderer(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + private org.jfree.chart.renderer.category.BarRenderer renderer; + + @Override + public org.jfree.chart.renderer.AbstractRenderer getRenderer() { + if(renderer == null) { + renderer = new org.jfree.chart.renderer.category.BarRenderer(); + renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator()); + } + return renderer; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/CategoryAxis.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/CategoryAxis.java new file mode 100644 index 00000000..65731618 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/CategoryAxis.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.axis.Axis; +import org.jfree.chart.axis.CategoryLabelPositions; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Class representing a JFreeChart.CategoryAxis + * + * @author Teemu Lempinen + * + */ +public class CategoryAxis extends AbstractAxis { + + public CategoryAxis(ReadGraph graph, Resource axisResource) { + super(graph, axisResource); + } + + @Override + public Axis getAxis() { + axis = new org.jfree.chart.axis.CategoryAxis(); + + if(rotate != null && rotate > 0) { + ((org.jfree.chart.axis.CategoryAxis)axis).setCategoryLabelPositions( + CategoryLabelPositions.createUpRotationLabelPositions(Math.toRadians(rotate))); + } + + return super.getAxis(); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/CategoryDataset.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/CategoryDataset.java new file mode 100644 index 00000000..8b67400b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/CategoryDataset.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + + +/** + * Class representing a JFreeChart.CategoryDataset + * + * @author Teemu Lempinen + * + */ +public interface CategoryDataset extends IDataset { + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/CategoryPlot.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/CategoryPlot.java new file mode 100644 index 00000000..b4a52d91 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/CategoryPlot.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.axis.CategoryAxis; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.plot.Plot; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.renderer.category.CategoryItemRenderer; +import org.jfree.data.general.Dataset; +import org.jfree.ui.RectangleInsets; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Class representing a CategoryPlot for JFreeChart + * @author Teemu Lempinen + * + */ +public class CategoryPlot extends AbstractPlot { + + public CategoryPlot(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + @Override + protected Plot newPlot() { + return new org.jfree.chart.plot.CategoryPlot(null, null, null, null); + } + + @Override + protected void setPlotProperties(PlotProperties properties) { + if(!(plot instanceof org.jfree.chart.plot.CategoryPlot)) + return; + + org.jfree.chart.plot.CategoryPlot cplot = (org.jfree.chart.plot.CategoryPlot) plot; + /* Support using multiple axis, but prefer using only one domain and + * one range axis + */ + for(int i = 0; i < properties.ranges.size(); i++) { + cplot.setRangeAxis(i, (ValueAxis)properties.ranges.get(i).getAxis()); + } + + for(int i = 0; i < properties.domains.size(); i++) { + cplot.setDomainAxis(i, (CategoryAxis)properties.domains.get(i).getAxis()); + } + + + + IAxis axis; + for(int i = 0; i < properties.datasets.size(); i++) { + IDataset dataset = properties.datasets.get(i); + org.jfree.data.category.CategoryDataset ds = (org.jfree.data.category.CategoryDataset)dataset.getDataset(); + cplot.setDataset(i, ds); +// System.out.println("setting dataset " + i + ": " + ds); + cplot.setRenderer(i, (CategoryItemRenderer)dataset.getRenderer()); + axis = properties.rangeMappings.get(dataset); + if(axis != null && properties.ranges.contains(axis)) + cplot.mapDatasetToRangeAxis(i, properties.ranges.indexOf(axis)); + axis = properties.domainMappings.get(dataset); + if(axis != null && properties.ranges.contains(axis)) + cplot.mapDatasetToDomainAxis(i, properties.domains.indexOf(axis)); + + if (ds instanceof FilteredDataset) { + FilteredDataset f = (FilteredDataset)ds; + Boolean useFilter = (Boolean)properties.otherProperties.get("useFilter"); + Double filterFraction = (Double)properties.otherProperties.get("filterFraction"); + if (useFilter != null && filterFraction != null) { + f.setFiltering(useFilter); + f.setFilterFraction(filterFraction*0.01); + f.updateFiltered(); + } else { + f.setFiltering(false); + } + } + } + + Boolean visibleGrid = (Boolean)properties.otherProperties.get("visibleGrid"); + if(visibleGrid != null) { + cplot.setRangeGridlinesVisible(visibleGrid); + cplot.setDomainGridlinesVisible(false); + } + + Boolean orientation = (Boolean)properties.otherProperties.get("orientation"); + if(orientation != null) { + if (orientation) + cplot.setOrientation(PlotOrientation.HORIZONTAL); + else + cplot.setOrientation(PlotOrientation.VERTICAL); + } + + // Cleaner look: no outline borders + cplot.setInsets(new RectangleInsets(2,5,2,2), false); + cplot.setOutlineVisible(false); + } + + @Override + protected void getOtherProperties(ReadGraph graph, PlotProperties properties) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Boolean visibleGrid = graph.getPossibleRelatedValue(resource, jfree.Plot_visibleGrid); + properties.otherProperties.put("visibleGrid", visibleGrid); + Boolean orientation = graph.getPossibleRelatedValue(resource, jfree.Plot_orientation); + properties.otherProperties.put("orientation", orientation); + + Boolean useFilter = graph.getPossibleRelatedValue(resource, JFreeChartResource.getInstance(graph).Filter_used, Bindings.BOOLEAN); + Double filterFraction = graph.getPossibleRelatedValue(resource, JFreeChartResource.getInstance(graph).Filter_fraction, Bindings.DOUBLE); + properties.otherProperties.put("useFilter", useFilter); + properties.otherProperties.put("filterFraction", filterFraction); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ChartComposite.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ChartComposite.java new file mode 100644 index 00000000..dd5b069a --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ChartComposite.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import java.awt.Frame; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.awt.SWT_AWT; +import org.eclipse.swt.widgets.Composite; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.simantics.Simantics; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.AsyncListener; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.RunnableWithObject; + +/** + * Composite containing a single chart defined by a JFreeChart.Chart + * + * @author Teemu Lempinen + * + */ +public class ChartComposite extends Composite { + + private Frame frame; + private ChartPanel panel; + private Composite composite; + private IJFreeChart chart; + + /** + * A new ChartComposite with a definition in chartResourceURI + * @param parent Composite + * @param chartResourceURI URI for a JFreeChart.Chart definition + * @param style SWT style + */ + public ChartComposite(Composite parent, final String chartResourceURI, int style) { + super(parent, style | SWT.NO_BACKGROUND | SWT.EMBEDDED); + + try { + Resource chartResource = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return graph.getPossibleResource(chartResourceURI); + } + + }); + if(chartResource != null) + CreateContent(chartResource); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + /** + * A new ChartComposite with a chartResource definition + * @param parent Composite + * @param chartResource JFreeChart.Chart resource + * @param style SWT style + */ + public ChartComposite(Composite parent, final Resource chartResource, int style) { + super(parent, style | SWT.NO_BACKGROUND | SWT.EMBEDDED); + CreateContent(chartResource); + } + + /** + * Creates and displays the chart defined in chartResource + * @param chartResource + */ + private void CreateContent(final Resource chartResource) { + composite = this; + + GridLayoutFactory.fillDefaults().applyTo(composite); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + frame = SWT_AWT.new_Frame(composite); + + // Add a listener displaying the contents of the chart. Chart is re-drawn if the definition changes + Simantics.getSession().asyncRequest(new Read() { + + @Override + public IJFreeChart perform(ReadGraph graph) throws DatabaseException { + // Adapt chartResource to a chart (XY, pie, bar, ...) + if(graph.isInstanceOf(chartResource, JFreeChartResource.getInstance(graph).Chart)) { + if(chart != null) + chart.dispose(); + chart = graph.adapt(chartResource, IJFreeChart.class); + return chart; + } else { + return null; + } + } + + } , new AsyncListener() { + + @Override + public boolean isDisposed() { + return composite.isDisposed(); + } + + @Override + public void execute(AsyncReadGraph graph, IJFreeChart chart) { + if(chart == null || composite.isDisposed()) + return; + + JFreeChart jfreeChart = chart.getChart(); + // Display the result chart + composite.getDisplay().asyncExec(new RunnableWithObject(jfreeChart) { + + @Override + public void run() { + if(composite.isDisposed()) + return; + if(panel != null) + frame.remove(panel); + composite.layout(); + JFreeChart chart = (JFreeChart)getObject(); + //panel = new ChartPanel(chart, false, true, true, true, true); + panel = new ChartPanel(chart, + ChartPanel.DEFAULT_WIDTH, + ChartPanel.DEFAULT_HEIGHT, + ChartPanel.DEFAULT_MINIMUM_DRAW_WIDTH, + ChartPanel.DEFAULT_MINIMUM_DRAW_HEIGHT, + ChartPanel.DEFAULT_MAXIMUM_DRAW_WIDTH, + ChartPanel.DEFAULT_MAXIMUM_DRAW_HEIGHT, + false, + false, true, true, true, true); + frame.add(panel); +// frame.repaint(); + frame.validate(); + } + }); + } + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + + } + }); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ChartUtils.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ChartUtils.java new file mode 100644 index 00000000..94eb56da --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ChartUtils.java @@ -0,0 +1,192 @@ +package org.simantics.jfreechart.chart; + +import java.awt.Dimension; +import java.awt.geom.Rectangle2D; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.UUID; + +import org.apache.batik.dom.GenericDOMImplementation; +import org.apache.batik.svggen.SVGGraphics2D; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleActiveExperiment; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.JFreeChartResource; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; + +/** + * Utilities for handling charts + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ChartUtils { + + public static final String emptyVariableName = ""; + + /** + * Creates a new range axis of type jfree.NumberAxis to a plot + * + * @param graph WriteGraph + * @param plot Plot resource + * @return Created number axis, null if not successful + * @throws DatabaseException + */ + public static Resource createNumberRangeAxis(WriteGraph graph, Resource plot) throws DatabaseException { + Resource axis = null; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + if(plot != null) { + // Create range axis + axis = GraphUtils.create2(graph, jfree.NumberAxis, + l0.HasName, "NumberAxis" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(graph, "Y-axis", plot), + jfree.Plot_rangeAxis_Inverse, plot, + l0.PartOf, plot); + + // Add range axis to the plot's range axis list + Resource axisList = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList); + ArrayList list = new ArrayList(); + list.add(axis); + if(axisList == null) { + axisList = ListUtils.create(graph, list); + graph.claim(plot, jfree.Plot_rangeAxisList, axisList); + } else { + ListUtils.insertBack(graph, axisList, list); + } + } + + return axis; + + } + + /** + * Create a XYDataset and map it to axis + * @param graph WriteGraph + * @param plot Plot resource containing the dataset + * @param domainAxis Mapped domain axis for the dataset + * @param rangeAxis Mapped range axis for the dataset + * @return created dataset or null if not successful + * @throws DatabaseException + */ + public static Resource createXYDataset(WriteGraph graph, Resource plot, Resource domainAxis, Resource rangeAxis) throws DatabaseException { + if(plot == null || domainAxis == null || rangeAxis == null) + return null; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + + // Create a dataset for the axis + Resource dataset = GraphUtils.create2(graph, jfree.XYDataset, + l0.HasName, "XYDataset" + UUID.randomUUID().toString(), + jfree.Dataset_mapToDomainAxis, domainAxis, + jfree.Dataset_mapToRangeAxis, rangeAxis, + jfree.Dataset_renderer, GraphUtils.create2(graph, jfree.XYLineRenderer), + l0.PartOf, plot); + + return dataset; + } + + /** + * Creates a new series to a dataset + * @param graph WriteGraph + * @param dataset Dataset for the new series + * @return created series or null if unsuccessful + * @throws DatabaseException + */ + public static Resource createSeries(WriteGraph graph, Resource dataset, String rvi) throws DatabaseException { + if(dataset == null) return null; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + // Create series + Resource series = GraphUtils.create2(graph, jfree.Series, + l0.HasName, "Series" + UUID.randomUUID().toString(), + jfree.variableRVI, rvi == null ? " " + emptyVariableName : rvi, + l0.PartOf, dataset); + + // Add series to the dataset's series list + Resource seriesList = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + ArrayList list = new ArrayList(); + list.add(series); + if(seriesList == null) { + seriesList = ListUtils.create(graph, list); + graph.claim(dataset, jfree.Dataset_seriesList, seriesList); + } else { + ListUtils.insertBack(graph, seriesList, list); + } + + return series; + } + + /** + * Find the current realization uri + * + * @param graph ReadGraph + * @param chartComponent A resource from a chart (consistsOf relation in a chart) + * @return current realization uri + * @throws DatabaseException + */ + public static String getCurrentRealizationURI(ReadGraph graph, Resource chartComponent) throws DatabaseException { + // Find the model where the chart is located + Resource model = graph.syncRequest(new PossibleModel(chartComponent)); + if(model == null) + return null; + + // Find the variable realization of the current experiment + String realizationURI = null; + Resource realization = graph.syncRequest(new PossibleActiveExperiment(model)); + if (realization == null) { + Layer0X L0X = Layer0X.getInstance(graph); + realization = graph.getPossibleObject(model, L0X.HasBaseRealization); + } + if (realization != null) + realizationURI = graph.getURI(realization); + + return realizationURI; + } + + public static void writeSVG(org.jfree.chart.JFreeChart chart, Rectangle2D bounds, Writer out) throws IOException { + // Get a DOMImplementation. + DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation(); + + // Create an instance of org.w3c.dom.Document. + Document document = domImpl.createDocument(null, "svg", null); + + // Create an instance of the SVG Generator. + SVGGraphics2D svgGenerator = new SVGGraphics2D(document); + + // Paint chart panel + svgGenerator.setSVGCanvasSize(new Dimension((int)bounds.getWidth(), (int)bounds.getHeight())); + chart.draw(svgGenerator, bounds); + + // Finally, write to out + svgGenerator.stream(out, false); + + } + + public static void writeSVG(org.jfree.chart.JFreeChart chart, Rectangle2D bounds, File file) throws IOException { + OutputStream outputStream = new FileOutputStream(file); + Writer out = new OutputStreamWriter(outputStream, "UTF-8"); + writeSVG(chart, bounds, out); + outputStream.flush(); + outputStream.close(); + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/DeviationRenderer.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/DeviationRenderer.java new file mode 100644 index 00000000..716bb682 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/DeviationRenderer.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.labels.StandardXYToolTipGenerator; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +public class DeviationRenderer extends AbstractRenderer { + + public DeviationRenderer(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + private org.jfree.chart.renderer.xy.DeviationRenderer renderer; + + @Override + public org.jfree.chart.renderer.AbstractRenderer getRenderer() { + if(renderer == null) { + renderer = new org.jfree.chart.renderer.xy.DeviationRenderer(); + renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); + } + return renderer; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ExtendedNumberAxis.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ExtendedNumberAxis.java new file mode 100644 index 00000000..0587a58b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ExtendedNumberAxis.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.data.Range; + +/** + * NumberAxis that supports adding only one bound, lower or upper. + * The standard NumberAxis disables auto adjusting if even one of the bounds is set + * + * @author Teemu Lempinen + * + */ +public class ExtendedNumberAxis extends org.jfree.chart.axis.NumberAxis { + private static final long serialVersionUID = 3066266986472919998L; + + private Double lower = null; + private Double upper = null; + /** + * Use own lower and upper bounds to support using only one of them + */ + protected void autoAdjustRange() { + super.autoAdjustRange(); + Range range = getRange(); + Double lower = this.lower == null ? range.getLowerBound() : this.lower; + Double upper = this.upper == null ? range.getUpperBound() : this.upper; + if(lower > upper) + upper = lower + 1; + if(upper - lower < getAutoRangeMinimumSize()) + upper = lower + getAutoRangeMinimumSize(); + + setRange(new Range(lower, upper), false, false); + + } + + public void setLower(Double lower) { + this.lower = lower; + } + + public void setUpper(Double upper) { + this.upper = upper; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteredDataset.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteredDataset.java new file mode 100644 index 00000000..1d11f122 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteredDataset.java @@ -0,0 +1,26 @@ +package org.simantics.jfreechart.chart; + +/** + * Interface for configuring data filtering. + * + * @author Marko Luukkainen + * + */ +public interface FilteredDataset { + + public boolean isFiltering(); + public void setFiltering(boolean filtering); + + + public double getFilterFraction(); + /** + * Sets filtering fraction 0 <= fraction <= 1 + * With filtering fraction 0 nothing gets filtered. + * With filtering fraction 1 everything gets filtered. + * + * @param filterFraction + */ + public void setFilterFraction(double filterFraction); + + public void updateFiltered(); +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringCategoryDataset.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringCategoryDataset.java new file mode 100644 index 00000000..ec719f95 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringCategoryDataset.java @@ -0,0 +1,179 @@ +package org.simantics.jfreechart.chart; + +/** + * Filters CategoryDataset by creating "Other" item for filtered data. + * + * @author Marko Luukkainen + * + */ +import java.util.List; + +import org.jfree.data.category.DefaultCategoryDataset; +import org.jfree.data.general.AbstractDataset; +import org.jfree.data.general.DatasetChangeEvent; + +@SuppressWarnings("rawtypes") +public class FilteringCategoryDataset extends AbstractDataset implements org.jfree.data.category.CategoryDataset, FilteredDataset{ + + private static final long serialVersionUID = -4955124650051030544L; + + org.jfree.data.category.CategoryDataset original; + DefaultCategoryDataset filtered; + org.jfree.data.category.CategoryDataset used; + + boolean filterRows = true; + boolean filtering = true; + double filterFraction = 0.05; + private Comparable other; + + public FilteringCategoryDataset(org.jfree.data.category.CategoryDataset dataset, Comparable other) { + this.original = dataset; + this.filtered = new DefaultCategoryDataset(); + this.other = other; + this.used = filtered; + updateFiltered(); + } + + @Override + public boolean isFiltering() { + return filtering; + } + + @Override + public void setFiltering(boolean filtering) { + this.filtering = filtering; + if (filtering) + used = filtered; + else + used = original; + fireDatasetChanged(); + } + + public void setFilterFraction(double filterFraction) { + this.filterFraction = filterFraction; + } + + public double getFilterFraction() { + return filterFraction; + } + + /** + * Filter rows or columns. + * @param filterRows + */ + public void setFilterRows(boolean filterRows) { + this.filterRows = filterRows; + } + + public boolean isFilterRows() { + return filterRows; + } + + public void updateFiltered() { + filtered.clear(); + if (filterRows) { + for (Object column : original.getColumnKeys()) { + Double total = 0.0; + Double other = 0.0; + for (Object row : original.getRowKeys()) { + Number value = original.getValue((Comparable) row, (Comparable)column); + if (value != null) + total+=value.doubleValue(); + } + total *= filterFraction; + for (Object row : original.getRowKeys()) { + Number value = original.getValue((Comparable) row, (Comparable)column); + if (value == null) + continue; + if (value.doubleValue() > total) { + filtered.addValue(value, (Comparable) row, (Comparable)column); + } else { + other += value.doubleValue(); + } + } + if (other > 0.0) { + filtered.addValue(other, this.other, (Comparable)column); + } + } + } else { + for (Object row : original.getRowKeys()) { + Double total = 0.0; + Double other = 0.0; + for (Object column : original.getColumnKeys()) { + Number value = original.getValue((Comparable) row, (Comparable)column); + if (value != null) + total += value.doubleValue(); + } + total *= filterFraction; + for (Object column : original.getColumnKeys()) { + Number value = original.getValue((Comparable) row, (Comparable)column); + if (value == null) + continue; + if (value.doubleValue() > total) { + filtered.addValue(value, (Comparable) row, (Comparable)column); + } else { + other += value.doubleValue(); + } + } + if (other > 0.0) { + filtered.addValue(other, (Comparable)row, this.other); + } + } + } + fireDatasetChanged(); + } + + @Override + public int getColumnCount() { + return used.getColumnCount(); + } + + @Override + public int getRowCount() { + return used.getRowCount(); + } + + @Override + public Number getValue(Comparable rowKey, Comparable columnKey) { + return used.getValue(rowKey, columnKey); + } + + @Override + public Number getValue(int row, int column) { + return used.getValue(row, column); + } + + @Override + public List getColumnKeys() { + return used.getColumnKeys(); + } + + @Override + public Comparable getColumnKey(int column) { + return used.getColumnKey(column); + } + + @Override + public List getRowKeys() { + return used.getRowKeys(); + } + + @Override + public Comparable getRowKey(int row) { + return used.getRowKey(row); + } + + @Override + public int getRowIndex(Comparable key) { + return used.getRowIndex(key); + } + + @Override + public int getColumnIndex(Comparable key) { + return used.getColumnIndex(key); + } + + + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringPieDataset.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringPieDataset.java new file mode 100644 index 00000000..249c2aa6 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/FilteringPieDataset.java @@ -0,0 +1,117 @@ +package org.simantics.jfreechart.chart; + +import java.util.List; + +import org.jfree.data.general.AbstractDataset; +import org.jfree.data.general.DatasetChangeEvent; +import org.jfree.data.general.DefaultPieDataset; +import org.jfree.data.general.PieDataset; + +/** + * Filters PieDataset by creating "Other" item for filtered data. + * + * @author Marko Luukkainen + * + */ +@SuppressWarnings("rawtypes") +public class FilteringPieDataset extends AbstractDataset implements PieDataset, FilteredDataset{ + + private static final long serialVersionUID = -4955124650051030544L; + + PieDataset original; + DefaultPieDataset filtered; + PieDataset used; + + + boolean filtering = true; + double filterFraction = 0.05; + + private Comparable other = "other"; + + public FilteringPieDataset(PieDataset dataset, Comparable other) { + this.original = dataset; + this.filtered = new DefaultPieDataset(); + this.other = other; + this.used = filtered; + updateFiltered(); + } + + @Override + public boolean isFiltering() { + return filtering; + } + + @Override + public void setFiltering(boolean filtering) { + this.filtering = filtering; + if (filtering) + used = filtered; + else + used = original; + fireDatasetChanged(); + } + + + public void setFilterFraction(double filterFraction) { + this.filterFraction = filterFraction; + } + + public double getFilterFraction() { + return filterFraction; + } + + public void updateFiltered() { + filtered.clear(); + Double total = 0.0; + Double other = 0.0; + for (Object key : original.getKeys()) { + total += original.getValue((Comparable) key).doubleValue(); + } + total *= filterFraction; + for (Object key : original.getKeys()) { + Number value = original.getValue((Comparable) key).doubleValue(); + + if (value.doubleValue() > total) { + filtered.setValue((Comparable) key,value); + } else { + other += value.doubleValue(); + } + } + if (other > 0.0) { + filtered.setValue(this.other, other); + } + fireDatasetChanged(); + + } + + @Override + public List getKeys() { + return used.getKeys(); + } + + @Override + public int getItemCount() { + return used.getItemCount(); + } + + @Override + public Comparable getKey(int index) { + return used.getKey(index); + } + + @Override + public int getIndex(Comparable key) { + return used.getIndex(key); + } + + @Override + public Number getValue(Comparable key) { + return used.getValue(key); + } + + @Override + public Number getValue(int index) { + return used.getValue(index); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IAxis.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IAxis.java new file mode 100644 index 00000000..c92f2438 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IAxis.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.axis.Axis; +import org.simantics.db.exception.DatabaseException; + +/** + * Interface for JFreeChart.Axis type resource + * + * @author Teemu Lempinen + * + */ +public interface IAxis extends IJFreeChartComponent { + + /** + * Returns the axis + * + * @return + * @throws DatabaseException + */ + public Axis getAxis(); + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IDataset.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IDataset.java new file mode 100644 index 00000000..6af906eb --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IDataset.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.renderer.AbstractRenderer; +import org.jfree.data.general.Dataset; +import org.simantics.db.Resource; + +/** + * Interface for JFreeChart.Dataset type resource + * @author Teemu Lempinen + * + */ +public interface IDataset extends IJFreeChartComponent { + + /** + * Returns the JFreeChart dataset represented by the associated resource + * + * @return JFreeChart dataset + */ + public Dataset getDataset(); + + + /** + * Returns the renderer for this dataset + * + * @return JFreeChart renderer + */ + public AbstractRenderer getRenderer(); + + /** + * Returns the resource of this dataset + * + * @return + */ + public Resource getResource(); +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IJFreeChart.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IJFreeChart.java new file mode 100644 index 00000000..f03d7b45 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IJFreeChart.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.JFreeChart; +import org.simantics.db.exception.DatabaseException; +/** + * Interface for JFreeChart.Chart type resource + * + * @author Teemu Lempinen + * + */ +public interface IJFreeChart extends IJFreeChartComponent { + + /** + * Returns the chart + * + * @return + * @throws DatabaseException + */ + public JFreeChart getChart(); + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IJFreeChartComponent.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IJFreeChartComponent.java new file mode 100644 index 00000000..27e1d4cc --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IJFreeChartComponent.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +/** + * Interface for all components that are used to create JFreeCharts based on org.simantics.jfreechart ontology + * @author Teemu Lempinen + * + */ +public interface IJFreeChartComponent { + + /** + * Dispose this component. Disposing a component may be useful + * if the component contains listeners that need to be disposed. + */ + public void dispose(); + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IPlot.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IPlot.java new file mode 100644 index 00000000..c040a5f5 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IPlot.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.plot.Plot; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; + +/** + * Interface for JFreeChart.Plot type resource + * + * @author Teemu Lempinen + * + */ +public interface IPlot extends IJFreeChartComponent { + + /** + * Returns the plot + * + * @return Title + * @throws DatabaseException + */ + public Plot getPlot(); + + /** + * Returns the resource of this plot + * + * @return + */ + public Resource getResource(); + + public void configurePlot(); + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IRenderer.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IRenderer.java new file mode 100644 index 00000000..7f68e8f1 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/IRenderer.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.renderer.AbstractRenderer; +import org.simantics.db.Resource; + +/** + * Interface for JFreeChart.Renderer type resource + * @author Teemu Lempinen + * + */ +public interface IRenderer extends IJFreeChartComponent { + + /** + * Returns the JFreeChart AbstractRenderer represented by the associated resource + * + * @return JFreeChart renderer + */ + public AbstractRenderer getRenderer(); + + /** + * Returns the resource of this renderer + * @return + */ + public Resource getResource(); + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ITitle.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ITitle.java new file mode 100644 index 00000000..aa50612f --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ITitle.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.title.Title; +import org.simantics.db.exception.DatabaseException; + +/** + * Interface for JFreeChart.Title type resource + * + * @author Teemu Lempinen + * + */ +public interface ITitle extends IJFreeChartComponent { + + /** + * Returns the title + * + * @return Title + * @throws DatabaseException + */ + public Title getTitle(); + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/JFreeChart.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/JFreeChart.java new file mode 100644 index 00000000..ea8df3d6 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/JFreeChart.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import java.awt.Color; +import java.awt.Font; +import java.util.Collection; + +import javax.swing.SwingUtilities; + +import org.jfree.chart.title.LegendTitle; +import org.jfree.chart.title.TextTitle; +import org.jfree.ui.RectangleInsets; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; + +/** + * Class representing a complete JFreeChart.Chart + * + * This class supports all types of charts. The details of the chart are + * defined in plots and other adapted classes. + * + * @author Teemu Lempinen + * + */ +public class JFreeChart implements IJFreeChart { + + private org.jfree.chart.JFreeChart jfreechart; + private IPlot plot; + private ITitle title; + private Resource chartResource; + + /** + * + * @param graph ReadGraph + * @param chartResource Resource of type JFreeChart.Chart + */ + public JFreeChart(ReadGraph graph, Resource chartResource) { + this.chartResource = chartResource; + + try { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Collection plotsCollection = graph.syncRequest(new ObjectsWithType(chartResource, l0.ConsistsOf, jfree.Plot)); + for(Resource plotResource : plotsCollection) { + this.plot = graph.adapt(plotResource, IPlot.class); + } + + } catch(DatabaseException e) { + e.printStackTrace(); + } + } + + + JFreeChartListener listener; + + /** + * Returns a new chart using the information collected in the constructor + */ + @Override + public org.jfree.chart.JFreeChart getChart() { + if(plot == null) + return null; + + if(jfreechart == null) + jfreechart = new org.jfree.chart.JFreeChart(plot.getPlot()); + + if(listener == null) { + listener = new JFreeChartListener(); + SimanticsUI.getSession().asyncRequest(new Read>() { + + @Override + public Pair perform(ReadGraph graph) throws DatabaseException { + if(chartResource == null || !graph.hasStatement(chartResource)) + return null; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource titleResource = graph.syncRequest(new PossibleObjectWithType(chartResource, l0.ConsistsOf, jfree.Title)); + title = graph.adapt(titleResource, ITitle.class); + Boolean legendVisible = graph.getPossibleRelatedValue(chartResource, jfree.Chart_visibleLegend, Bindings.BOOLEAN); + return new Pair(title, legendVisible); + } + }, listener); + } + + return jfreechart; + } + + @Override + public void dispose() { + // Call dispose to title and plots to disable their possible listeners + if(title != null) + title.dispose(); + if(listener != null) + listener.dispose(); + if(plot != null) + plot.dispose(); + } + + + private class JFreeChartListener implements Listener> { + + private boolean disposed = false; + private LegendTitle legend; + + public void dispose() { + disposed = true; + } + + @Override + public void execute(final Pair result) { + if(result == null) + return; + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if(jfreechart == null) + return; + + jfreechart.setBackgroundPaint(Color.WHITE); + + if(jfreechart.getLegend() != null && !jfreechart.getLegend().equals(legend)) { + legend = jfreechart.getLegend(); + legend.setBorder(0, 0, 0, 0); + int size = legend.getItemFont().getSize(); + legend.setItemFont(new Font("helvetica", Font.PLAIN, size)); + } + + if(Boolean.FALSE.equals(result.second)) { + jfreechart.removeLegend(); + } else if (jfreechart.getLegend() == null && legend != null){ + jfreechart.addLegend(legend); + } + + TextTitle t = (org.jfree.chart.title.TextTitle)result.first.getTitle(); + if(t.isVisible()) { + t.setFont(new Font("georgia", Font.BOLD, 13)); + t.setPadding(new RectangleInsets(4, 0, 0, 0)); + jfreechart.setTitle(t); + } else { + jfreechart.setTitle((TextTitle)null); + } + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/NumberAxis.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/NumberAxis.java new file mode 100644 index 00000000..4f070631 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/NumberAxis.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.axis.Axis; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Class representing a JFreeChart.NumberAxis + * + * @author Teemu Lempinen + * + */ +public class NumberAxis extends AbstractAxis { + + /** + * + * @param graph ReadGraph + * @param axisResource resource of type JFreeChart.NumberAxis + */ + public NumberAxis(ReadGraph graph, Resource axisResource) { + super(graph, axisResource); + } + + + @Override + public Axis getAxis() { + axis = new ExtendedNumberAxis(); + ((ExtendedNumberAxis)axis).setLower(min); + ((ExtendedNumberAxis)axis).setUpper(max); + return super.getAxis(); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PieDataset.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PieDataset.java new file mode 100644 index 00000000..c45eb951 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PieDataset.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import java.awt.Color; +import java.util.HashMap; + +/** + * Class representing a PieDataset in JFreeChart ontology + * @author Teemu Lempinen + * + */ +public interface PieDataset> extends IDataset { + + + /** + * Map of colors for different slices in a pie chart. Name + * indicates the key of the value. + * @return Map of colors for different slices in a pie chart + */ + public HashMap getColorMap(); + + + /** + * Map of exploded statuses for slices in a pie chart. Name + * indicates the key of the slice. + * @return + */ + public HashMap getExplodedMap(); + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PiePlot.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PiePlot.java new file mode 100644 index 00000000..9c4f1193 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/PiePlot.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import java.awt.Color; +import java.awt.Font; +import java.util.HashMap; + +import org.jfree.chart.labels.StandardPieSectionLabelGenerator; +import org.jfree.chart.labels.StandardPieToolTipGenerator; +import org.jfree.chart.plot.DefaultDrawingSupplier; +import org.jfree.chart.plot.Plot; +import org.jfree.data.general.Dataset; +import org.jfree.data.general.DatasetChangeEvent; +import org.jfree.data.general.DatasetChangeListener; +import org.jfree.ui.RectangleInsets; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Class representing a PiePlot in JFreeChart ontology + * + * @author Teemu Lempinen + * + */ +public class PiePlot extends AbstractPlot { + + private org.jfree.data.general.PieDataset pieDataset; + private DatasetChangeListener listener; + + public PiePlot(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + /** + * Pie plot class with a stricter equals condition + * @author Teemu Lempinen + * + */ + private class MyPiePlot extends org.jfree.chart.plot.PiePlot { + + private static final long serialVersionUID = -5917620061541212934L; + + @Override + public boolean equals(Object obj) { + boolean result = super.equals(obj); + if(result == true) { + org.jfree.chart.plot.PiePlot that = (org.jfree.chart.plot.PiePlot) obj; + if (this.getDataset() != that.getDataset()) { + return false; // Normally plot does not check this. We need this to properly update the charts + } + } + + return result; + } + + } + + @Override + protected Plot newPlot() { + MyPiePlot plot = new MyPiePlot(); + plot.setToolTipGenerator(new StandardPieToolTipGenerator()); + return plot; + } + + @Override + protected void getOtherProperties(ReadGraph graph, PlotProperties properties) throws DatabaseException { + Boolean labelsVisible = graph.getPossibleRelatedValue(resource, JFreeChartResource.getInstance(graph).Plot_visibleLabels, Bindings.BOOLEAN); + properties.otherProperties.put("labelsVisible", labelsVisible); + + Boolean useFilter = graph.getPossibleRelatedValue(resource, JFreeChartResource.getInstance(graph).Filter_used, Bindings.BOOLEAN); + Double filterFraction = graph.getPossibleRelatedValue(resource, JFreeChartResource.getInstance(graph).Filter_fraction, Bindings.DOUBLE); + properties.otherProperties.put("useFilter", useFilter); + properties.otherProperties.put("filterFraction", filterFraction); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + protected void setPlotProperties(PlotProperties properties) { + if(!(plot instanceof MyPiePlot)) + return; + + final MyPiePlot piePlot = (MyPiePlot)plot; + + if(!properties.datasets.isEmpty()) { + // We assume that a pie plot has only one dataset + final IDataset ds = properties.datasets.get(0); + Dataset dataset = ((PieDataset)ds).getDataset(); + + if(dataset == null) + return; + + if(pieDataset != null && listener != null) { + pieDataset.removeChangeListener(listener); + } + + pieDataset = (org.jfree.data.general.PieDataset)dataset; + piePlot.setDataset(pieDataset); + + if (pieDataset instanceof FilteredDataset) { + FilteredDataset f = (FilteredDataset)pieDataset; + Boolean useFilter = (Boolean)properties.otherProperties.get("useFilter"); + Double filterFraction = (Double)properties.otherProperties.get("filterFraction"); + if (useFilter != null && filterFraction != null) { + f.setFiltering(useFilter); + f.setFilterFraction(filterFraction*0.01); + f.updateFiltered(); + } else { + f.setFiltering(false); + } + } + + Boolean labelsVisible = (Boolean)properties.otherProperties.get("labelsVisible"); + if(Boolean.FALSE.equals(labelsVisible)) + piePlot.setLabelGenerator(null); + else if(piePlot.getLabelGenerator() == null) + piePlot.setLabelGenerator(new StandardPieSectionLabelGenerator()); + + listener = new DatasetChangeListener() { + + @Override + public void datasetChanged(DatasetChangeEvent event) { + HashMap, Color> colorMap = ((PieDataset)ds).getColorMap(); + HashMap, Boolean> explodedMap = ((PieDataset)ds).getExplodedMap(); + + for(Object o : piePlot.getDataset().getKeys()) { + if(o instanceof Comparable) { + Comparable key = (Comparable)o; + if(explodedMap.containsKey(key) && explodedMap.get(key)) { + piePlot.setExplodePercent(key, 0.3); + + } else { + piePlot.setExplodePercent(key, 0); + } + } + } + + for(Comparable name : explodedMap.keySet()) { + Boolean exploded = explodedMap.get(name); + if(Boolean.TRUE.equals(exploded)) + piePlot.setExplodePercent(name, 0.3); + } + piePlot.clearSectionPaints(false); + piePlot.setDrawingSupplier(new DefaultDrawingSupplier()); + for(Comparable name : colorMap.keySet()) + piePlot.setSectionPaint(name, colorMap.get(name)); + } + }; + + pieDataset.addChangeListener(listener); + } + + // Cleaner look: no outline borders + piePlot.setInsets(new RectangleInsets(0,0,0,0), false); + piePlot.setOutlineVisible(false); + piePlot.setLabelBackgroundPaint(Color.WHITE); + piePlot.setLabelFont(new Font("helvetica", Font.PLAIN, 11)); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/StackedBarRenderer.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/StackedBarRenderer.java new file mode 100644 index 00000000..a7da60cc --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/StackedBarRenderer.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.labels.StandardCategoryToolTipGenerator; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Stacked bar renderer + * @author Teemu Lempinen + * + */ +public class StackedBarRenderer extends AbstractRenderer { + + public StackedBarRenderer(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + private org.jfree.chart.renderer.category.StackedBarRenderer renderer; + + @Override + public org.jfree.chart.renderer.AbstractRenderer getRenderer() { + if(renderer == null) { + renderer = new org.jfree.chart.renderer.category.StackedBarRenderer(); + renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator()); + } + return renderer; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/TextTitle.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/TextTitle.java new file mode 100644 index 00000000..bdb73de1 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/TextTitle.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.title.Title; +import org.jfree.ui.RectangleEdge; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Class representing a JFreeChart.TextTitle + * @author Teemu Lempinen + * + */ +public class TextTitle implements ITitle { + + private org.jfree.chart.title.TextTitle textTitle; + private RectangleEdge position; + private String text; + private Boolean visible; + + public TextTitle(ReadGraph graph, Resource titleResource) { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + try { + text = graph.getPossibleRelatedValue(titleResource, l0.HasLabel, Bindings.STRING); + Resource pos = graph.getPossibleObject(titleResource, jfree.Title_position); + position = getRectangleEdgePosition(graph, pos); + visible = graph.getPossibleRelatedValue(titleResource, jfree.visible, Bindings.BOOLEAN); + + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + /** + * Get the RectangleEdge representation for Resource position (JFreeChart.Position) + * @param graph ReadGraph + * @param position Resource of type JFreeChart.Position + * @return RectangleEdge representation for Resource position + */ + private RectangleEdge getRectangleEdgePosition(ReadGraph graph, Resource position) { + if(position == null) + return null; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + if(position.equals(jfree.Top)) + return RectangleEdge.TOP; + else if(position.equals(jfree.Bottom)) + return RectangleEdge.BOTTOM; + else if(position.equals(jfree.Left)) + return RectangleEdge.LEFT; + else if(position.equals(jfree.Right)) + return RectangleEdge.RIGHT; + else + return null; + + } + + @Override + public Title getTitle() { + textTitle = new org.jfree.chart.title.TextTitle(text); + if(position != null) + textTitle.setPosition(position); + if(visible != null) + textTitle.setVisible(visible); + return textTitle; + } + + @Override + public void dispose() { + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYAreaRenderer.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYAreaRenderer.java new file mode 100644 index 00000000..6c680348 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYAreaRenderer.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.labels.StandardXYToolTipGenerator; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Renderer representing jfree chart renderer for xy areas + * @author Teemu Lempinen + * + */ +public class XYAreaRenderer extends AbstractRenderer { + + private org.jfree.chart.renderer.xy.XYAreaRenderer renderer; + + public XYAreaRenderer(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + @Override + public org.jfree.chart.renderer.AbstractRenderer getRenderer() { + if(renderer == null) { + renderer = new org.jfree.chart.renderer.xy.XYAreaRenderer(); + renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); + } + return renderer; + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYDataset.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYDataset.java new file mode 100644 index 00000000..d7433d64 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYDataset.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + + +/** + * Class representing a JFreeChart.XYDataset + * + * @author Teemu Lempinen + * + */ +public interface XYDataset extends IDataset { + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYLineRenderer.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYLineRenderer.java new file mode 100644 index 00000000..7d5abb22 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYLineRenderer.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.labels.StandardXYToolTipGenerator; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Renderer representing jfree chart renderer for xy lines + * @author Teemu Lempinen + * + */ +public class XYLineRenderer extends AbstractRenderer { + + XYLineAndShapeRenderer renderer; + + public XYLineRenderer(ReadGraph graph, Resource resource) { + super(graph, resource); + } + + @Override + public org.jfree.chart.renderer.AbstractRenderer getRenderer() { + if(renderer == null) { + renderer = new XYLineAndShapeRenderer(true, false); + renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); + } + return renderer; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYPlot.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYPlot.java new file mode 100644 index 00000000..4ffae630 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/XYPlot.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart; + +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.plot.Plot; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.renderer.xy.XYItemRenderer; +import org.jfree.data.xy.XYDataset; +import org.jfree.ui.RectangleInsets; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Class representing a JFreeChart.XYPlot + * + * @author Teemu Lempinen + * + */ +public class XYPlot extends AbstractPlot { + + public XYPlot(ReadGraph graph, Resource plotResource) { + super(graph, plotResource); + } + + @Override + protected Plot newPlot() { + return new org.jfree.chart.plot.XYPlot(null, null, null, null); + } + + @Override + protected void getOtherProperties(ReadGraph graph, PlotProperties properties) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Boolean visibleGrid = graph.getPossibleRelatedValue(resource, jfree.Plot_visibleGrid); + properties.otherProperties.put("visibleGrid", visibleGrid); + if(!properties.datasets.isEmpty()) { + IDataset idataset = properties.datasets.get(0); + Resource renderer = graph.getPossibleObject(idataset.getResource(), jfree.Dataset_renderer); + if(renderer != null) { + properties.otherProperties.put("renderer", graph.adapt(renderer, IRenderer.class)); + } + } + } + + @Override + protected void setPlotProperties(PlotProperties properties) { + if(!(plot instanceof org.jfree.chart.plot.XYPlot)) + return; + + org.jfree.chart.plot.XYPlot xyplot = (org.jfree.chart.plot.XYPlot)plot; + xyplot.clearDomainAxes(); + xyplot.clearRangeAxes(); + + for(int i = 0; i < properties.ranges.size(); i++) { + xyplot.setRangeAxis(i, (ValueAxis)properties.ranges.get(i).getAxis()); + } + + for(int i = 0; i < properties.domains.size(); i++) { + xyplot.setDomainAxis(i, (ValueAxis)properties.domains.get(i).getAxis()); + } + + IAxis axis; + for(int i = 0; i < properties.datasets.size(); i++) { + IDataset dataset = properties.datasets.get(i); + xyplot.setDataset(i, (XYDataset)dataset.getDataset()); + xyplot.setRenderer(i, (XYItemRenderer)dataset.getRenderer()); + axis = properties.rangeMappings.get(dataset); + if(axis != null && properties.ranges.contains(axis)) + xyplot.mapDatasetToRangeAxis(i, properties.ranges.indexOf(axis)); + axis = properties.domainMappings.get(dataset); + if(axis != null && properties.ranges.contains(axis)) + xyplot.mapDatasetToDomainAxis(i, properties.domains.indexOf(axis)); + } + + Boolean visibleGrid = (Boolean)properties.otherProperties.get("visibleGrid"); + if(visibleGrid == null) + visibleGrid = true; + + Boolean orientation = (Boolean)properties.otherProperties.get("orientation"); + if(orientation != null) { + if (orientation) + xyplot.setOrientation(PlotOrientation.HORIZONTAL); + else + xyplot.setOrientation(PlotOrientation.VERTICAL); + } + + xyplot.setRangeGridlinesVisible(visibleGrid); + xyplot.setDomainGridlinesVisible(visibleGrid); + + // Cleaner look: no outline borders + xyplot.setInsets(new RectangleInsets(2,5,2,10), false); + xyplot.setOutlineVisible(false); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartBoundsOutline.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartBoundsOutline.java new file mode 100644 index 00000000..990ff4f1 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartBoundsOutline.java @@ -0,0 +1,37 @@ +package org.simantics.jfreechart.chart.element; + +import java.awt.geom.Rectangle2D; + +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.LifeCycle; +import org.simantics.g2d.element.handler.impl.BoundsOutline; + +/** + * Outline with default bounds. Needed to avoid crashing when trying to rotate chart elements. + * @author Teemu Lempinen + * + */ +public class ChartBoundsOutline extends BoundsOutline implements LifeCycle { + private static final long serialVersionUID = -3819495313008722843L; + + Rectangle2D defaultBounds; + + public ChartBoundsOutline(Rectangle2D defaultBounds) { + this.defaultBounds = defaultBounds; + } + + @Override + public void onElementCreated(IElement e) { + e.setHint(ElementHints.KEY_BOUNDS, defaultBounds); + } + + @Override + public void onElementDestroyed(IElement e) {} + @Override + public void onElementActivated(IDiagram d, IElement e) {} + @Override + public void onElementDeactivated(IDiagram d, IElement e) {} + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartElementFactory.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartElementFactory.java new file mode 100644 index 00000000..c1eb01a6 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartElementFactory.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.element; + +import java.awt.BasicStroke; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; +import java.awt.geom.QuadCurve2D; +import java.awt.geom.Rectangle2D; + +import org.jfree.chart.JFreeChart; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.adapter.ElementFactory; +import org.simantics.diagram.adapter.SyncElementFactory; +import org.simantics.diagram.elements.ElementPropertySetter; +import org.simantics.diagram.synchronization.CompositeHintSynchronizer; +import org.simantics.diagram.synchronization.IHintSynchronizer; +import org.simantics.diagram.synchronization.SynchronizationHints; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.diagram.synchronization.graph.RemoveElement; +import org.simantics.diagram.synchronization.graph.TransformSynchronizer; +import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.LifeCycle; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; +import org.simantics.jfreechart.chart.IJFreeChart; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; + +/** + * Element factory for creating chart elements to diagrams + * + * @author Teemu Lempinen + * + */ +public class ChartElementFactory extends SyncElementFactory { + + private static final String CLASS_ID = "Chart"; + public static final ElementFactory INSTANCE = new ChartElementFactory(); + public static final Image STATIC_IMAGE = new ShapeImage(getChartShape(), null, new BasicStroke(1f), true); + public static final double SYMBOL_CHART_SIZE = 10.0; + public static final Key KEY_CHART_COMPONENT = new KeyOf(Resource.class, "CHART_COMPONENT"); + public static final Key KEY_CHART = new KeyOf(JFreeChart.class, "CHART"); + + static Shape getChartShape() { + + Path2D path = new Path2D.Double(); + // First create the axis for a chart symbol + path.moveTo(-SYMBOL_CHART_SIZE, -SYMBOL_CHART_SIZE); + path.lineTo(-SYMBOL_CHART_SIZE, SYMBOL_CHART_SIZE); + path.lineTo( SYMBOL_CHART_SIZE, SYMBOL_CHART_SIZE); + + // Then a curve to the chart + QuadCurve2D curve = new QuadCurve2D.Double( + -SYMBOL_CHART_SIZE + 1, SYMBOL_CHART_SIZE - 1, + SYMBOL_CHART_SIZE - 5, SYMBOL_CHART_SIZE - 5, + SYMBOL_CHART_SIZE - 1, -SYMBOL_CHART_SIZE + 3); + + // Connect shapes + path.append(curve, false); + return path; + } + + // Hint synchronizer for synchronizing transform and bounds + private static final IHintSynchronizer HINT_SYNCHRONIZER = new CompositeHintSynchronizer( + TransformSynchronizer.INSTANCE); + + public static ElementClass create(ReadGraph graph, Resource chart) throws DatabaseException { + return ElementClass.compile( + new ChartSceneGraph(), + new Initializer(chart), + new StaticObjectAdapter(JFreeChartResource.getInstance(graph).ChartElement), + DefaultTransform.INSTANCE, + StaticSymbolImageInitializer.INSTANCE, + new StaticSymbolImpl(STATIC_IMAGE), + new ChartBoundsOutline(new Rectangle2D.Double(-20, -20, 60, 40)), + new ElementPropertySetter(ChartSceneGraph.KEY_SG_NODE) + ).setId(CLASS_ID); + } + + public ElementClass create(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType) throws DatabaseException { + return create(graph, null); + } + + @Override + public void load(ReadGraph g, ICanvasContext canvas, final IDiagram diagram, Resource element, final IElement e) throws DatabaseException { + + Resource chartResource; + ElementPropertySetter ps = e.getElementClass().getSingleItem(ElementPropertySetter.class); + ps.loadProperties(e, element, g); + + AffineTransform at = DiagramGraphUtil.getAffineTransform(g, element); + // Hack for disabling all rotations in chart elements + double x = at.getTranslateX(); + double y = at.getTranslateY(); + at.setToRotation(0); + at.setToTranslation(x, y); + ElementUtils.setTransform(e, at); // Set hint transform without rotations + ps.overrideProperty(e, "Transform", at); // Set property Transform without rotations + + e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, HINT_SYNCHRONIZER); + + + Object o = e.getHint(KEY_CHART_COMPONENT); + if(o == null || !(o instanceof Resource)) { + chartResource = g.getPossibleObject(element, JFreeChartResource.getInstance(g).ChartElement_component); + } else { + chartResource = (Resource)o; + } + + if(chartResource == null || !g.hasStatement(chartResource)) { + // Remove element if there is no chart resource for it + g.asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + new RemoveElement( + (Resource)diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE), + (Resource)e.getHint(ElementHints.KEY_OBJECT)) + .perform(graph); + } + }); + return; + } + + IJFreeChart ichart = g.adapt(chartResource, IJFreeChart.class); + + if(ichart != null) { + JFreeChart chart = ichart.getChart(); + e.setHint(KEY_CHART, chart); + } + + } + + + /** + * Initializer for setting a chart component for element + * @author Teemu Lempinen + * + */ + static class Initializer implements LifeCycle { + private static final long serialVersionUID = -5822080013184271204L; + Object component; + + Initializer(Object component) { + this.component = component; + } + + @Override + public void onElementCreated(IElement e) { + if(component != null) e.setHint(KEY_CHART_COMPONENT, component); + } + + @Override + public void onElementActivated(IDiagram d, IElement e) {} + @Override + public void onElementDeactivated(IDiagram d, IElement e) {} + @Override + public void onElementDestroyed(IElement e) {} + }; +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartElementWriter.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartElementWriter.java new file mode 100644 index 00000000..2fe7fc13 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartElementWriter.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.element; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.synchronization.graph.ElementWriter; +import org.simantics.g2d.element.IElement; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Element writer for chart elements. ChartElementWriter stores + * the reference to a chart definition into the element resource + * @author Teemu Lempinen + * + */ +public class ChartElementWriter implements ElementWriter { + + @Override + public void addToGraph(WriteGraph graph, IElement element, Resource elementResource) throws DatabaseException { + Resource chartComponent = element.getHint(ChartElementFactory.KEY_CHART_COMPONENT); + if (chartComponent == null) + throw new IllegalArgumentException("KEY_CHART_COMPONENT hint not set"); + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + graph.claim(elementResource, jfree.ChartElement_component, chartComponent); + } + + @Override + public void removeFromGraph(WriteGraph graph, Resource elementResource) throws DatabaseException { + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartNode.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartNode.java new file mode 100644 index 00000000..00715038 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartNode.java @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.element; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import javax.swing.JPanel; + +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.simantics.scenegraph.ISelectionPainterNode; +import org.simantics.scenegraph.g2d.events.EventTypes; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; +import org.simantics.scenegraph.swing.ComponentNode; +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.scenegraph.utils.NodeUtil; + +/** + * Chart node for displaying jfreechart charts in diagrams + * @author Teemu Lempinen + * + */ +public class ChartNode extends ComponentNode implements ISelectionPainterNode { + + private static final long serialVersionUID = 5013911689968911010L; + private boolean hover = false; + private boolean dragging = false; + + private ResizeListener resizeListener; + + protected transient JFreeChart chart = null; + + public boolean dragging() { + return dragging; + } + + public void setChart(JFreeChart chart) { + this.chart = chart; + } + + public void setResizeListener(ResizeListener listener) { + this.resizeListener = listener; + } + + @SyncField({"hover"}) + public void setHover(boolean hover) { + this.hover = hover; + repaint(); + } + + @Override + public void cleanup() { + removeEventHandler(this); + super.cleanup(); + } + + @Override + public void init() { + super.init(); + } + + public static void expand(Rectangle2D rectangle, double scaleX, double scaleY) { + GeometryUtils.expandRectangle(rectangle, + 5 * scaleY > 5 ? 5 * scaleY : 5, + 3 * scaleY > 3 ? 3 * scaleY : 3, + 3 * scaleX > 3 ? 3 * scaleX : 3, + 3 * scaleX > 3 ? 3 * scaleX : 3); + } + + @Override + public void render(Graphics2D g2d) { + if (component == null && chart != null) { + // Need the chart, so this cannot be done during initialization + component = new ChartPanel(chart, false); + ((ChartPanel)component).setRefreshBuffer(false); + component.setIgnoreRepaint(true); + component.setDoubleBuffered(false); + if(bounds != null) { + component.setBounds(0, 0, 0, 0); + } + super.init(); + addEventHandler(this); + } + + if (component != null) { + AffineTransform ot = g2d.getTransform(); + g2d.transform(transform); + double scaleX = g2d.getTransform().getScaleX(); + double scaleY = g2d.getTransform().getScaleY(); + + AffineTransform at = new AffineTransform(transform); + synchronized(transform) { + at.setToTranslation(bounds.getMinX(), bounds.getMinY()); + at.scale(1/scaleX, 1/scaleY); + } + g2d.transform(at); + int width = (int)(bounds.getWidth() * scaleX); + int height = (int)(bounds.getHeight() * scaleY); + + if(hover || dragging) { + // Borders + Color orig = g2d.getColor(); + BasicStroke oldStroke = (BasicStroke) g2d.getStroke(); + g2d.setColor(Color.LIGHT_GRAY); + Rectangle2D b = new Rectangle2D.Double(0, 0, width, height); + Rectangle2D r = b.getBounds2D(); + expand(r, 1 * scaleX, 1 * scaleY); + g2d.fill(r); + + // Lower right corner for dragging + double x = r.getMaxX() - (0.33 * scaleX); + double y = r.getMaxY() - (0.33 * scaleY); + + if(r.getMaxX() - x > 0.4) { + // if there is enough space, use decorated corner + BasicStroke hilightStroke = new BasicStroke(oldStroke.getLineWidth() * 3); + for(int i = 1; i < 4; i++) { + Line2D line = new Line2D.Double( + x - (i * scaleX), + y, + x, + y - (i * scaleY)); + + g2d.setStroke(hilightStroke); + g2d.setColor(Color.GRAY); + g2d.draw(line); + + g2d.setStroke(oldStroke); + g2d.setColor(Color.BLACK); + g2d.draw(line); + } + + + } else { + // not enough space, use a non-decorated corner + float f = 3; + Rectangle2D corner = new Rectangle2D.Double(r.getMaxX() - f, r.getMaxY() - f, f, f); + g2d.setColor(Color.DARK_GRAY); + g2d.fill(corner); + } + + g2d.setStroke(oldStroke); + g2d.setColor(orig); + } + + boolean selected = NodeUtil.isSelected(this, 1); + if (selected) { + Color orig = g2d.getColor(); + Stroke origStroke = g2d.getStroke(); + + g2d.setColor(Color.RED); + double s = GeometryUtils.getScale(g2d.getTransform()); + g2d.setStroke(new BasicStroke(1f * s < 1f ? 1f : 1f * (float)s)); + + Rectangle2D b = new Rectangle2D.Double(0, 0, width, height); + Rectangle2D r = b.getBounds2D(); + expand(r, scaleX, scaleY); + g2d.draw(r); + + g2d.setColor(orig); + g2d.setStroke(origStroke); + } + + synchronized(component) { + component.setLocation((int)g2d.getTransform().getTranslateX(), (int)g2d.getTransform().getTranslateY()); + if(component.getSize().getWidth() != width || component.getSize().getHeight() != height) { + component.setSize(width, height); + } + component.paint(g2d); + } + + g2d.setTransform(ot); + } else { + /* + * Component == null + * + * The related chart definition ha been removed. + */ + System.out.println("TÄÄLLÄ, TÄÄLLÄ"); + } + } + + @Override + protected boolean mouseButtonPressed(MouseButtonPressedEvent event) { + Point2D local = controlToLocal( event.controlPosition ); + local = parentToLocal(local); + Rectangle2D bounds = getBoundsInLocal().getBounds2D(); + expand(bounds, 1, 1); + double control = 3.0; + Rectangle2D corner = new Rectangle2D.Double(bounds.getMaxX() - control, bounds.getMaxY() - control, control, control); + if (hover && corner.contains(local)) { + dragging = true; + return true; + } + return super.mouseButtonPressed(event); + } + + + @Override + protected boolean mouseMoved(MouseMovedEvent e) { + if(dragging) { + Point2D local = controlToLocal( e.controlPosition ); + local = parentToLocal(local); + + Rectangle2D bounds = getBoundsInLocal().getBounds2D(); + + if(Math.abs(bounds.getMaxX() - local.getX()) > 3 || + Math.abs(bounds.getMaxY() - local.getY()) > 3) { + resize(local); + } + return true; + } + return false; + } + + public boolean hitCorner(Point2D point) { + Rectangle2D bounds = getBoundsInLocal().getBounds2D(); + expand(bounds, 1, 1); + double control = 3.0; + Rectangle2D corner = new Rectangle2D.Double(bounds.getMaxX() - control, bounds.getMaxY() - control, control, control); + return corner.contains(point); + } + + private void resize(Point2D local) { + Rectangle2D bounds = getBoundsInLocal().getBounds2D(); + double x = bounds.getX(); + double y = bounds.getY(); + double dx = local.getX() - bounds.getMaxX(); + double dy = local.getY() - bounds.getMaxY(); + double w = bounds.getWidth() + dx; + double h = bounds.getHeight() + dy; + bounds.setRect( + x, + y, + w > 20 ? w : 20, + h > 20 ? h : 20 + ); + setBounds(bounds); + } + + @Override + protected boolean mouseDragged(MouseDragBegin e) { + if(dragging) { + return true; // Eat event for faster resize + } else { + return false; + } + } + + @Override + protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) { + if(dragging) { + Point2D local = controlToLocal( e.controlPosition ); + local = parentToLocal(local); + if(Math.abs(bounds.getMaxX() - local.getX()) > 3 || + Math.abs(bounds.getMaxY() - local.getY()) > 3) { + resize(local); + } + dragging = false; + if(resizeListener != null) + resizeListener.elementResized(bounds); + } + return false; + } + + @Override + public int getEventMask() { + return EventTypes.MouseButtonPressedMask + | EventTypes.MouseMovedMask + | EventTypes.MouseButtonReleasedMask + ; + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartSceneGraph.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartSceneGraph.java new file mode 100644 index 00000000..7ca96929 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ChartSceneGraph.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.element; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.jfree.chart.JFreeChart; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.DiagramUtils; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.SceneGraphNodeKey; +import org.simantics.g2d.element.handler.HandleMouseEvent; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.PropertySetter; +import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.scenegraph.Node; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.IG2DNode; +import org.simantics.scenegraph.g2d.events.MouseEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintListener; +import org.simantics.utils.datastructures.hints.IHintObservable; + +/** + * Chart scenegraph for chart elements in diagrams + * @author Teemu Lempinen + * + */ +public class ChartSceneGraph implements SceneGraph, HandleMouseEvent, InternalSize { + private static final long serialVersionUID = 1875762898776996989L; + + public static final Key KEY_SG_NODE = new SceneGraphNodeKey(Node.class, "CHART_SG_NODE"); + public static final Key KEY_SG_SELECTION_NODE = new SceneGraphNodeKey(Node.class, "CHART_SG_SELECTION_NODE"); + + protected IHintListener hoverHintListener; + + public ChartSceneGraph() { + } + + /** + * Expands bounds a little to allow selecting and grabbing a chart element + * from outside the chart graphics + */ + @Override + public Rectangle2D getBounds(IElement e, Rectangle2D s) { + if (s==null) s = new Rectangle2D.Double(); + + IG2DNode node = (IG2DNode)e.getHint(KEY_SG_NODE); + AffineTransform at = (AffineTransform)e.getHint(ElementHints.KEY_TRANSFORM); + if(at != null && node != null && node.getBoundsInLocal() != null) { + Shape shape = node.getBoundsInLocal(); + Rectangle2D r = shape.getBounds2D(); + double scaleX = at.getScaleX(); + double scaleY = at.getScaleY(); + ChartNode.expand(r, 1 * scaleX, 1 * scaleY); + shape = r; + s.setFrame(shape.getBounds2D()); + } else { + s.setFrame((Rectangle2D)e.getHint(ElementHints.KEY_BOUNDS)); + } + return s; + } + + @Override + public void cleanup(IElement e) { + if(hoverHintListener != null) + e.removeHintListener(hoverHintListener); + + Node node = e.removeHint(KEY_SG_NODE); + if (node != null) + node.remove(); + } + + @Override + public void init(final IElement e, G2DParentNode parent) { + ChartNode node = e.getHint(KEY_SG_NODE); + if(node == null) { + // Create a new chart node + node = parent.getOrCreateNode("chart_"+e.hashCode(), ChartNode.class); + + Rectangle2D bounds = (Rectangle2D)e.getHint(ElementHints.KEY_BOUNDS); + if(bounds == null) { + bounds = new Rectangle2D.Double(-40, -40, 80, 80); + e.setHint(ElementHints.KEY_BOUNDS, bounds); + } + node.setBounds(bounds); + + JFreeChart chart = e.getHint(ChartElementFactory.KEY_CHART); + if(chart != null) + node.setChart(chart); + + // Add a resize listener for updating bounds information to graph after resizing + node.setResizeListener(new ResizeListener() { + + @Override + public void elementResized(Rectangle2D newBounds) { + e.setHint(ElementHints.KEY_BOUNDS, newBounds); + IDiagram diagram = ElementUtils.getDiagram(e); + DiagramUtils.synchronizeHintsToBackend(diagram, e); + } + }); + + e.setHint(KEY_SG_NODE, node); + } + + // Hover listening + hoverHintListener = new IHintListener() { + @Override + public void hintRemoved(IHintObservable sender, Key key, Object oldValue) { + + } + + @Override + public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { + if(key == ElementHints.KEY_HOVER) { + IElement e = (IElement)sender; + ChartNode name = (ChartNode) e.getHint(KEY_SG_NODE); + if (name != null) + name.setHover(Boolean.TRUE.equals(e.getHint(ElementHints.KEY_HOVER))); + } + } + }; + e.addHintListener(hoverHintListener); + + update(e); + } + + public void update(IElement e) { + PropertySetter setter = e.getElementClass().getSingleItem(PropertySetter.class); + setter.syncPropertiesToNode(e); + } + + + @Override + public boolean handleMouseEvent(IElement e, ICanvasContext ctx, MouseEvent me) { + if (me instanceof MouseEnterEvent) { + e.setHint(ElementHints.KEY_HOVER, true); + } else if (me instanceof MouseExitEvent) { + e.setHint(ElementHints.KEY_HOVER, false); + } + return false; + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/PopulateChartDropParticipant.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/PopulateChartDropParticipant.java new file mode 100644 index 00000000..2d7c5a93 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/PopulateChartDropParticipant.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.element; + +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.geom.AffineTransform; +import java.io.IOException; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.request.UnaryRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.adapter.GraphToDiagramSynchronizer; +import org.simantics.g2d.dnd.DnDHints; +import org.simantics.g2d.dnd.ElementClassDragItem; +import org.simantics.g2d.dnd.IDnDContext; +import org.simantics.g2d.dnd.IDropTargetParticipant; +import org.simantics.g2d.element.ElementHints; +import org.simantics.modeling.ui.diagramEditor.PopulateElementDropParticipant; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.dnd.LocalObjectTransfer; +import org.simantics.ui.dnd.LocalObjectTransferable; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Drop participant for dropping chart definitions into diagrams + * @author Teemu Lempinen + * + */ +public class PopulateChartDropParticipant extends PopulateElementDropParticipant implements IDropTargetParticipant { + + public PopulateChartDropParticipant(GraphToDiagramSynchronizer synchronizer) { + super(synchronizer); + } + + @Override + public void dragEnter(DropTargetDragEvent dtde, final IDnDContext dp) { + Transferable tr = dtde.getTransferable(); + if (tr.isDataFlavorSupported(LocalObjectTransferable.FLAVOR)) { + + Session session = synchronizer.getSession(); + + Object obj = null; + + try { + obj = tr.getTransferData(LocalObjectTransferable.FLAVOR); + + // Create a structural selection from transfer data + if (!(obj instanceof IStructuredSelection)) { + obj = LocalObjectTransfer.getTransfer().getObject(); + } + + if (obj instanceof IStructuredSelection) { + + IStructuredSelection sel = (IStructuredSelection) obj; + + // Can drop only one chart at the time + if (sel.size() == 1) { + + // Get the chart definition + Resource chart = AdaptionUtils.adaptToSingle(sel, Resource.class); + if (chart == null) + return; + + ElementClassDragItem item = session.syncRequest(new UnaryRead(chart) { + + @Override + public ElementClassDragItem perform(ReadGraph graph) throws DatabaseException { + if(graph.isInstanceOf(parameter, JFreeChartResource.getInstance(graph).Chart)) { + ElementClassDragItem item = new ElementClassDragItem(ChartElementFactory.create(graph, parameter)); + AffineTransform initialTr = AffineTransform.getScaleInstance(1, 1); + item.getHintContext().setHint(ElementHints.KEY_TRANSFORM, initialTr); + return item; + } else { + return null; + } + + } + }); + + if(item != null) { + dp.add(item); + dp.getHints().setHint(DnDHints.KEY_DND_GRID_COLUMNS, Integer.valueOf(1)); + } + + } + + } + + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ResizeListener.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ResizeListener.java new file mode 100644 index 00000000..4c31a6be --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/element/ResizeListener.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.element; + +import java.awt.geom.Rectangle2D; + +/** + * Interface for listeners listening resize events in chart nodes + * @author Teemu Lempinen + * + */ +public interface ResizeListener { + + /** + * Triggered when a node has been resized + * @param newBounds new bounds for the node + */ + public void elementResized(Rectangle2D newBounds); +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/AxisChildRule.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/AxisChildRule.java new file mode 100644 index 00000000..af8071fb --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/AxisChildRule.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.ge; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * ChildRule for finding the axis of a JFreeChart + * + * @author Teemu Lempinen + * + */ +public class AxisChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) throws DatabaseException { + ArrayList result = new ArrayList(); + if(!(parent instanceof Resource)) + return result; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + /* + * 1. chart may have multiple plots + * 2. plot may have multiple axis + */ + for(Resource plot : graph.syncRequest(new ObjectsWithType((Resource)parent, l0.ConsistsOf, jfree.Plot))) { + Resource rangeAxisList = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList); + if(rangeAxisList != null) + for(Resource axis : ListUtils.toList(graph, rangeAxisList)) { + result.add(axis); + } + } + return result; + + + } + + @Override + public Collection getParents(ReadGraph graph, Object child) throws DatabaseException { + return new ArrayList(); + } + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/AxisDropAction.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/AxisDropAction.java new file mode 100644 index 00000000..20f79bb0 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/AxisDropAction.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.ge; + +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.DropActionFactory; +import org.simantics.jfreechart.chart.properties.xyline.AxisAndVariablesExplorerComposite; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Action for dropping axis on top of other axis or series in {@link AxisAndVariablesExplorerComposite} + * @author Teemu Lempinen + * + */ +public class AxisDropAction implements DropActionFactory { + + @Override + public Runnable create(ReadGraph g, Object target, Object source) throws DatabaseException { + // Make sure that both target and source are resources + Resource t = AdaptionUtils.adaptToSingle(target, Resource.class); + Resource s = AdaptionUtils.adaptToSingle(source, Resource.class); + + if(t == null || s == null) + return null; + + // Make sure that source and target are of correct type + JFreeChartResource jfree = JFreeChartResource.getInstance(g); + if(!g.isInstanceOf(s, jfree.Axis)) + return null; + if(!g.isInstanceOf(t, jfree.Series) && !g.isInstanceOf(t, jfree.Axis)) + return null; + + return getRunnable(t, s); + } + + /** + * Get the runnable for doing the drop action + * + * @param t target resource + * @param s source resource + * @return Runnable + */ + private Runnable getRunnable(final Resource t, final Resource s) { + Runnable runnable = new Runnable() { + + @Override + public void run() { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + if(t == null || s == null) return; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource target = t; + Resource source = s; + + // Dragged axis always exists in the same list with target axis, so it is safe to get the target index + Resource plot = graph.getPossibleObject(source, l0.PartOf); + Resource axisListResource = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList); + List axisList = ListUtils.toList(graph, axisListResource); + if(graph.isInstanceOf(target, jfree.Series)) { + // Dropped a axis over a series -> get the axis of the series + Resource dataset = graph.getPossibleObject(target, l0.PartOf); + target = graph.getPossibleObject(dataset, jfree.Dataset_mapToRangeAxis); + } + + // move axis to target position + int targetIndex = axisList.indexOf(target); + axisList.remove(source); + axisList.add(targetIndex, source); + + // Update the range axis list + graph.deny(plot, jfree.Plot_rangeAxisList); + axisListResource = ListUtils.create(graph, axisList); + graph.claim(plot, jfree.Plot_rangeAxisList, axisListResource); + } + + }); + } + }; + return runnable; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/AxisLabelRule.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/AxisLabelRule.java new file mode 100644 index 00000000..d501c6b5 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/AxisLabelRule.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.ge; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.labels.LabelRule; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Label rule for range axis label + * @author Teemu Lempinen + * + */ +public class AxisLabelRule implements LabelRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + /** + * Range axis label + * + * Options: + * 1. Label + * 2. Default + */ + @Override + public Map getLabel(ReadGraph graph, Object content) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource resource = (Resource)content; + String label = graph.getPossibleRelatedValue(resource, l0.HasLabel, Bindings.STRING); + if(label == null || label.isEmpty()) { + label = "Range"; + Resource plot = graph.getPossibleObject(resource, l0.PartOf); + if(plot != null) { + Resource axisListResource = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList); + if(axisListResource != null) { + List axisList = ListUtils.toList(graph, axisListResource); + if(axisList.contains(resource)) + label = label + " " + (axisList.indexOf(resource) + 1); + } + } + } + return Collections.singletonMap(ColumnKeys.SINGLE, label); + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesChildRule.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesChildRule.java new file mode 100644 index 00000000..3e058fbc --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesChildRule.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.ge; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Child rule for obtaining series in a chart. + * Assumes that the chart has only one plot and that plot has only one dataset + * @author Teemu Lempinen + * + */ +public class SeriesChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) throws DatabaseException { + ArrayList result = new ArrayList(); + if(!(parent instanceof Resource)) + return result; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + /* + * 1. we assume that there is only one plot + * 2. we assume that the only plot has only one dataset + */ + Resource plot = graph.syncRequest(new PossibleObjectWithType((Resource)parent, l0.ConsistsOf, jfree.Plot)); + + Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + + Resource seriesList = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + if(seriesList != null) + for(Resource series : ListUtils.toList(graph, seriesList)) { + result.add(series); + } + return result; + } + + @Override + public Collection getParents(ReadGraph graph, Object child) throws DatabaseException { + return new ArrayList(); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesDropAction.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesDropAction.java new file mode 100644 index 00000000..5870cd52 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesDropAction.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.ge; + +import java.util.Collections; +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.DropActionFactory; +import org.simantics.jfreechart.chart.properties.xyline.XYLineAxisAndVariablesTab; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Drop action for explorer in {@link XYLineAxisAndVariablesTab}. This action is used for dropping + * both series on axis or another sries + * + * @author Teemu Lempinen + * + */ +public class SeriesDropAction implements DropActionFactory { + + @Override + public Runnable create(ReadGraph g, Object target, Object source) throws DatabaseException { + // Make sure that both target and source are resources + Resource t = AdaptionUtils.adaptToSingle(target, Resource.class); + Resource s = AdaptionUtils.adaptToSingle(source, Resource.class); + + if(t == null || s == null) + return null; + + // Make sure that source and target are of correct type + JFreeChartResource jfree = JFreeChartResource.getInstance(g); + if(!g.isInstanceOf(s, jfree.Series)) + return null; + if(!g.isInstanceOf(t, jfree.Series) && !g.isInstanceOf(t, jfree.Axis)) + return null; + + return getRunnable(t, s); + } + + /** + * Get the runnable for doing the drop action + * + * @param t target resource + * @param s source resource + * @return Runnable + */ + private Runnable getRunnable(final Resource t, final Resource s) { + Runnable runnable = new Runnable() { + + @Override + public void run() { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + if(t == null || s == null) return; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource target = t; + Resource source = s; + Resource droppedOnSeries = null; + + // Dropped a series over a series -> get target dataset + if(graph.isInstanceOf(target, jfree.Series)) { + droppedOnSeries = target; + Resource dataset = graph.getPossibleObject(target, l0.PartOf); + if(dataset != null) + target = dataset; + } + + // Dropped a series over an axis -> get target dataset + if(graph.isInstanceOf(target, jfree.Axis)) { + Resource dataset = graph.syncRequest(new PossibleObjectWithType(target, jfree.Dataset_mapToRangeAxis_Inverse, jfree.Dataset)); + if(dataset != null) + target = dataset; + } + + // Move series to a dataset + if(graph.isInstanceOf(target, jfree.Dataset)) { + // Remove from old dataset if it was different than the new one + Resource sourceDataset = graph.getPossibleObject(source, l0.PartOf); + if(sourceDataset != null && !sourceDataset.equals(target)) { + Resource sourceSeriesList = graph.getPossibleObject(sourceDataset, jfree.Dataset_seriesList); + if(sourceSeriesList != null) + ListUtils.removeElement(graph, sourceSeriesList, source); + } + graph.deny(source, l0.PartOf); + + // Add to new dataset + Resource targetSeriesList = graph.getPossibleObject(target, jfree.Dataset_seriesList); + if(targetSeriesList == null) { + targetSeriesList = ListUtils.create(graph, Collections.emptyList()); + graph.claim(target, jfree.Dataset_seriesList, targetSeriesList); + } + + + // Series was dropped on another series. Move the dropped series to that place and recreate the list + if(droppedOnSeries != null) { + List list = ListUtils.toList(graph, targetSeriesList); + int targetIndex = list.indexOf(droppedOnSeries); + if(list.contains(source)) + list.remove(source); + list.add(targetIndex, source); + graph.deny(target, jfree.Dataset_seriesList); + targetSeriesList = ListUtils.create(graph, list); + graph.claim(target, jfree.Dataset_seriesList, targetSeriesList); + } else { + ListUtils.insertFront(graph, targetSeriesList, Collections.singleton(source)); + } + + graph.claim(target, l0.ConsistsOf, source); + } + } + }); + } + }; + return runnable; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesLabelDecorationRule.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesLabelDecorationRule.java new file mode 100644 index 00000000..b7b9a37c --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesLabelDecorationRule.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.ge; + +import org.eclipse.jface.resource.FontDescriptor; +import org.simantics.browsing.ui.content.LabelDecorator; +import org.simantics.browsing.ui.model.labeldecorators.LabelDecorationRule; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.ui.AdaptionUtils; + +public class SeriesLabelDecorationRule implements LabelDecorationRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public LabelDecorator getLabelDecorator(ReadGraph graph, Object content) throws DatabaseException { + Resource resource = AdaptionUtils.adaptToSingle(content, Resource.class); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + if (resource != null && graph.isInstanceOf(resource, jfree.Series)) { + final String[] filter = graph.getPossibleRelatedValue(resource, jfree.variableFilter, Bindings.STRING_ARRAY); + if(filter != null) { + return new LabelDecorator.Stub() { + @Override + public String decorateLabel(String label, String column, int itemIndex) { + label += " ["; + for(int i = 0; i < filter.length; i++) { + label += filter[i]; + if(i < filter.length - 1) + label += ", "; + } + label += "]"; + return label; + } + + @SuppressWarnings("unchecked") + @Override + public F decorateFont(F font, String column, int itemIndex) { + return (F) ((FontDescriptor) font); + } + }; + } + } + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesLabelRule.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesLabelRule.java new file mode 100644 index 00000000..399c4d02 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/SeriesLabelRule.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.ge; + +import java.util.Collections; +import java.util.Map; + +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.labels.LabelRule; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.jfreechart.chart.properties.IAllVariablesOfModel; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Label rule for dataset series + * @author Teemu Lempinen + * + */ +public class SeriesLabelRule implements LabelRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + /** + * Options: + * 1. Label + * 2. Variable rvi + * 3. Default + */ + @Override + public Map getLabel(ReadGraph graph, Object content) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource resource = (Resource)content; + String label = graph.getPossibleRelatedValue(resource, l0.HasLabel, Bindings.STRING); + if(label == null || label.isEmpty()) { + IAllVariablesOfModel vom = graph.adapt(resource, IAllVariablesOfModel.class); + + String rvi = graph.getPossibleRelatedValue(resource, jfree.variableRVI); + if (rvi != null) { + label =vom.getVariablesLabel(graph, rvi); + if (label == null) + label = rvi; + } else + label = "Set variable"; + } + return Collections.singletonMap(ColumnKeys.SINGLE, label); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/VariableChildRule.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/VariableChildRule.java new file mode 100644 index 00000000..afe693dc --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/ge/VariableChildRule.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.ge; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * ChildRule for finding the series of an axis + * + * @author Teemu Lempinen + * + */ +public class VariableChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) throws DatabaseException { + ArrayList result = new ArrayList(); + if(!(parent instanceof Resource)) + return result; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource axis = (Resource)parent; + /* + * 1. Axis belongs to a plot + * 2. Plot may have multiple datasets + * 3. Dataset is mapped to a single range axis + * 3. Dataset may have multiple seires + */ + Resource plot = graph.getPossibleObject(axis, jfree.Plot_rangeAxis_Inverse); + if(plot == null) + return result; + + for(Resource dataset : graph.syncRequest(new ObjectsWithType(plot, l0.ConsistsOf, jfree.Dataset))) { + if(graph.hasStatement(dataset, jfree.Dataset_mapToRangeAxis, axis)) { + Resource seriesList = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + if(seriesList != null) + for(Resource series : ListUtils.toList(graph, seriesList)) { + result.add(series); + } + } + } + return result; + } + + @Override + public Collection getParents(ReadGraph graph, Object child) throws DatabaseException { + return new ArrayList(); + } + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/AllVariablesOfModel.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/AllVariablesOfModel.java new file mode 100644 index 00000000..f3fcd7dd --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/AllVariablesOfModel.java @@ -0,0 +1,57 @@ +package org.simantics.jfreechart.chart.properties; + +import java.util.Collection; +import java.util.Collections; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; + +public class AllVariablesOfModel implements Read> { + + public Resource model; + + /** + * Queries all variables of a model + * @param res the model. + */ + public AllVariablesOfModel(Resource res) { + this.model = res; + } + + public Resource getModel() { + return model; + } + + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + if(!graph.hasStatement(model)) + return Collections.emptyList(); + IAllVariablesOfModel query = graph.adapt(model, IAllVariablesOfModel.class); + return graph.syncRequest(query.getVariablesQuery()); + } + + public static AllVariablesOfModel withRandomResource(ISessionContext context, final Resource resource) throws DatabaseException { + Resource model = context.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + Resource r = resource; + while((r = graph.getPossibleObject(r, Layer0.getInstance(graph).PartOf)) != null) { + if(graph.isInstanceOf(r, SimulationResource.getInstance(graph).Model)) + return r; + } + return null; + } + + }); + if (model == null) + return null; + return new AllVariablesOfModel(model); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/AxisHidePropertyComposite.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/AxisHidePropertyComposite.java new file mode 100644 index 00000000..02960a88 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/AxisHidePropertyComposite.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Class containing properties for hiding pars of an axis + * + * @author Teemu Lempinen + * + */ +public class AxisHidePropertyComposite extends Composite { + + public AxisHidePropertyComposite(Composite parent, ISessionContext context, WidgetSupport support, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().applyTo(this); + + Group hideGroup = new Group(this, SWT.NONE); + hideGroup.setText("Hide"); + GridDataFactory.fillDefaults().applyTo(hideGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(hideGroup); + + Button label = new Button(hideGroup, support, SWT.CHECK); + label.setText("Label"); + label.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.Axis_visibleLabel, true)); + label.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Axis_visibleLabel)); + GridDataFactory.fillDefaults().applyTo(label.getWidget()); + + Button tmarks = new Button(hideGroup, support, SWT.CHECK); + tmarks.setText("Tick marks"); + tmarks.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.Axis_visibleTickMarks, true)); + tmarks.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Axis_visibleTickMarks)); + GridDataFactory.fillDefaults().applyTo(tmarks.getWidget()); + + Button axisLine = new Button(hideGroup, support, SWT.CHECK); + axisLine.setText("Axis line"); + axisLine.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.Axis_visibleAxisLine, true)); + axisLine.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Axis_visibleAxisLine)); + GridDataFactory.fillDefaults().applyTo(axisLine.getWidget()); + + Button tlabels = new Button(hideGroup, support, SWT.CHECK); + tlabels.setText("Tick labels"); + tlabels.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.Axis_visibleTickLabels, true)); + tlabels.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Axis_visibleTickLabels)); + GridDataFactory.fillDefaults().applyTo(tlabels.getWidget()); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/BooleanPropertyFactory.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/BooleanPropertyFactory.java new file mode 100644 index 00000000..751a1344 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/BooleanPropertyFactory.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.utils.datastructures.Quad; + +/** + * PropertyFactory for finding a boolean property. Supports also finding the + * property from a first occurrence of resource ConsistsOf type HasProperty + * + * @author Teemu Lempinen + * + */ +public class BooleanPropertyFactory extends ReadFactoryImpl { + + final private String propertyURI; + final private String typeURI; + final private Boolean inverse; + final private Boolean defaultValue; + + /** + * PropertyFactory for finding a boolean property with propertyURI + * + * @param propertyURI URI for the boolean property + */ + public BooleanPropertyFactory(String propertyURI) { + this(null, propertyURI, false); + } + + /** + * PropertyFactory for finding a boolean property with propertyURI. + * + * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible) + * + * @param propertyURI URI for the boolean property + * @param inverse Invert the result? + */ + public BooleanPropertyFactory(String propertyURI, boolean inverse) { + this(null, propertyURI, inverse); + } + + /** + * PropertyFactory for finding a boolean property with propertyURI. + * + * Finds the property for first ObjectWithType(resource, L0.ConsistsOf, type) + * + * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible) + * + * @param typeURI URI for a resource (resource ConsistsOf type) (null allowed) + * @param propertyURI URI for the boolean property + * @param inverse Invert the result? + */ + public BooleanPropertyFactory(String typeURI, String propertyURI, boolean inverse) { + this(typeURI, propertyURI, inverse, false); + } + + /** + * PropertyFactory for finding a boolean property with propertyURI. + * + * Finds the property for first ObjectWithType(resource, L0.ConsistsOf, type) + * + * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible) + * + * @param typeURI URI for a resource (resource ConsistsOf type) (null allowed -> not used) + * @param propertyURI URI for the boolean property + * @param inverse Invert the result? + * @param defaultValue default value + */ + public BooleanPropertyFactory(String typeURI, String propertyURI, boolean inverse, boolean defaultValue) { + this.propertyURI = propertyURI; + this.inverse = inverse; + this.typeURI = typeURI; + this.defaultValue = defaultValue; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Quad((Resource) inputContents, propertyURI, getClass(), defaultValue); + } + + @Override + public Boolean perform(ReadGraph graph, Resource r) throws DatabaseException { + if(typeURI == null) { + // if no typeUri, use the default resource r + return getValue(graph, r); + } else { + // typeURI was defined, find the property for the first occurence of ConsistsOf type + Resource type = graph.getResource(typeURI); + for(Resource o : graph.syncRequest(new ObjectsWithType(r, Layer0.getInstance(graph).ConsistsOf, type))) { + // Returns the value for the first occurrence + return getValue(graph, o); + } + } + // if nothing was found with typeURI + return false; + } + + /** + * Return the value for a Boolean literal possibly inverted (or default if resource != Boolean literal) + * + * @param graph ReadGraph + * @param resource Literal Boolean resource + * @return value of the parameter (or default or inverted) + * @throws DatabaseException + */ + private Boolean getValue(ReadGraph graph, Resource resource) throws DatabaseException { + Boolean value = graph.getPossibleRelatedValue(resource, graph.getResource(propertyURI), Bindings.BOOLEAN); + if(value != null) { + return !inverse.equals(value); + } else { + return defaultValue; + } + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/BooleanSelectionListener.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/BooleanSelectionListener.java new file mode 100644 index 00000000..8364b82c --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/BooleanSelectionListener.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; + +/** + * Class for setting a boolean value when a selection occurs. (check box buttons) + * + * @author Teemu Lempinen + * + */ +public class BooleanSelectionListener extends SelectionListenerImpl { + + final private String propertyURI; + final private String typeUri; + + /** + * Boolean selection listener for property with propertyURI + * + * @param context ISessionContext + * @param propertyURI uri of the boolean property + */ + public BooleanSelectionListener(ISessionContext context, String propertyURI) { + this(context, null, propertyURI); + } + + /** + * Boolean selection listener for property with propertyURI + * Sets the property for all ObjectWithType(resource, L0.ConsistsOf, type) + * + * @param context ISessionContext + * @param typeUri URI for a resource (resource ConsistsOf type) (null allowed -> not used) + * @param propertyURI uri of the boolean property + */ + public BooleanSelectionListener(ISessionContext context, String typeUri, String propertyURI) { + super(context); + this.propertyURI = propertyURI; + this.typeUri = typeUri; + } + + @Override + public void apply(WriteGraph graph, Resource chart) throws DatabaseException { + if(typeUri == null) { + setValue(graph, chart); + } else { + Resource type = graph.getResource(typeUri); + for(Resource object : graph.syncRequest(new ObjectsWithType(chart, Layer0.getInstance(graph).ConsistsOf, type))) { + setValue(graph, object); + } + } + + } + + /** + * Set boolean value for Boolean literal resource (inverts the current value). + * @param graph ReadGraph + * @param resource Boolean literal resource + * @throws DatabaseException + */ + private void setValue(WriteGraph graph, Resource resource) throws DatabaseException { + Resource property = graph.getResource(propertyURI); + Boolean value = graph.getPossibleRelatedValue(resource, property, Bindings.BOOLEAN); + graph.claimLiteral(resource, property, Boolean.FALSE.equals(value)); + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartTab.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartTab.java new file mode 100644 index 00000000..d8d20f0e --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartTab.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.ChartComposite; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Tab for displaying a chart + * @author Teemu Lempinen + * + */ +public class ChartTab extends LabelPropertyTabContributor implements Widget { + + private Composite parent; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + support.register(this); + this.parent = body; + } + + @Override + public void setInput(ISessionContext context, final Object input) { + Resource chart = AdaptionUtils.adaptToSingle(input, Resource.class); + new ChartComposite(parent, chart, SWT.BORDER); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariable.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariable.java new file mode 100644 index 00000000..20ee6389 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariable.java @@ -0,0 +1,60 @@ +package org.simantics.jfreechart.chart.properties; + +public class ChartVariable implements Comparable{ + + private String rvi; + private String label; + + public ChartVariable(String rvi) { + this.rvi = rvi; + } + + public ChartVariable(String rvi, String label) { + this.rvi = rvi; + this.label = label; + } + + public String getRvi() { + return rvi; + } + + public String getLabel() { + return label; + } + + @Override + public String toString() { + if (label != null) + return label; + return rvi; + } + + @Override + public int hashCode() { + return rvi.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) + return false; + if (obj.getClass() != getClass()) + return false; + ChartVariable other = (ChartVariable)obj; + return rvi.equals(other.rvi); + } + + @Override + public int compareTo(ChartVariable o) { + int rvicomp = rvi.compareTo(o.rvi); + if (rvicomp == 0) + return 0; + if (label != null && o.label != null) { + int labelcomp = label.compareTo(o.label); + if (labelcomp != 0) + return labelcomp; + } + return rvicomp; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableFactory.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableFactory.java new file mode 100644 index 00000000..fea54159 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableFactory.java @@ -0,0 +1,34 @@ +package org.simantics.jfreechart.chart.properties; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.JFreeChartResource; + +public class ChartVariableFactory extends ReadFactoryImpl{ + + private Map map; + + public ChartVariableFactory(Collection data) { + map = new HashMap(); + for (ChartVariable v : data) { + map.put(v.getRvi(), v); + } + } + + @Override + public ChartVariable perform(ReadGraph graph, Resource input) + throws DatabaseException { + String rvi = graph.getPossibleRelatedValue(input, JFreeChartResource.getInstance(graph).variableRVI); + if (rvi == null) + return null; + return map.get(rvi); + + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableModifier.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableModifier.java new file mode 100644 index 00000000..a1e13dd0 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ChartVariableModifier.java @@ -0,0 +1,95 @@ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.jface.bindings.keys.KeyStroke; +import org.eclipse.jface.bindings.keys.ParseException; +import org.eclipse.jface.fieldassist.ContentProposalAdapter; +import org.eclipse.jface.fieldassist.IContentProposal; +import org.eclipse.jface.fieldassist.IContentProposalListener; +import org.eclipse.jface.fieldassist.IContentProposalListener2; +import org.eclipse.jface.fieldassist.TextContentAdapter; +import org.eclipse.swt.widgets.Control; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.JFreeChartResource; + +public class ChartVariableModifier extends StringChooserModifyListenerImpl { + + private boolean active; + private Control control; + + private char[] alphaNumericCharacters = { + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','å','ä','ö', + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Å','Ä','Ö', + '1','2','3','4','5','6','7','8','9','0','.','_'}; + + public ChartVariableModifier(Control control, WidgetSupport support) { + this.control = control; + this.active = true; + + KeyStroke keyStroke = null; + try { + keyStroke = KeyStroke.getInstance("Ctrl+Space"); + } catch (ParseException e1) { + e1.printStackTrace(); + } + + //SimpleContentProposalProvider scpp = new VariableProposalProvider(control, support); + VariableProposalProvider scpp = new VariableProposalProvider(control, support); + scpp.setFiltering(true); + + ContentProposalAdapter adapter = new ContentProposalAdapter( + control, new TextContentAdapter(), scpp, keyStroke, alphaNumericCharacters); + adapter.setAutoActivationDelay(0); + adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); + adapter.addContentProposalListener(new IContentProposalListener2() { + + @Override + public void proposalPopupOpened(ContentProposalAdapter adapter) { + if(ChartVariableModifier.this != null) + ChartVariableModifier.this.deactivate(); + } + + @Override + public void proposalPopupClosed(ContentProposalAdapter adapter) { + if(ChartVariableModifier.this != null) + ChartVariableModifier.this.activate(); + } + }); + + adapter.addContentProposalListener(new IContentProposalListener() { + + + @Override + public void proposalAccepted(IContentProposal proposal) { + if(ChartVariableModifier.this.control != null && !ChartVariableModifier.this.control.isDisposed()) + ChartVariableModifier.this.modifySelection(new StringChooserModifyEvent(ChartVariableModifier.this.control, new ChartVariable(proposal.getContent(), proposal.getLabel()), proposal.getLabel())); + } + }); + + + } + + @Override + public void applyObject(WriteGraph graph, Resource resource, ChartVariable object, String text) throws DatabaseException { + if(active) { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + graph.claimLiteral(resource, jfree.variableRVI, object.getRvi(), Bindings.STRING); + graph.deny(resource, jfree.variableFilter); + } + + } + + + + public void deactivate() { + active = false; + } + + public void activate() { + active = true; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ColorPicker.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ColorPicker.java new file mode 100644 index 00000000..e5f003f8 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/ColorPicker.java @@ -0,0 +1,388 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.ColorDialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.RunnableWithObject; +import org.simantics.utils.datastructures.Triple; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.ui.gfx.ColorImageDescriptor; + +/** + * Composite for selecting a color for a chart component + * + * @author Teemu Lempinen + * + */ +public class ColorPicker extends Composite implements Widget { + + Button defaultColor, customColor, color; + + /** + * Create a composite containing radio buttons for default or custom color. Color chooser button is active + * when the custom radio button is selected. Color chooser uses {@link ColorDialog} to select a color + * + * @param parent Composite + * @param context ISessionContext + * @param support WidgetSupport + * @param style SWT style + */ + public ColorPicker(Composite parent, ISessionContext context, WidgetSupport support, int style) { + this(parent, context, support, style, true); + } + + /** + * Create a composite containing radio buttons for default or custom color. Color chooser button is active + * when the custom radio button is selected. Color chooser uses {@link ColorDialog} to select a color + * + * @param parent Composite + * @param context ISessionContext + * @param support WidgetSupport + * @param style SWT style + * @param defaultColor provide default color widget? + */ + public ColorPicker(Composite parent, ISessionContext context, WidgetSupport support, int style, boolean defaultColor) { + super(parent, style); + support.register(this); + + if(support.getParameter(WidgetSupport.RESOURCE_MANAGER) == null) { + LocalResourceManager resourceManager = new LocalResourceManager(JFaceResources.getResources(), this); + support.setParameter(WidgetSupport.RESOURCE_MANAGER, resourceManager); + } + + if(defaultColor) { + GridLayoutFactory.fillDefaults().numColumns(4).applyTo(this); + + this.defaultColor = new Button(this, support, SWT.RADIO); + this.defaultColor.setText("default"); + this.defaultColor.setSelectionFactory(new DefaultColorSelectionFactory(false)); + this.defaultColor.addSelectionListener(new DefaultColorSelectionListener(context)); + GridDataFactory.fillDefaults().applyTo(this.defaultColor.getWidget()); + + customColor = new Button(this, support, SWT.RADIO); + customColor.setText("custom"); + customColor.setSelectionFactory(new DefaultColorSelectionFactory(true)); + customColor.addSelectionListener(new DefaultColorSelectionListener(context)); + + GridDataFactory.fillDefaults().applyTo(customColor.getWidget()); + } else { + GridLayoutFactory.fillDefaults().applyTo(this); + } + + + color = new Button(this, support, SWT.PUSH); + color.setImageFactory(new ColorImageFactoryFactory(this)); + color.addSelectionListener(new ColorSelectionListener(context)); + color.getWidget().setEnabled(false); + GridDataFactory.fillDefaults().applyTo(color.getWidget()); + } + + /** + * Method for finding the resource for which the color is selected. + * + * @param graph ReadGraph + * @param input input from WidgetSupport + * @return + * @throws DatabaseException + */ + protected Resource getResource(ReadGraph graph, Resource input) throws DatabaseException { + return input; + } + + /** + * Method for getting the relation with which the g2d.Color is related to a resource + * + * @param graph ReadGraph + * @return Color relation + * @throws DatabaseException + */ + protected Resource getColorRelation(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + return jfree.color; + } + + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class); + + // Create a listener to define the enabled state of the color chooser button + context.getSession().asyncRequest(new Read() { + + @Override + public Float[] perform(ReadGraph graph) throws DatabaseException { + if(graph.hasStatement(getResource(graph, resource), getColorRelation(graph))) { + float[] components = graph.getPossibleRelatedValue(getResource(graph, resource), getColorRelation(graph)); + Float[] result = new Float[components.length]; + for(int i = 0; i < components.length; i++) result[i] = components[i]; + return result; + } else { + return null; + } + } + + }, new Listener() { + + @Override + public void execute(Float[] result) { + if(!color.getWidget().isDisposed()) { + color.getWidget().getDisplay().asyncExec(new RunnableWithObject(result != null ? true : false) { + @Override + public void run() { + if(!color.getWidget().isDisposed()) { + if(!Boolean.TRUE.equals(getObject())) + color.getWidget().setEnabled(false); + else + color.getWidget().setEnabled(true); + } + } + }); + } + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return color.getWidget().isDisposed(); + } + }); + } + + + /** + * ImageFactory returning an image for color button + * @author Teemu Lempinen + * + */ + private class ColorImageFactoryFactory extends ReadFactoryImpl { + + private ColorPicker picker; + + public ColorImageFactoryFactory(ColorPicker colorPicker) { + this.picker = colorPicker; + } + + @Override + public ImageDescriptor perform(ReadGraph graph, Resource input) throws DatabaseException { + RGB rgb = getColor(graph, getResource(graph, input)); + return new ColorImageDescriptor(rgb.red, rgb.green, rgb.blue, 20, 20, false); + + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple>(inputContents, picker, getClass()); + } + + } + + /** + * Get RGB from a color literal resource. If resource is not a color resource, return blue (RGB 0, 0, 255) + * @param graph ReadGraph + * @param input Color literal resource (float[4]) + * @return RGB color + * @throws DatabaseException + */ + private RGB getColor(ReadGraph graph, Resource input) throws DatabaseException{ + float[] colorComponents = graph.getPossibleRelatedValue(input, getColorRelation(graph)); + RGB rgb; + if(colorComponents == null) + rgb = new RGB(0, 0, 255); + else + rgb = new RGB((int)(colorComponents[0] * 255.0f), + (int)(colorComponents[1] * 255.0f), + (int)(colorComponents[2] * 255.0f)); + return rgb; + } + + + /** + * SelectionListener for color button. + * + * @author Teemu Lempinen + * + */ + private class ColorSelectionListener extends SelectionListenerImpl { + + private SelectionEvent e; + private RGB rgb; + + /** + * + * @param context ISessionContext + */ + public ColorSelectionListener(ISessionContext context) { + super(context); + } + + @Override + public void widgetSelected(SelectionEvent e) { + if(color.getWidget().isDisposed()) + return; + // Save the event for coordinates + this.e = e; + super.widgetSelected(e); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(color.getWidget().isDisposed()) + return; + + final Resource resource = getResource(graph, input); + final Display display = color.getWidget().getDisplay(); + final RGB oldRGB = getColor(graph, resource); + + display.asyncExec(new RunnableWithObject(oldRGB) { + @Override + public void run() { + // Use color dialog to select a color + Shell shell = new Shell(display); + ColorDialog cd = new ColorDialog(shell); + Point point = color.getWidget().toDisplay(e.x - 150, e.y - 150); + cd.getParent().setLocation(point.x, point.y); + cd.setText("Select color"); + cd.setRGB((RGB)getObject()); + rgb = cd.open(); + if(rgb == null) + return; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + G2DResource g2d = G2DResource.getInstance(graph); + float[] components = new float[] {rgb.red / 255.0f, rgb.green / 255.0f, rgb.blue / 255.0f, 1.0f}; + graph.claimLiteral(resource, getColorRelation(graph), g2d.Color, components); + } + }); + + } + }); + + + + } + + } + + /** + * SelectionFactory for default and custom color radio buttons + * @author Teemu Lempinen + * + */ + private class DefaultColorSelectionFactory extends ReadFactoryImpl { + + private final Boolean isCustom; + + /** + * + * @param isCustom Is this custom button? + */ + public DefaultColorSelectionFactory(Boolean isCustom) { + super(); + this.isCustom = isCustom; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple((Resource) inputContents, getClass(), isCustom); + } + + @Override + public Boolean perform(ReadGraph graph, Resource input) throws DatabaseException { + Resource r = graph.getPossibleObject(getResource(graph, input), getColorRelation(graph)); + boolean result = false; // Default == not selected + if(r == null && !isCustom) { + // No color definition and default-button -> selected + result = true; + } else if(r != null && isCustom) { + // color definition and custom button -> selected + result = true; + } + return result; + } + + } + + /** + * SelectionListener for default and custom radio buttons + * + * @author Teemu Lempinen + * + */ + private class DefaultColorSelectionListener extends SelectionListenerImpl { + + private SelectionEvent e; + + public DefaultColorSelectionListener(ISessionContext context) { + super(context); + } + + @Override + public void widgetSelected(SelectionEvent e) { + this.e = e; + super.widgetSelected(e); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + Resource resource = getResource(graph, input); + if(customColor.getWidget().equals(e.widget)) { + // Custom selected. If there is no color already, create a default Blue color + G2DResource g2d = G2DResource.getInstance(graph); + if(graph.getPossibleObject(resource, getColorRelation(graph)) == null) { + float[] components = java.awt.Color.BLUE.getColorComponents(new float[4]); + components[3] = 1.0f; + graph.claimLiteral(resource, getColorRelation(graph), g2d.Color, components); + } + } else { + // Default selected, remove color definition + graph.deny(resource, getColorRelation(graph)); + } + } + } + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyFactory2.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyFactory2.java new file mode 100644 index 00000000..3bd42500 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyFactory2.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.utils.datastructures.Quad; + +/** + * PropertyFactory for finding a double property. Supports also finding the + * property from a first occurrence of resource ConsistsOf type HasProperty + * + * @author Teemu Lempinen + * @author Marko Luukkainen + * + */ +public class DoublePropertyFactory2 extends ReadFactoryImpl { + + final private String propertyURI; + final private String typeURI; + final private Double defaultValue; + + /** + * PropertyFactory for finding a boolean property with propertyURI + * + * @param propertyURI URI for the boolean property + */ + public DoublePropertyFactory2(String propertyURI) { + this(null, propertyURI); + } + + + /** + * PropertyFactory for finding a boolean property with propertyURI. + * + * Finds the property for first ObjectWithType(resource, L0.ConsistsOf, type) + * + * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible) + * + * @param typeURI URI for a resource (resource ConsistsOf type) (null allowed) + * @param propertyURI URI for the boolean property + * @param inverse Invert the result? + */ + public DoublePropertyFactory2(String typeURI, String propertyURI) { + this(typeURI, propertyURI, 0.0); + } + + /** + * PropertyFactory for finding a boolean property with propertyURI. + * + * Finds the property for first ObjectWithType(resource, L0.ConsistsOf, type) + * + * Supports inverting the result (e.g. if required information is IsHidden, but database contains IsVisible) + * + * @param typeURI URI for a resource (resource ConsistsOf type) (null allowed -> not used) + * @param propertyURI URI for the boolean property + * @param inverse Invert the result? + * @param defaultValue default value + */ + public DoublePropertyFactory2(String typeURI, String propertyURI, double defaultValue) { + this.propertyURI = propertyURI; + this.typeURI = typeURI; + this.defaultValue = defaultValue; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Quad((Resource) inputContents, propertyURI, getClass(), defaultValue); + } + + @Override + public String perform(ReadGraph graph, Resource r) throws DatabaseException { + if(typeURI == null) { + // if no typeUri, use the default resource r + return getValue(graph, r); + } else { + // typeURI was defined, find the property for the first occurence of ConsistsOf type + Resource type = graph.getResource(typeURI); + for(Resource o : graph.syncRequest(new ObjectsWithType(r, Layer0.getInstance(graph).ConsistsOf, type))) { + // Returns the value for the first occurrence + return getValue(graph, o); + } + } + // if nothing was found with typeURI + return ""; + } + + /** + * Return the value for a Boolean literal possibly inverted (or default if resource != Boolean literal) + * + * @param graph ReadGraph + * @param resource Literal Boolean resource + * @return value of the parameter (or default or inverted) + * @throws DatabaseException + */ + private String getValue(ReadGraph graph, Resource resource) throws DatabaseException { + Double value = graph.getPossibleRelatedValue(resource, graph.getResource(propertyURI), Bindings.DOUBLE); + if(value != null) { + return value.toString(); + } else if (defaultValue != null){ + return defaultValue.toString(); + } + return ""; + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyModifier2.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyModifier2.java new file mode 100644 index 00000000..a7dfe81b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoublePropertyModifier2.java @@ -0,0 +1,49 @@ +package org.simantics.jfreechart.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; + +public class DoublePropertyModifier2 extends TextModifyListenerImpl { + + final private String typeUri; + final private String propertyURI; + + public DoublePropertyModifier2(ISessionContext context, String propertyURI) { + this.propertyURI = propertyURI; + this.typeUri = null; + } + + public DoublePropertyModifier2(ISessionContext context, String typeURI, String propertyURI) { + this.propertyURI = propertyURI; + this.typeUri = typeURI; + } + + @Override + public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException { + if (typeUri == null) + applyValue(graph, input, text); + else { + Resource type = graph.getResource(typeUri); + for(Resource object : graph.syncRequest(new ObjectsWithType(input, Layer0.getInstance(graph).ConsistsOf, type))) { + applyValue(graph, object,text); + } + } + + } + + private void applyValue(WriteGraph graph, Resource input, String text) throws DatabaseException { + if (text == null || text.trim().isEmpty()) { + if (graph.hasStatement(input, graph.getResource(propertyURI))) + graph.denyValue(input, graph.getResource(propertyURI)); + } else { + graph.claimLiteral(input, graph.getResource(propertyURI), Double.parseDouble(text), Bindings.DOUBLE); + } + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoubleValidator.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoubleValidator.java new file mode 100644 index 00000000..e41c9b0a --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/DoubleValidator.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.jface.dialogs.IInputValidator; + +/** + * Validator for validating that an input is double. + * + * Can allow empty strings. + * + * @author Teemu Lempinen + * + */ +public class DoubleValidator implements IInputValidator { + + boolean allowEmpty; + + /** + * New double validator. Does not allow empty strings + */ + public DoubleValidator() { + this(false); + } + + /** + * New double validator. + * @param allowEmpty Are empty strings allowed + */ + public DoubleValidator(boolean allowEmpty) { + this.allowEmpty = allowEmpty; + } + + @Override + public String isValid(String newText) { + if (allowEmpty && newText.trim().isEmpty()) + return null; + try { + Double.parseDouble(newText); + return null; + } catch (NumberFormatException e) { + return e.getMessage(); + } + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/IAllVariablesOfModel.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/IAllVariablesOfModel.java new file mode 100644 index 00000000..95573151 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/IAllVariablesOfModel.java @@ -0,0 +1,17 @@ +package org.simantics.jfreechart.chart.properties; + +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; + +public interface IAllVariablesOfModel { + + + public Read> getVariablesQuery(); + + public String getVariablesLabel(ReadGraph graph, String rvi) throws DatabaseException; + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/JFreeChartPropertyColorProvider.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/JFreeChartPropertyColorProvider.java new file mode 100644 index 00000000..ab4c4327 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/JFreeChartPropertyColorProvider.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.jface.resource.ColorDescriptor; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.simantics.browsing.ui.swt.widgets.impl.ITrackedColorProvider; + +/** + * ColorProvider providing coloring scheme for chart tab text widgets + * + * @author Teemu Lempinen + * + */ +public class JFreeChartPropertyColorProvider implements ITrackedColorProvider { + + private final ResourceManager resourceManager; + + private final ColorDescriptor highlightColor = ColorDescriptor.createFrom(new RGB(254, 255, 197)); + private final ColorDescriptor inactiveColor = ColorDescriptor.createFrom(new RGB(255, 255, 255)); + private final ColorDescriptor invalidInputColor = ColorDescriptor.createFrom(new RGB(255, 128, 128)); + + public JFreeChartPropertyColorProvider(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + @Override + public Color getEditingBackground() { + return null; + } + + @Override + public Color getHoverBackground() { + return resourceManager.createColor(highlightColor); + } + + @Override + public Color getInactiveBackground() { + return resourceManager.createColor(inactiveColor); + } + + @Override + public Color getInvalidBackground() { + return resourceManager.createColor(invalidInputColor); + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/LabelPropertyTabContributor.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/LabelPropertyTabContributor.java new file mode 100644 index 00000000..045b4d31 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/LabelPropertyTabContributor.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.AsyncListener; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.selectionview.PropertyTabContributorImpl; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.ui.AdaptionUtils; + +public abstract class LabelPropertyTabContributor extends PropertyTabContributorImpl { + + private boolean isDisposed = false; + + + public void createControl(Composite parent, final IWorkbenchSite site, final ISessionContext context, final WidgetSupportImpl support) { + super.createControl(parent, site, context, support); + + // Add dispose listener to make sure name listening receives the correct isDisposed -value + parent.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + LabelPropertyTabContributor.this.dispose(); + } + }); + } + + @Override + public void updatePartName(ISelection forSelection, final Callback updateCallback) { + final Variable variable = AdaptionUtils.adaptToSingle(forSelection, Variable.class); + final Resource resource = AdaptionUtils.adaptToSingle(forSelection, Resource.class); + if(resource == null && variable == null) { + updateCallback.run("Selection properties"); + return; + } + + SimanticsUI.getSession().asyncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + + Resource r; + if(variable != null) { + r = (Resource)variable.getRepresents(graph); + } else { + r = resource; + } + + if(graph.hasStatement(r, mr.ElementToComponent)) { + r = graph.getSingleObject(r, mr.ElementToComponent); + } + String label = graph.getPossibleRelatedValue(r, l0.HasLabel); + if(label != null) + return label; + label = graph.getPossibleRelatedValue(r, l0.HasName); + if(label != null) + return label; + return "No name for selection"; + } + }, new AsyncListener() { + + @Override + public void execute(AsyncReadGraph graph, String result) { + updateCallback.run(result); + } + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + + } + + @Override + public boolean isDisposed() { + return isDisposed; + } + }); + } + + @Override + protected void dispose() { + this.isDisposed = true; + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RVIFactory.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RVIFactory.java new file mode 100644 index 00000000..52a9a632 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RVIFactory.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Class for providing RVI content to a text field with all '/' characters changed to '.' + * @author Teemu Lempinen + * + */ +public class RVIFactory extends ReadFactoryImpl { + + @Override + public String perform(ReadGraph graph, Resource input) throws DatabaseException { + String value = graph.getPossibleRelatedValue(input, JFreeChartResource.getInstance(graph).variableRVI); + return value != null ? value = value.substring(1).replace('/', '.') : ""; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RVIModifier.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RVIModifier.java new file mode 100644 index 00000000..3c87d5aa --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RVIModifier.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.jface.bindings.keys.KeyStroke; +import org.eclipse.jface.bindings.keys.ParseException; +import org.eclipse.jface.fieldassist.ContentProposalAdapter; +import org.eclipse.jface.fieldassist.IContentProposal; +import org.eclipse.jface.fieldassist.IContentProposalListener; +import org.eclipse.jface.fieldassist.IContentProposalListener2; +import org.eclipse.jface.fieldassist.TextContentAdapter; +import org.eclipse.swt.widgets.Control; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Class for modifying variable name to rvi and saving it to database. + * + * Modifier also adds content proposal support to the control it is added to. + * @author Teemu Lempinen + * + */ +public class RVIModifier extends TextModifyListenerImpl { + + private boolean active; + private Control control; + private String rviUri; + private String indexUri; + + private char[] alphaNumericCharacters = { + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','å','ä','ö', + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Å','Ä','Ö', + '1','2','3','4','5','6','7','8','9','0','.'}; + + /** + * Create a new RVIModifier and attach a content proposal support to control + * @param control + * @param support + */ + public RVIModifier(Control control, WidgetSupport support) { + this(control, support, JFreeChartResource.URIs.variableRVI, JFreeChartResource.URIs.variableFilter); + } + + + public RVIModifier(Control control, WidgetSupport support, String rviRelationUri, String indexUri) { + this.rviUri = rviRelationUri; + this.indexUri = indexUri; + + this.control = control; + this.active = true; + + KeyStroke keyStroke = null; + try { + keyStroke = KeyStroke.getInstance("Ctrl+Space"); + } catch (ParseException e1) { + e1.printStackTrace(); + } + + //SimpleContentProposalProvider scpp = new VariableProposalProvider(control, support); + VariableProposalProvider scpp = new VariableProposalProvider(control, support); + scpp.setFiltering(true); + + ContentProposalAdapter adapter = new ContentProposalAdapter( + control, new TextContentAdapter(), scpp, keyStroke, alphaNumericCharacters); + adapter.setAutoActivationDelay(0); + adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); + adapter.addContentProposalListener(new IContentProposalListener2() { + + @Override + public void proposalPopupOpened(ContentProposalAdapter adapter) { + if(RVIModifier.this != null) + RVIModifier.this.deactivate(); + } + + @Override + public void proposalPopupClosed(ContentProposalAdapter adapter) { + if(RVIModifier.this != null) + RVIModifier.this.activate(); + } + }); + + adapter.addContentProposalListener(new IContentProposalListener() { + + @Override + public void proposalAccepted(IContentProposal proposal) { + if(RVIModifier.this.control != null && !RVIModifier.this.control.isDisposed()) + RVIModifier.this.modifyText(new TrackedModifyEvent(RVIModifier.this.control, proposal.getContent())); + } + }); + + + } + + + @Override + public void applyText(WriteGraph graph, Resource resource, String text) throws DatabaseException { + if(active) { + text = "/" + text.replace('.', '/'); + graph.claimLiteral(resource, getRVIRelation(graph), text, Bindings.STRING); + graph.deny(resource, getIndexRelation(graph)); + } + } + + private Resource getRVIRelation(ReadGraph graph) throws DatabaseException { + return graph.getResource(rviUri); + } + + private Resource getIndexRelation(ReadGraph graph) throws DatabaseException { + return graph.getResource(indexUri); + } + + public void deactivate() { + active = false; + } + + public void activate() { + active = true; + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RangeComposite.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RangeComposite.java new file mode 100644 index 00000000..b3d95473 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RangeComposite.java @@ -0,0 +1,289 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.RunnableWithObject; +import org.simantics.utils.datastructures.Triple; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Composite for range controls in chart series properties + * @author Teemu Lempinen + * + */ +public class RangeComposite extends Composite implements Widget { + + private Composite composite; + + public RangeComposite(Composite parent, ISessionContext context, WidgetSupport support, int style) { + super(parent, style); + support.register(this); + GridLayoutFactory.fillDefaults().spacing(3, 0).margins(3, 3).applyTo(this); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this); + composite = this; + } + + @Override + public void setInput(final ISessionContext context, final Object input) { + if(composite == null || composite.isDisposed()) + return; + + final Resource series = AdaptionUtils.adaptToSingle(input, Resource.class); + + RangeHandlerFactory f; + try { + f = context.getSession().syncRequest(new Read() { + @Override + public RangeHandlerFactory perform(ReadGraph graph) + throws DatabaseException { + return graph.adapt(series, RangeHandlerFactory.class); + } + }); + + } catch (DatabaseException e) { + //ExceptionUtils.logAndShowError("Insert something intelligent here.", e); + return; + } + + final RangeHandlerFactory factory = f; + + /* + * Listen to the enumerations assigned to the variable in this series. + * Listener is needed because the user can change the variableRVI for the series + * and that changes the options for range + */ + context.getSession().asyncRequest(factory.getRequest(series), new Listener>() { + + @Override + public void execute(LinkedHashMap result) { + if(isDisposed()) + return; + + // Always modify the composite, even with null result + composite.getDisplay().asyncExec(new RunnableWithObject(result) { + @Override + public void run() { + if(composite == null || composite.isDisposed()) + return; + + // Remove all content (even with null result) + for(Control child : composite.getChildren()) + child.dispose(); + + composite.layout(); + + if(getObject() == null) + return; + + // New widgetSupport for the combos + WidgetSupportImpl support = new WidgetSupportImpl(); + + Label label; + TrackedCombo combo; + LinkedHashMap result = (LinkedHashMap)getObject(); + Iterator iterator = result.keySet().iterator(); + + // Set the width of the combo + GridLayout gl = (GridLayout)composite.getLayout(); + gl.numColumns = result.size(); + + // For each array index (enumeration), create a label and a combo + int index = 0; + while(iterator.hasNext()) { + Object key = iterator.next(); + Composite c = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(c); + GridLayoutFactory.fillDefaults().applyTo(c); + + label = new Label(c, SWT.NONE); + label.setText((String)key); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.END).applyTo(label); + + combo = new TrackedCombo(c, support, SWT.READ_ONLY); + combo.setItemFactory(factory.getRangeItemFactory(index, (Resource)result.get(key))); + combo.setSelectionFactory(new RangeSelectionFactory(index)); + combo.addModifyListener(new RangeModifyListener(index, result.size())); + GridDataFactory.fillDefaults().applyTo(combo.getWidget()); + index++; + } + + // Set input for the combos + support.fireInput(context, input); + + /* + * Find out if this composite is located in a scrolled composite. + * If it is, resize the scrolled composite + */ + composite.layout(); + Composite previousParent = composite.getParent(); + for(int i = 0; i < 7 && previousParent != null; i++) { + previousParent.layout(); + if(previousParent.getParent() instanceof ScrolledComposite) { + ScrolledComposite sc = (ScrolledComposite) previousParent.getParent(); + Point size = previousParent.computeSize(SWT.DEFAULT, SWT.DEFAULT); + sc.setMinSize(size); + break; + } + previousParent = previousParent.getParent(); + } + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return composite == null || composite.isDisposed(); + } + }); + } + + /** + * + * @author Teemu Lempinen + * + */ + private class RangeSelectionFactory extends ReadFactoryImpl { + + int index; + + /** + * + * @param index Index of the enumeration in the variable + */ + public RangeSelectionFactory(int index) { + this.index = index; + } + + public Object getIdentity(Object inputContents) { + return new Triple>(inputContents, index, getClass()); + } + + @Override + public String perform(ReadGraph graph, Resource series) throws DatabaseException { + String[] filter = graph.getPossibleRelatedValue(series, getIndexRelation(graph), Bindings.STRING_ARRAY); + + + /* + * If no filter was found or the index is not applicable, return the first index + */ + String result = null; + if(filter == null) + result = getFirstIndex(graph, series, index); + else if(filter.length < index) + result = getFirstIndex(graph, series, index); + else + result = filter[index]; + + return result; + } + + } + + + + /** + * RangeModifyListener for modifying a range filter in chart series + * @author Teemu Lempinen + * + */ + private class RangeModifyListener extends ComboModifyListenerImpl { + + private int index, size; + + /** + * + * @param index Index of the modified range filter + * @param size Size of the whole filter (for situations where there is no filter) + */ + public RangeModifyListener(int index, int size) { + this.index = index; + this.size = size; + } + + @Override + public void applyText(WriteGraph graph, Resource series, String text) throws DatabaseException { + Resource filterRelation = getIndexRelation(graph); + String[] filter = graph.getPossibleRelatedValue(series, filterRelation, Bindings.STRING_ARRAY); + + // If there is no filter, create a default filter with all indexes "All" + if(filter == null) { + filter = new String[size]; + for(int i = 0; i < filter.length; i++) { + filter[i] = getFirstIndex(graph, series, i); + } + } + + // Modify the filter index + filter[index] = text; + graph.claimLiteral(series, filterRelation, filter, Bindings.STRING_ARRAY); + } + } + + protected Resource getIndexRelation(ReadGraph graph) { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + return jfree.variableFilter; + } + + private static String getFirstIndex(ReadGraph graph, Resource series, int index) throws DatabaseException { + RangeHandlerFactory f = graph.adapt(series, RangeHandlerFactory.class); + LinkedHashMap map = graph.syncRequest(f.getRequest(series)); + if(map == null) + return null; + else { + Resource enumeration = null; + Iterator iterator = map.values().iterator(); + for(int i = 0; i <= index && iterator.hasNext(); i++) { + enumeration = iterator.next(); + } + if(enumeration != null) { + Map indexmap = f.getRangeItemFactory(index, enumeration).perform(graph, null); + if(indexmap != null) + return indexmap.values().iterator().next().toString(); + } + } + + return null; + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RangeHandlerFactory.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RangeHandlerFactory.java new file mode 100644 index 00000000..f015878c --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/RangeHandlerFactory.java @@ -0,0 +1,15 @@ +package org.simantics.jfreechart.chart.properties; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.db.Resource; +import org.simantics.db.request.Read; + +public interface RangeHandlerFactory { + + public Read> getRequest(final Resource series); + + public ReadFactoryImpl> getRangeItemFactory(int index, Resource res); +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooser.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooser.java new file mode 100644 index 00000000..ce1b351b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooser.java @@ -0,0 +1,600 @@ +package org.simantics.jfreechart.chart.properties; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Text; +import org.simantics.browsing.ui.swt.widgets.DefaultColorProvider; +import org.simantics.browsing.ui.swt.widgets.impl.ITrackedColorProvider; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactory; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; + +/** + * Widget for choosing and labeled object from a set of objects. + * + * Supports cases when multiple objects have the same label (as much as possible) + * + * + * Based on org.simantics.browsing.ui.swt.widgets.Trackedtext + * + * + * @author Marko Luukkainen + * + */ +public class StringChooser implements Widget{ + private static final int EDITING = 1 << 0; + private static final int MODIFIED_DURING_EDITING = 1 << 1; + + /** + * Used to tell whether or not a mouseDown has occurred after a focusGained + * event to be able to select the whole text field when it is pressed for + * the first time while the widget holds focus. + */ + private static final int MOUSE_DOWN_FIRST_TIME = 1 << 2; + private static final int MOUSE_INSIDE_CONTROL = 1 << 3; + + private int caretPositionBeforeEdit; + + private String textBeforeEdit; + + private int state; + + private Map objectToLabel; + private Set allowedLabels; + + private T selected; + + private final Display display; + + private final Text text; + + private CompositeListener listener; + + private ListenerList modifyListeners; + + private ReadFactory objectFactory; + + private ITrackedColorProvider colorProvider; + + private final ResourceManager resourceManager; + + private boolean moveCaretAfterEdit = true; + + private boolean selectAllOnStartEdit = true; + + public StringChooser(Composite parent, WidgetSupport support, int style) { + this.state = 0; + this.text = new Text(parent, style); + this.display = text.getDisplay(); + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), text); + this.colorProvider = new DefaultColorProvider(resourceManager); + if (support!=null) support.register(this); + initialize(); + } + + + + public ResourceManager getResourceManager() { + return resourceManager; + } + + public void setFont(Font font) { + text.setFont(font); + } + + public void setObjectFactory(ReadFactory objectFactory) { + this.objectFactory = objectFactory; + } + + public void setMoveCaretAfterEdit(boolean value) { + this.moveCaretAfterEdit = value; + } + + public void setData(Map data) { + this.objectToLabel = data; + this.allowedLabels = new HashSet(); + this.allowedLabels.addAll(objectToLabel.values()); + } + + public void setData(Collection data) { + this.objectToLabel = new HashMap(); + this.allowedLabels = new HashSet(); + for (T t : data) { + String label = t.toString(); + objectToLabel.put(t, label); + allowedLabels.add(label); + } + } + + public void setSelected(T selected) { + if (selected != null) { + String label = objectToLabel.get(selected); + if (label == null) + return; + this.selected = selected; + this.text.setText(label); + } else { + this.selected = null; + this.text.setText(""); + } + } + + public void setSelected(String label) { + // TODO : we could create a label to object map. + for (T t : objectToLabel.keySet()) { + if (label.equals(objectToLabel.get(t))) { + setSelected(t); + return; + } + } + } + + + @Override + public void setInput(ISessionContext context, Object input) { + if (modifyListeners != null) { + for (Object o : modifyListeners.getListeners()) { + if(o instanceof Widget) { + ((Widget) o).setInput(context, input); + } + } + } + + if(objectFactory != null) { + objectFactory.listen(context, input, new Listener() { + + @Override + public void exception(final Throwable t) { + display.asyncExec(new Runnable() { + + @Override + public void run() { + if(isDisposed()) return; +// System.out.println("Button received new text: " + text); + text.setText(t.toString()); + } + + }); + } + + @Override + public void execute(final T object) { + + if(text.isDisposed()) return; + + display.asyncExec(new Runnable() { + + @Override + public void run() { + if(isDisposed()) return; + setSelected(object); +// text.getParent().layout(); +// text.getParent().getParent().layout(); + } + + }); + } + + @Override + public boolean isDisposed() { + return text.isDisposed(); + } + + }); + } + + } + + /** + * Common initialization. Assumes that text is already created. + */ + private void initialize() { + Assert.isNotNull(text); + + text.setBackground(colorProvider.getInactiveBackground()); + text.setDoubleClickEnabled(false); + + listener = new CompositeListener(); + + text.addModifyListener(listener); + text.addDisposeListener(listener); + text.addKeyListener(listener); + text.addMouseTrackListener(listener); + text.addMouseListener(listener); + text.addFocusListener(listener); + } + + public void startEdit(boolean selectAll) { + if (isEditing()) { + // Print some debug incase we end are in an invalid state + System.out.println("TrackedText: BUG: startEdit called when in editing state"); + } +// System.out.println("start edit: selectall=" + selectAll + ", text=" + text.getText() + ", caretpos=" + caretPositionBeforeEdit); + + // Backup text-field data for reverting purposes + caretPositionBeforeEdit = text.getCaretPosition(); + textBeforeEdit = text.getText(); + + // Signal editing state + setBackground(colorProvider.getEditingBackground()); + + if (selectAll) { + text.selectAll(); + } + state |= EDITING | MOUSE_DOWN_FIRST_TIME; + } + + @SuppressWarnings("unchecked") + private void applyEdit() { + try { + if (isTextValid() != null) { + text.setText(textBeforeEdit); + } else if (isModified() && !text.getText().equals(textBeforeEdit)) { + setSelected(text.getText()); + //System.out.println("apply"); + if (modifyListeners != null) { + StringChooserModifyEvent event = new StringChooserModifyEvent(text, selected, text.getText()); + for (Object o : modifyListeners.getListeners()) { + ((StringChooserModifyListener) o).modifySelection(event); + } + } + } + } catch (Throwable t) { + t.printStackTrace(); + } finally { + endEdit(); + } + } + + private void endEdit() { + if (text.isDisposed()) + return; + + if (!isEditing()) { + // Print some debug incase we end are in an invalid state + //ExceptionUtils.logError(new Exception("BUG: endEdit called when not in editing state")); + //System.out.println(); + } + setBackground(isMouseInsideControl() ? colorProvider.getHoverBackground() : colorProvider.getInactiveBackground()); +// System.out.println("endEdit: " + text.getText() + ", caret: " + text.getCaretLocation() + ", selection: " + text.getSelection()); + // Always move the caret to the end of the string + if(moveCaretAfterEdit) + text.setSelection(text.getCharCount()); + state &= ~(EDITING | MOUSE_DOWN_FIRST_TIME); + setModified(false); + } + + private void revertEdit() { + if (!isEditing()) { + // Print some debug incase we end are in an invalid state + //ExceptionUtils.logError(new Exception("BUG: revertEdit called when not in editing state")); + System.out.println("BUG: revertEdit called when not in editing state"); + } + text.setText(textBeforeEdit); + text.setSelection(caretPositionBeforeEdit); + setBackground(isMouseInsideControl() ? colorProvider.getHoverBackground() : colorProvider.getInactiveBackground()); + state &= ~(EDITING | MOUSE_DOWN_FIRST_TIME); + setModified(false); + } + + private boolean isEditing() { + return (state & EDITING) != 0; + } + + private void setModified(boolean modified) { + if (modified) { + state |= MODIFIED_DURING_EDITING; + } else { + state &= ~MODIFIED_DURING_EDITING; + } + } + + private boolean isMouseInsideControl() { + return (state & MOUSE_INSIDE_CONTROL) != 0; + } + + private void setMouseInsideControl(boolean inside) { + if (inside) + state |= MOUSE_INSIDE_CONTROL; + else + state &= ~MOUSE_INSIDE_CONTROL; + } + + private boolean isModified() { + return (state & MODIFIED_DURING_EDITING) != 0; + } + + public void setSelectAllOnStartEdit(boolean selectAll) { + this.selectAllOnStartEdit = selectAll; + } + + public void setEditable(boolean editable) { + if (editable) { + text.setEditable(true); + setBackground(isMouseInsideControl() ? colorProvider.getHoverBackground() : colorProvider.getInactiveBackground()); + } else { + text.setEditable(false); + text.setBackground(null); + } + } + + public void setText(String text) { + this.text.setText(text); + } + + public void setTextWithoutNotify(String text) { + this.text.removeModifyListener(listener); + setText(text); + this.text.addModifyListener(listener); + } + + public Text getWidget() { + return text; + } + + public synchronized void addModifyListener(StringChooserModifyListener listener) { + if (modifyListeners == null) { + modifyListeners = new ListenerList(ListenerList.IDENTITY); + } + modifyListeners.add(listener); + } + + public synchronized void removeModifyListener(StringChooserModifyListener listener) { + if (modifyListeners == null) + return; + modifyListeners.remove(listener); + } + + + + private String isTextValid() { + if (allowedLabels.contains(getWidget().getText())) + return null; + return "There is no such object."; + } + + public void setColorProvider(ITrackedColorProvider provider) { + Assert.isNotNull(provider); + this.colorProvider = provider; + } + + private void setBackground(Color background) { + if(text.isDisposed()) return; + if (!text.getEditable()) { + // Do not alter background when the widget is not editable. + return; + } + text.setBackground(background); + } + + public boolean isDisposed() { + return text.isDisposed(); + } + + public Display getDisplay() { + return display; + } + + public String getText() { + return text.getText(); + } + + public int getCaretPosition() { + return text.getCaretPosition(); + } + + + /** + * A composite of many UI listeners for creating the functionality of this + * class. + */ + private class CompositeListener + implements ModifyListener, DisposeListener, KeyListener, MouseTrackListener, + MouseListener, FocusListener + { + // Keyboard/editing events come in the following order: + // 1. keyPressed + // 2. verifyText + // 3. modifyText + // 4. keyReleased + + @Override + public void modifyText(ModifyEvent e) { + //System.out.println("modifyText: " + e); + setModified(true); + + String valid = isTextValid(); + if (valid != null) { + setBackground(colorProvider.getInvalidBackground()); + } else { + if (isEditing()) + setBackground(colorProvider.getEditingBackground()); + else + setBackground(colorProvider.getInactiveBackground()); + } + } + + @Override + public void widgetDisposed(DisposeEvent e) { + getWidget().removeModifyListener(this); + } + + private boolean isMultiLine() { + return (text.getStyle() & SWT.MULTI) != 0; + } + + private boolean hasMultiLineCommitModifier(KeyEvent e) { + return (e.stateMask & SWT.CTRL) != 0; + } + + @Override + public void keyPressed(KeyEvent e) { + //System.out.println("keyPressed: " + e); + if (!isEditing()) { + // ESC, ENTER & keypad ENTER must not start editing + if (e.keyCode == SWT.ESC) + return; + + if (!isMultiLine()) { + if (e.keyCode == SWT.F2 || e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + startEdit(selectAllOnStartEdit); + } else if (e.character != '\0') { + startEdit(false); + } + } else { + // In multi-line mode, TAB must not start editing! + if (e.keyCode == SWT.F2) { + startEdit(selectAllOnStartEdit); + } else if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + if (hasMultiLineCommitModifier(e)) { + e.doit = false; + } else { + startEdit(false); + } + } else if (e.keyCode == SWT.TAB) { + text.traverse(((e.stateMask & SWT.SHIFT) != 0) ? SWT.TRAVERSE_TAB_PREVIOUS : SWT.TRAVERSE_TAB_NEXT); + e.doit = false; + } else if (e.character != '\0') { + startEdit(false); + } + } + } else { + // ESC reverts any changes made during this edit + if (e.keyCode == SWT.ESC) { + revertEdit(); + } + if (!isMultiLine()) { + if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + applyEdit(); + } + } else { + if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + if (hasMultiLineCommitModifier(e)) { + applyEdit(); + e.doit = false; + } + } + } + } + } + + @Override + public void keyReleased(KeyEvent e) { + //System.out.println("keyReleased: " + e); + } + + @Override + public void mouseEnter(MouseEvent e) { + //System.out.println("mouseEnter"); + if (!isEditing()) { + setBackground(colorProvider.getHoverBackground()); + } + setMouseInsideControl(true); + } + + @Override + public void mouseExit(MouseEvent e) { + //System.out.println("mouseExit"); + if (!isEditing()) { + setBackground(colorProvider.getInactiveBackground()); + } + setMouseInsideControl(false); + } + + @Override + public void mouseHover(MouseEvent e) { + //System.out.println("mouseHover"); + setMouseInsideControl(true); + } + + @Override + public void mouseDoubleClick(MouseEvent e) { + //System.out.println("mouseDoubleClick: " + e); + if (e.button == 1) { + getWidget().selectAll(); + } + } + + @Override + public void mouseDown(MouseEvent e) { + //System.out.println("mouseDown: " + e); + if (!isEditing()) { + // In reality we should never get here, since focusGained + // always comes before mouseDown, but let's keep this + // fallback just to be safe. + if (e.button == 1) { + startEdit(selectAllOnStartEdit); + } + } else { + if (e.button == 1 && (state & MOUSE_DOWN_FIRST_TIME) != 0) { + if (!isMultiLine()) { + // This is useless for multi-line texts + getWidget().selectAll(); + } + state &= ~MOUSE_DOWN_FIRST_TIME; + } + } + } + + @Override + public void mouseUp(MouseEvent e) { + } + + @Override + public void focusGained(FocusEvent e) { + //System.out.println("focusGained"); + if (!isEditing()) { + if (!isMultiLine()) { + // Always start edit on single line texts when focus is gained + startEdit(selectAllOnStartEdit); + } + } + } + + @Override + public void focusLost(FocusEvent e) { + //System.out.println("focusLost"); + if (isEditing()) { + applyEdit(); + } + } + } + + public void dispose() { + allowedLabels.clear(); + allowedLabels = null; + objectFactory = null; + objectToLabel.clear(); + objectToLabel = null; + + } + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyEvent.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyEvent.java new file mode 100644 index 00000000..c4916655 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyEvent.java @@ -0,0 +1,32 @@ +package org.simantics.jfreechart.chart.properties; + +import java.util.EventObject; + +import org.eclipse.swt.widgets.Widget; + +public class StringChooserModifyEvent extends EventObject { + + private static final long serialVersionUID = 2630732165074702762L; + + private T object; + private String text; + + public StringChooserModifyEvent(Widget source, T object, String text) { + super(source); + this.object = object; + this.text = text; + } + + public Widget getWidget() { + return (Widget) getSource(); + } + + public T getObject() { + return object; + } + + public String getText() { + return text; + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListener.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListener.java new file mode 100644 index 00000000..b9756408 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListener.java @@ -0,0 +1,7 @@ +package org.simantics.jfreechart.chart.properties; + +public interface StringChooserModifyListener { + + + void modifySelection(StringChooserModifyEvent e); +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListenerImpl.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListenerImpl.java new file mode 100644 index 00000000..8fa748dd --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/StringChooserModifyListenerImpl.java @@ -0,0 +1,71 @@ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Text; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.utils.ReflectionUtils; +import org.simantics.utils.ui.ISelectionUtils; + +public abstract class StringChooserModifyListenerImpl implements StringChooserModifyListener, Widget { + protected ISessionContext context; + protected T lastInput = null; + + protected final Class clazz; + + public StringChooserModifyListenerImpl() { + clazz = ReflectionUtils.getSingleParameterType(getClass()); + } + + private Object getInputContents(Object input, Class inputClass) { + if (inputClass.isInstance(input)) + return input; + if (input instanceof ISelection) + return ISelectionUtils.filterSingleSelection(input, inputClass); + return null; + } + + @Override + public void modifySelection(StringChooserModifyEvent e) { + + Text text = (Text)e.getWidget(); + final T2 object = e.getObject(); + final String textValue = text.getText(); + final T input = lastInput; + + try { + context.getSession().syncRequest(new WriteRequest() { + + @SuppressWarnings("unchecked") + @Override + public void perform(WriteGraph graph) throws DatabaseException { + + if(clazz.isInstance(input)) { + applyObject(graph, (T)input, object, textValue); + } else { + T single = (T)getInputContents(input, clazz); + if(single != null) + applyObject(graph, single, object, textValue); + } + + + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + } + + @Override + public void setInput(ISessionContext context, Object parameter) { + this.context = context; + lastInput = (T)parameter; + } + + abstract public void applyObject(WriteGraph graph, T input, T2 object, String text) throws DatabaseException; + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/TitleFactory.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/TitleFactory.java new file mode 100644 index 00000000..c02b3a58 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/TitleFactory.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * TextFactory for chart title + * @author Teemu Lempinen + * + */ +public class TitleFactory extends ReadFactoryImpl { + @Override + public String perform(ReadGraph graph, Resource chart) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Resource title = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.TextTitle)); + if(title == null) + return ""; + else { + String label = graph.getPossibleRelatedValue(title, l0.HasLabel, Bindings.STRING); + return label == null ? "" : label; + } + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/TitleModifier.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/TitleModifier.java new file mode 100644 index 00000000..543d173b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/TitleModifier.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * TitleModifier for chart title + * @author Teemu Lempinen + * + */ +public class TitleModifier extends TextModifyListenerImpl { + + @Override + public void applyText(WriteGraph graph, Resource chart, String text) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Resource title = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.TextTitle)); + if(title == null) { + title = GraphUtils.create2(graph, jfree.TextTitle, + jfree.Title_position, jfree.Top); + } + graph.claimLiteral(title, l0.HasLabel, text); + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/TrackedSpinner.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/TrackedSpinner.java new file mode 100644 index 00000000..74673a03 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/TrackedSpinner.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Spinner; +import org.simantics.browsing.ui.common.ErrorLogger; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactory; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.utils.ui.SWTUtils; + +/** + * Class for implementing Widget behavior for SWT Spinner in Simantics. + * + * @author Teemu Lempinen + * + */ +public class TrackedSpinner implements Widget { + + private Spinner spinner; + private ListenerList modifyListeners; + private ReadFactory selectionFactory; + + + public TrackedSpinner(Composite parent, WidgetSupport support, int style) { + spinner = new Spinner(parent, style); + support.register(this); + + // Add a ModifyListener that uses all listeners in modifyListeners -list + spinner.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + if (modifyListeners != null) { + TrackedModifyEvent event = new TrackedModifyEvent(spinner, spinner.getText()); + for (Object o : modifyListeners.getListeners()) { + ((TextModifyListener) o).modifyText(event); + } + } + } + }); + } + + @Override + public void setInput(ISessionContext context, Object input) { + + // Update all modifyListeners + if (modifyListeners != null) { + for (Object o : modifyListeners.getListeners()) { + if(o instanceof Widget) { + ((Widget) o).setInput(context, input); + } + } + } + + if (selectionFactory != null) { + // Get a value for the spinner + selectionFactory.listen(context, input, new Listener() { + @Override + public void exception(Throwable t) { + ErrorLogger.defaultLogError(t); + } + @Override + public void execute(final Integer selection) { + SWTUtils.asyncExec(spinner, new Runnable() { + @Override + public void run() { + if(isDisposed()) return; + spinner.setSelection(selection); + } + }); + } + @Override + public boolean isDisposed() { + return spinner.isDisposed(); + } + }); + } + + } + + /** + * Set a selection factory for the spinner + * + * @param selectionFactory ReadFactory SelectionFactory + */ + public void setSelectionFactory(ReadFactory selectionFactory) { + this.selectionFactory = selectionFactory; + } + + /** + * Add a modifyListener for the spinner + * @param listener TextModifyListener + */ + public synchronized void addModifyListener(TextModifyListener listener) { + if (modifyListeners == null) { + modifyListeners = new ListenerList(ListenerList.IDENTITY); + } + modifyListeners.add(listener); + } + + /** + * Remove modifyListener from the spinner + * + * @param listener TextModifyListener + */ + public synchronized void removeModifyListener(TextModifyListener listener) { + if (modifyListeners == null) + return; + modifyListeners.remove(listener); + } + + /** + * Get the SWT Spinner of this TrackedSpinner widget + * @return + */ + public Spinner getWidget() { + return spinner; + } + + /** + * Set minimum value + * @param value int minimum value + */ + public void setMinimum(int value) { + spinner.setMinimum(value); + } + + /** + * Set maximum value + * @param value int maximum value + */ + public void setMaximum(int value) { + spinner.setMaximum(value); + } + + /** + * Sets the receiver's selection, minimum value, maximum value, digits, increment and page increment all at once. + * + * @param selection the new selection value + * @param minimum the new minimum value + * @param maximum the new maximum value + * @param digits the new digits value + * @param increment the new increment value + * @param pageIncrement the new pageIncrement value + */ + public void setValues(int selection, int minimum, int maximum, int digits, int increment, int pageIncrement) { + spinner.setValues(selection, minimum, maximum, digits, increment, pageIncrement); + } + + /** + * Sets the selection, which is the receiver's position, to the argument. + * If the argument is not within the range specified by minimum and maximum, + * it will be adjusted to fall within this range. + * + * @param value + */ + public void setSelection(int value) { + spinner.setSelection(value); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableExistsValidator.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableExistsValidator.java new file mode 100644 index 00000000..32abe9e6 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableExistsValidator.java @@ -0,0 +1,129 @@ +package org.simantics.jfreechart.chart.properties; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.jface.dialogs.IInputValidator; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Variable exists validator for tracked text widgets. + * + * @author Teemu Lempinen + * + */ +public class VariableExistsValidator implements IInputValidator, Widget { + + protected Collection variables; + protected TrackedText text; + private boolean allowEmpty; + @SuppressWarnings("unused") + private boolean useLabels = false; + + /** + * Validate against all variables + * + * Do not allow empty input + * @param support WidgetSupport + * @param text Text widget + */ + public VariableExistsValidator(WidgetSupport support, TrackedText text) { + this(support, text, false); + } + + + + /** + * Validate against all variables + * + * @param support WidgetSupport + * @param text Text widget + * @param allowEmpty Allow empty input text + */ + public VariableExistsValidator(WidgetSupport support, TrackedText text, boolean allowEmpty) { + support.register(this); + this.variables = new ArrayList(); + this.text = text; + this.allowEmpty = allowEmpty; + } + + public VariableExistsValidator(WidgetSupport support, TrackedText text, boolean allowEmpty, boolean useLabels) { + this(support, text, allowEmpty); + this.useLabels = useLabels; + } + + /** + * Returns null if there is a variable named newText in the model + */ + @Override + public String isValid(String newText) { + if(newText == null || newText.isEmpty()) { + if(allowEmpty) + return null; + else + return "Empty name not allowed"; + } + + synchronized (variables) { + for(ChartVariable variable : variables) { + if(newText.equals(variable.getLabel())) + return null; + if(newText.equals(variable.getRvi())) + return null; + } + } + + return "Not a valid variable name"; + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class); + + if(resource == null) { + variables = new ArrayList(); + return; + } + + + try { + /* Find the model resource. It can be found with PartOf + relations from series resource in a chart */ + AllVariablesOfModel query = AllVariablesOfModel.withRandomResource(context, resource); + + if(query != null) { + // Find all variables and set them as the reference for isValid(String) + SimanticsUI.getSession().asyncRequest(query + , new Listener>() { + + @Override + public void execute(Collection variables) { + VariableExistsValidator.this.variables = variables; + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return text.isDisposed(); + } + + }); + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableProposalProvider.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableProposalProvider.java new file mode 100644 index 00000000..da399f6b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/VariableProposalProvider.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.jface.fieldassist.ContentProposal; +import org.eclipse.jface.fieldassist.IContentProposal; +import org.eclipse.jface.fieldassist.IContentProposalProvider; +import org.eclipse.swt.widgets.Control; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * + * @author Marko Luukkainen + * + */ +public class VariableProposalProvider implements IContentProposalProvider, Widget { + + /* + * The proposals provided. + */ + private Collection proposals; + + /* + * The proposals mapped to IContentProposal. Cached for speed in the case + * where filtering is not used. + */ + private IContentProposal[] contentProposals; + + /* + * Boolean that tracks whether filtering is used. + */ + private boolean filterProposals = false; + + + private boolean compareRVI = false; + /** + * Return an array of Objects representing the valid content proposals for a + * field. + * + * @param contents + * the current contents of the field (only consulted if filtering + * is set to true) + * @param position + * the current cursor position within the field (ignored) + * @return the array of Objects that represent valid proposals for the field + * given its current content. + */ + @SuppressWarnings("unchecked") + public IContentProposal[] getProposals(String contents, int position) { + if (filterProposals) { + @SuppressWarnings("rawtypes") + ArrayList list = new ArrayList(); + if (compareRVI) { + for (ChartVariable proposal : proposals) { + if (proposal.getRvi().length() >= contents.length() && proposal.getRvi().substring(0, contents.length()).equalsIgnoreCase(contents)) { + if (proposal.getLabel() != null) + list.add(new ContentProposal(proposal.getRvi(),proposal.getLabel(), null)); + else + list.add(new ContentProposal(proposal.getRvi())); + } else if (proposal.getLabel() != null && proposal.getLabel().length() >= contents.length() && proposal.getLabel().substring(0, contents.length()).equalsIgnoreCase(contents)) { + list.add(new ContentProposal(proposal.getRvi(),proposal.getLabel(), null)); + } + } + } else { + for (ChartVariable proposal : proposals) { + if (proposal.getLabel() != null && proposal.getLabel().length() >= contents.length() && proposal.getLabel().substring(0, contents.length()).equalsIgnoreCase(contents)) { + list.add(new ContentProposal(proposal.getRvi(),proposal.getLabel(), null)); + } + } + } + + return (IContentProposal[]) list.toArray(new IContentProposal[list + .size()]); + } + if (contentProposals == null) { + contentProposals = new IContentProposal[proposals.size()]; + Iterator iter = proposals.iterator(); + for (int i = 0; i < proposals.size(); i++) { + ChartVariable proposal = iter.next(); + if (proposal.getLabel() != null) + contentProposals[i] = new ContentProposal(proposal.getRvi(),proposal.getLabel(),null); + else + contentProposals[i] = new ContentProposal(proposal.getRvi()); + } + } + return contentProposals; + } + + /** + * Set the Strings to be used as content proposals. + * + * @param items + * the array of Strings to be used as proposals. + */ + public void setProposals(Collection items) { + this.proposals = items; + contentProposals = null; + } + + /** + * Set the boolean that controls whether proposals are filtered according to + * the current field content. + * + * @param filterProposals + * true if the proposals should be filtered to + * show only those that match the current contents of the field, + * and false if the proposals should remain the + * same, ignoring the field content. + * @since 3.3 + */ + public void setFiltering(boolean filterProposals) { + this.filterProposals = filterProposals; + // Clear any cached proposals. + contentProposals = null; + } + + /** + * Provides all variables a model contains. Given resource needs to be + * part of a model (i.e. using PartOf leads eventually to a SysdynModel). + * + * @param control Control that is using this provider + * @param resource A resource that is part of a model + */ + public VariableProposalProvider(final Control control, WidgetSupport support) { + this.proposals = new ArrayList(); + support.register(this); + this.control = control; + } + + private Resource resource; + private Control control; + + @Override + public void setInput(ISessionContext context, Object input) { + + final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class); + if(resource == null) + return; + this.resource = resource; + /* Find the model resource. It can be found with PartOf + relations from series resource in a chart */ + try { + AllVariablesOfModel query = AllVariablesOfModel.withRandomResource(context, resource); + SimanticsUI.getSession().asyncRequest(query + , new Listener>() { + + @Override + public void execute(Collection result) { + setProposals(result); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return control == null || + control.isDisposed() || + !resource.equals(VariableProposalProvider.this.resource); + } + + }); + } catch (DatabaseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarAxisTab.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarAxisTab.java new file mode 100644 index 00000000..cf11899b --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarAxisTab.java @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.bar; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Spinner; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.properties.AxisHidePropertyComposite; +import org.simantics.jfreechart.chart.properties.ColorPicker; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.jfreechart.chart.properties.TrackedSpinner; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; +import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Tab for bar chart axis properties + * @author Teemu Lempinen + * + */ +public class BarAxisTab extends LabelPropertyTabContributor implements Widget { + + private TrackedSpinner angle; + private Integer angleInt = null; + private WidgetSupportImpl domainAxisSupport = new WidgetSupportImpl(); + private WidgetSupportImpl rangeAxisSupport = new WidgetSupportImpl(); + private TrackedText rangelabel, rangemin, rangemax; + private ScrolledComposite sc; + private Composite composite; + + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + support.register(this); + + // Scrolled composite containing all of the properties in this tab + sc = new ScrolledComposite(body, SWT.NONE | SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(sc); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + composite = new Composite(sc, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // Domain Axis properties + Group domainGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(domainGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(3).applyTo(domainGroup); + domainGroup.setText("Domain axis"); + + // Label for x-axis + Label label = new Label(domainGroup, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Label:"); + + rangelabel = new TrackedText(domainGroup, domainAxisSupport, SWT.BORDER); + rangelabel.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + rangelabel.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + rangelabel.setColorProvider(new JFreeChartPropertyColorProvider(rangelabel.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangelabel.getWidget()); + + Composite axisHide = new AxisHidePropertyComposite(domainGroup, context, domainAxisSupport, SWT.NONE); + GridDataFactory.fillDefaults().span(1, 3).applyTo(axisHide); + + Label angleLabel = new Label(domainGroup, SWT.NONE); + angleLabel.setText("Label angle:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(angleLabel); + + Composite angleComposite = new Composite(domainGroup, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(angleComposite); + GridLayoutFactory.fillDefaults().applyTo(angleComposite); + angle = new TrackedSpinner(angleComposite, domainAxisSupport, SWT.BORDER); + angle.setSelectionFactory(new AngleSelectionFactory()); + angle.addModifyListener(new AngleModifyListener()); + angle.setMinimum(0); + angle.setMaximum(90); + angle.getWidget().setIncrement(5); + GridDataFactory.fillDefaults().applyTo(angle.getWidget()); + + // Domain Color + label = new Label(domainGroup, SWT.NONE); + label.setText("Color:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + Composite colorPicker = new ColorPicker(domainGroup, context, domainAxisSupport, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(colorPicker); + + domainGroup.layout(); + + // Range Axis properties + Group rangeGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(rangeGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(3).applyTo(rangeGroup); + rangeGroup.setText("Range axis"); + + // Label for range axis + label = new Label(rangeGroup, SWT.NONE); + label.setText("Label:"); + label.setAlignment(SWT.RIGHT); + GridDataFactory.fillDefaults().hint(angleLabel.getBounds().width, SWT.DEFAULT).align(SWT.END, SWT.CENTER).applyTo(label); + + rangelabel = new TrackedText(rangeGroup, rangeAxisSupport, SWT.BORDER); + rangelabel.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + rangelabel.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + rangelabel.setColorProvider(new JFreeChartPropertyColorProvider(rangelabel.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangelabel.getWidget()); + + axisHide = new AxisHidePropertyComposite(rangeGroup, context, rangeAxisSupport, SWT.NONE); + GridDataFactory.fillDefaults().span(1, 4).applyTo(axisHide); + + // Min and max values for range axis + label = new Label(rangeGroup, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Min:"); + + Composite minmax = new Composite(rangeGroup, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(minmax); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(minmax); + rangemin = new TrackedText(minmax, rangeAxisSupport, SWT.BORDER); + rangemin.setColorProvider(new JFreeChartPropertyColorProvider(rangemin.getResourceManager())); + rangemin.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Axis_min)); + rangemin.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Axis_min)); + rangemin.setInputValidator(new DoubleValidator(true)); + + label = new Label(minmax, SWT.NONE); + label.setText("Max:"); + rangemax = new TrackedText(minmax, rangeAxisSupport, SWT.BORDER); + rangemax.setColorProvider(new JFreeChartPropertyColorProvider(rangemax.getResourceManager())); + rangemax.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Axis_max)); + rangemax.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Axis_max)); + rangemax.setInputValidator(new DoubleValidator(true)); + + // Range Color + label = new Label(rangeGroup, SWT.NONE); + label.setText("Color:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + colorPicker = new ColorPicker(rangeGroup, context, rangeAxisSupport, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(colorPicker); + + // Resize scrolled composite + sc.setContent(composite); + Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT); + sc.setMinSize(size); + } + + /** + * ModifyListener for the angle {@link TrackedSpinner} + * + * @author Teemu Lempinen + * + */ + private class AngleModifyListener implements TextModifyListener, Widget { + + private ISessionContext context; + private Object lastInput = null; + + @Override + public void modifyText(TrackedModifyEvent e) { + if(context == null) + return; + + // Get the text value from spinner and associated resource (input) + Spinner spinner = (Spinner)e.getWidget(); + final String textValue = spinner.getText(); + final Object input = lastInput; + + try { + context.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Resource domainAxis = AdaptionUtils.adaptToSingle(input, Resource.class); + try { + // usually reliable, since the spinner does all the checks + Double value = Double.parseDouble(textValue); + Double oldValue = graph.getPossibleRelatedValue(domainAxis, jfree.Axis_rotateLabelDegrees, Bindings.DOUBLE); + if(oldValue == null || !oldValue.equals(value)) { + graph.claimLiteral(domainAxis, jfree.Axis_rotateLabelDegrees, value, Bindings.DOUBLE); + angleInt = value.intValue(); + } + } catch (NumberFormatException e) { + graph.claimLiteral(domainAxis, jfree.Axis_rotateLabelDegrees, 0.0, Bindings.DOUBLE); + angleInt = 0; + } + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + } + + @Override + public void setInput(ISessionContext context, Object parameter) { + this.context = context; + lastInput = parameter; + } + + } + + /** + * Class for setting the value for angle {@link TrackedSpinner} + * @author Teemu Lempinen + * + */ + private class AngleSelectionFactory extends ReadFactoryImpl { + + @Override + public Integer perform(ReadGraph graph, Resource domainAxis) throws DatabaseException { + if(angleInt == null) { + Double angle = 0.0; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + if(domainAxis != null) { + Double value = graph.getPossibleRelatedValue(domainAxis, jfree.Axis_rotateLabelDegrees); + if(value != null) + angle = value; + } + return angle.intValue(); + } else { + return angleInt; + } + } + + } + + @Override + public void setInput(final ISessionContext context, Object input) { + final Resource chart = AdaptionUtils.adaptToSingle(input, Resource.class); + if(chart == null) + return; + + context.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.Plot)); + if(plot == null) return; + Resource rangeAxis = graph.getPossibleObject(plot, jfree.Plot_rangeAxis); + if(rangeAxis == null) return; + rangeAxisSupport.fireInput(context, new StructuredSelection(rangeAxis)); + + Resource domainAxis = graph.getPossibleObject(plot, jfree.Plot_domainAxis); + if(domainAxis == null) return; + domainAxisSupport.fireInput(context, new StructuredSelection(domainAxis)); + } + }); + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarGeneralPropertiesTab.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarGeneralPropertiesTab.java new file mode 100644 index 00000000..c2d97014 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarGeneralPropertiesTab.java @@ -0,0 +1,386 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.bar; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.layout.LayoutConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.ChartPropertyOptions; +import org.simantics.jfreechart.chart.properties.BooleanPropertyFactory; +import org.simantics.jfreechart.chart.properties.BooleanSelectionListener; +import org.simantics.jfreechart.chart.properties.DoublePropertyFactory2; +import org.simantics.jfreechart.chart.properties.DoublePropertyModifier2; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.jfreechart.chart.properties.TitleFactory; +import org.simantics.jfreechart.chart.properties.TitleModifier; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; +import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; +import org.simantics.sysdyn.JFreeChartResource; + + +/** + * General properties of a bar chart + * @author Teemu Lempinen + * + */ +public class BarGeneralPropertiesTab extends LabelPropertyTabContributor { + + private ScrolledComposite sc; + private Composite composite; + private Button hgrid, htitle, hlegend; + private TrackedText name, title, time; + private TrackedCombo type; + private TrackedCombo orientation; + + private boolean showTime = true; + private boolean showFilter = false; + + public BarGeneralPropertiesTab() { + + } + + public BarGeneralPropertiesTab(int options) { + showTime = ((options & ChartPropertyOptions.SHOW_TIME) > 0); + showFilter = ((options & ChartPropertyOptions.SHOW_FILTER) > 0); + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + // Scrolled composite containing all of the properties in this tab + sc = new ScrolledComposite(body, SWT.NONE | SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().applyTo(sc); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + composite = new Composite(sc, SWT.NONE); + if (showFilter) + GridLayoutFactory.fillDefaults().numColumns(4).margins(3, 3).applyTo(composite); + else + GridLayoutFactory.fillDefaults().numColumns(3).margins(3, 3).applyTo(composite); + + // General properties + Group general = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(general); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(4).applyTo(general); + general.setText("General"); + + // first column: labels + Composite labelColumn1 = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(labelColumn1); + GridLayoutFactory.fillDefaults().applyTo(labelColumn1); + + // second column: name and title + Composite propertyColumn1 = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(propertyColumn1); + GridLayoutFactory.fillDefaults().spacing(0, LayoutConstants.getSpacing().y).applyTo(propertyColumn1); + + // third column: labels + Composite labelColumn2 = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(labelColumn2); + GridLayoutFactory.fillDefaults().spacing(0, LayoutConstants.getSpacing().y).applyTo(labelColumn2); + + // fourth column: type and time + Composite propertyColumn2 = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(propertyColumn2); + GridLayoutFactory.fillDefaults().applyTo(propertyColumn2); + + // Name + Label label = new Label(labelColumn1, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Name:"); + + name = new org.simantics.browsing.ui.swt.widgets.TrackedText(propertyColumn1, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget()); + name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + name.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + // Type +// label = new Label(labelColumn2, SWT.NONE); +// GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); +// label.setText("Type:"); +// +// type = new TrackedCombo(propertyColumn2, support, SWT.BORDER | SWT.READ_ONLY); +// type.addModifyListener(new TypeModifyListener()); +// type.setItemFactory(new TypeItemFactory()); +// type.setSelectionFactory(new TypeSelectionFactory()); +// GridDataFactory.fillDefaults().applyTo(type.getWidget()); + label = new Label(labelColumn2, SWT.NONE); + label = new Label(propertyColumn2, SWT.NONE); + + // Title (Which is different than name) + label = new Label(labelColumn1, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Title:"); + + title = new org.simantics.browsing.ui.swt.widgets.TrackedText(propertyColumn1, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(title.getWidget()); + title.setTextFactory(new TitleFactory()); + title.addModifyListener(new TitleModifier()); + title.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + if (showTime) { + // Time + label = new Label(labelColumn2, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Time:"); + + time = new org.simantics.browsing.ui.swt.widgets.TrackedText(propertyColumn2, support, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(time.getWidget()); + time.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Chart_time)); + time.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Chart_time)); + time.setInputValidator(new DoubleValidator(true)); + time.setColorProvider(new JFreeChartPropertyColorProvider(time.getResourceManager())); + } + + Group typeGroup = new Group(composite,SWT.NONE); + GridDataFactory.fillDefaults().applyTo(typeGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(typeGroup); + typeGroup.setText("Visuals"); + + label = new Label(typeGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Type:"); + + type = new TrackedCombo(typeGroup, support, SWT.BORDER | SWT.READ_ONLY); + type.addModifyListener(new TypeModifyListener()); + type.setItemFactory(new TypeItemFactory()); + type.setSelectionFactory(new TypeSelectionFactory()); + GridDataFactory.fillDefaults().applyTo(type.getWidget()); + + label = new Label(typeGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Orientation:"); + + orientation = new TrackedCombo(typeGroup, support, SWT.BORDER | SWT.READ_ONLY); + orientation.addModifyListener(new OrientationModifyListener()); + orientation.setItemFactory(new OrientationItemFactory()); + orientation.setSelectionFactory(new OrientationSelectionFactory()); + GridDataFactory.fillDefaults().applyTo(type.getWidget()); + + + // Group for hide options + Group hideGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(hideGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(hideGroup); + hideGroup.setText("Hide"); + + hgrid = new Button(hideGroup, support, SWT.CHECK); + hgrid.setText("Grid"); + hgrid.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleGrid, true)); + hgrid.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleGrid)); + htitle = new Button(hideGroup, support, SWT.CHECK); + htitle.setText("Title"); + htitle.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible, true)); + htitle.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible)); + hlegend = new Button(hideGroup, support, SWT.CHECK); + hlegend.setText("Legend"); + hlegend.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.Chart_visibleLegend, true)); + hlegend.addSelectionListener(new BooleanSelectionListener(context, null, JFreeChartResource.URIs.Chart_visibleLegend)); + + if (showFilter) { + Group filteringGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(filteringGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(filteringGroup); + filteringGroup.setText("Filter"); + label = new Label(filteringGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Use:"); + Button useFilter = new Button(filteringGroup, support, SWT.CHECK); + useFilter.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_used, false)); + useFilter.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_used)); + label = new Label(filteringGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Percent:"); + TrackedText fraction = new TrackedText(filteringGroup, support, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(fraction.getWidget()); + fraction.setTextFactory(new DoublePropertyFactory2(JFreeChartResource.URIs.Plot,JFreeChartResource.URIs.Filter_fraction)); + fraction.addModifyListener(new DoublePropertyModifier2(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_fraction)); + fraction.setInputValidator(new DoubleValidator(true)); + fraction.setColorProvider(new JFreeChartPropertyColorProvider(fraction.getResourceManager())); + } + + // Resize scrolled composite + sc.setContent(composite); + Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT); + sc.setMinSize(size); + + + } + + /** + * + * @author Teemu Lempinen + * + */ + private class TypeSelectionFactory extends ReadFactoryImpl { + @Override + public String perform(ReadGraph graph, Resource chart) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.CategoryPlot)); + if(plot != null) { + Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.CategoryDataset)); + + if(dataset != null) { + Resource renderer = graph.syncRequest(new PossibleObjectWithType(dataset, jfree.Dataset_renderer, jfree.Renderer)); + + if(renderer != null && graph.isInstanceOf(renderer, jfree.StackedBarRenderer)) + return "Stacked"; + } + } + return "Normal"; + } + } + + /** + * RangeItemFactory finds all inexes of a given enumeration + * and adds "Sum" and "All" to the returned indexes + * @author Teemu Lempinen + * + */ + private class TypeItemFactory extends ReadFactoryImpl> { + @Override + public Map perform(ReadGraph graph, Resource series) throws DatabaseException { + LinkedHashMap result = new LinkedHashMap(); + result.put("Normal", "Normal"); + result.put("Stacked", "Stacked"); + return result; + } + } + + /** + * TypeModifyListener for modifying the type of a bar chart + * @author Teemu Lempinen + * + */ + private class TypeModifyListener extends ComboModifyListenerImpl { + @Override + public void applyText(WriteGraph graph, Resource chart, String text) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.CategoryPlot)); + if(plot == null) + return; + + Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.CategoryDataset)); + if(dataset == null) + return; + + graph.deny(dataset, jfree.Dataset_renderer); + + Resource renderer; + if(text.equals("Stacked")) + renderer = GraphUtils.create2(graph, jfree.StackedBarRenderer); + else + renderer = GraphUtils.create2(graph, jfree.BarRenderer); + + graph.claim(dataset, jfree.Dataset_renderer, renderer); + } + } + + /** + * + * @author Marko Luukkainen + * + */ + private class OrientationSelectionFactory extends ReadFactoryImpl { + @Override + public String perform(ReadGraph graph, Resource chart) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.CategoryPlot)); + if(plot != null) { + Boolean orientation = graph.getPossibleRelatedValue(plot, jfree.Plot_orientation); + if (orientation != null) { + if (orientation) + return "Horizontal"; + return "Vertical"; + } + } + return "Vertical"; + } + } + + /** + * + * @author Marko Luukkainen + * + */ + private class OrientationItemFactory extends ReadFactoryImpl> { + @Override + public Map perform(ReadGraph graph, Resource series) throws DatabaseException { + LinkedHashMap result = new LinkedHashMap(); + result.put("Vertical", "Vertical"); + result.put("Horizontal", "Horizontal"); + return result; + } + } + + /** + * + * @author Marko Luukkainen + * + */ + private class OrientationModifyListener extends ComboModifyListenerImpl { + @Override + public void applyText(WriteGraph graph, Resource chart, String text) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.CategoryPlot)); + if(plot == null) + return; + + + if(text.equals("Horizontal")) + graph.claimLiteral(plot, jfree.Plot_orientation,true); + else + graph.claimLiteral(plot, jfree.Plot_orientation,false); + + + } + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesPropertyComposite.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesPropertyComposite.java new file mode 100644 index 00000000..ca8777e2 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesPropertyComposite.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.bar; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.ChartPropertyOptions; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.jfreechart.chart.properties.RVIFactory; +import org.simantics.jfreechart.chart.properties.RVIModifier; +import org.simantics.jfreechart.chart.properties.RangeComposite; +import org.simantics.jfreechart.chart.properties.VariableExistsValidator; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; +import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Composite for modifying properties of a series in a bar chart + * @author Teemu Lempinen + * + */ +public class BarSeriesPropertyComposite extends Composite { + + private TrackedText variable, label, time; + + public BarSeriesPropertyComposite(Composite parent, final ISessionContext context, WidgetSupport support, int options, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this); + + // Variable for the series + Label label = new Label(this, SWT.NONE); + label.setText("Variable:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + variable = new TrackedText(this, support, SWT.BORDER); + variable.setTextFactory(new RVIFactory()); + variable.addModifyListener(new RVIModifier(variable.getWidget(), support)); + variable.setInputValidator(new VariableExistsValidator(support, variable)); + variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget()); + + // Range + label = new Label(this, SWT.NONE); + label.setText("Range:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + RangeComposite rangeComposite = new RangeComposite(this, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeComposite); + + + // Label to be displayed in chart for this series + label = new Label(this, SWT.NONE); + label.setText("Label:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + this.label = new TrackedText(this, support, SWT.BORDER); + this.label.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + this.label.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + this.label.setColorProvider(new JFreeChartPropertyColorProvider(this.label.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.label.getWidget()); + + // Time + if ((options & ChartPropertyOptions.SHOW_TIME) > 0) { + label = new Label(this, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Time:"); + + Composite composite = new Composite(this, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(composite); + GridLayoutFactory.fillDefaults().applyTo(composite); + + time = new org.simantics.browsing.ui.swt.widgets.TrackedText(composite, support, SWT.BORDER); + time.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Series_time)); + time.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Series_time)); + time.setInputValidator(new DoubleValidator(true)); + time.setColorProvider(new JFreeChartPropertyColorProvider(time.getResourceManager())); + GridDataFactory.fillDefaults().applyTo(time.getWidget()); + } + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesPropertyComposite2.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesPropertyComposite2.java new file mode 100644 index 00000000..a9a1d48d --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesPropertyComposite2.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.bar; + +import java.util.Collection; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.ChartPropertyOptions; +import org.simantics.jfreechart.chart.properties.ChartVariable; +import org.simantics.jfreechart.chart.properties.ChartVariableFactory; +import org.simantics.jfreechart.chart.properties.ChartVariableModifier; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.jfreechart.chart.properties.RangeComposite; +import org.simantics.jfreechart.chart.properties.StringChooser; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; +import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Composite for modifying properties of a series in a bar chart + * @author Teemu Lempinen + * + */ +public class BarSeriesPropertyComposite2 extends Composite { + + private TrackedText label, time; + private StringChooser variable; + + public BarSeriesPropertyComposite2(Composite parent, final ISessionContext context, WidgetSupport support, Collection variables, int options, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this); + + // Variable for the series + Label label = new Label(this, SWT.NONE); + label.setText("Variable:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + +// variable = new TrackedText(this, support, SWT.BORDER); +// +// // FIXME: using bijectionmap and trackedText looses the variables that have the same label. +// BijectionMap map = new BijectionMap(); +// for (ChartVariable variable : variables) { +// map.map(variable.getRvi(), variable.toString()); +// } +// variable.setTextFactory(new VariableFactory(map)); +// variable.addModifyListener(new VariableModifier(variable.getWidget(), support)); +// variable.setInputValidator(new VariableExistsValidator(support, variable, false, true)); + + + variable = new StringChooser(this, support, SWT.BORDER); + variable.setData(variables); + variable.setObjectFactory(new ChartVariableFactory(variables)); + variable.addModifyListener(new ChartVariableModifier(variable.getWidget(), support)); + + variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget()); + + // Range + label = new Label(this, SWT.NONE); + label.setText("Range:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + RangeComposite rangeComposite = new RangeComposite(this, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeComposite); + + + // Label to be displayed in chart for this series + label = new Label(this, SWT.NONE); + label.setText("Label:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + this.label = new TrackedText(this, support, SWT.BORDER); + this.label.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + this.label.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + this.label.setColorProvider(new JFreeChartPropertyColorProvider(this.label.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.label.getWidget()); + + if ((options & ChartPropertyOptions.SHOW_TIME) > 0) { + // Time + label = new Label(this, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Time:"); + + Composite composite = new Composite(this, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(composite); + GridLayoutFactory.fillDefaults().applyTo(composite); + + time = new org.simantics.browsing.ui.swt.widgets.TrackedText(composite, support, SWT.BORDER); + time.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Series_time)); + time.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Series_time)); + time.setInputValidator(new DoubleValidator(true)); + time.setColorProvider(new JFreeChartPropertyColorProvider(time.getResourceManager())); + GridDataFactory.fillDefaults().applyTo(time.getWidget()); + } + } + + @Override + public void dispose() { + variable.dispose(); + variable = null; + super.dispose(); + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesTab.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesTab.java new file mode 100644 index 00000000..3dd56229 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesTab.java @@ -0,0 +1,213 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.bar; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.jfreechart.chart.properties.xyline.AxisAndVariablesExplorerComposite; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Tab containing the series of a bar chart + * @author Teemu Lempinen + * + */ +public class BarSeriesTab extends LabelPropertyTabContributor implements Widget { + + private GraphExplorerComposite explorer; + private ScrolledComposite propertyContainer; + private WidgetSupportImpl additionalSupport; + private Button add, remove; + private Resource chartResource; + private BarSeriesPropertyComposite spc; + private int options; + + public BarSeriesTab(int options) { + additionalSupport = new WidgetSupportImpl(); + this.options = options; + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, final ISessionContext context, WidgetSupport support) { + support.register(this); + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // (Ontology-based) GraphExplorer displaying variables in a bar chart + explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE); + explorer.setBrowseContexts(JFreeChartResource.URIs.BarSeriesBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning + explorer.finish(); + + ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateSelection(context); + } + }); + GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer); + + // Scrolled composite for displaying properties of a selection in explorer + propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(propertyContainer); + GridLayoutFactory.fillDefaults().applyTo(propertyContainer); + propertyContainer.setExpandHorizontal(true); + propertyContainer.setExpandVertical(true); + + // Buttons for adding and removing variables from a pie plot + Composite buttonComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(buttonComposite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite); + + add = new Button(buttonComposite, additionalSupport, SWT.NONE); + add.setText("Add"); + add.addSelectionListener(new NewVariableListener(context)); + + remove = new Button(buttonComposite, additionalSupport, SWT.NONE); + remove.setText("Remove"); + remove.addSelectionListener(new RemoveListener(context)); + } + + /** + * Updates the content of propertyContainer + * @param context + */ + private void updateSelection(ISessionContext context) { + ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); + IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class); + if(resource == null) + return; + + for(Control child : propertyContainer.getChildren()) { + child.dispose(); + } + spc = new BarSeriesPropertyComposite(propertyContainer, context, additionalSupport, options,SWT.NONE); + + additionalSupport.fireInput(context, selection); + + propertyContainer.setContent(spc); + Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } + + /** + * SelectionListener for adding a new variable to a plot + * @author Teemu Lempinen + * + */ + private class NewVariableListener extends SelectionListenerImpl { + + public NewVariableListener(ISessionContext context) { + super(context); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + Resource dataset = null; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + if(input == null) { + if(chartResource != null) { + Resource plot = graph.syncRequest(new PossibleObjectWithType(chartResource, l0.ConsistsOf, jfree.Plot)); + if(plot != null) + dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + } + } else { + if(graph.isInstanceOf(input, jfree.Series)) { + dataset = graph.getPossibleObject(input, l0.PartOf); + } + } + + if(dataset != null) { + // Create series with no rvi + ChartUtils.createSeries(graph, dataset, null); + } + } + } + + /** + * SelectionListener for remove button + * @author Teemu Lempinen + * + */ + private class RemoveListener extends SelectionListenerImpl { + + public RemoveListener(ISessionContext context) { + super(context); + } + + /** + * Removes selected resource from explorer + */ + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(input == null) + return; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource list = null; + if(graph.isInstanceOf(input, jfree.Series)) { + // Remove series from dataset and seriesList + Resource dataset = graph.getPossibleObject(input, l0.PartOf); + if(dataset != null) + list = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + + if(list != null) + ListUtils.removeElement(graph, list, input); + RemoverUtil.remove(graph, input); + } + } + } + + @Override + public void setInput(ISessionContext context, Object input) { + chartResource = AdaptionUtils.adaptToSingle(input, Resource.class); + } + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesTab2.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesTab2.java new file mode 100644 index 00000000..24076dda --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/bar/BarSeriesTab2.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.bar; + +import java.util.Collection; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.jfreechart.chart.properties.AllVariablesOfModel; +import org.simantics.jfreechart.chart.properties.ChartVariable; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.jfreechart.chart.properties.xyline.AxisAndVariablesExplorerComposite; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.ui.ExceptionUtils; + +/** + * Tab containing the series of a bar chart + * @author Teemu Lempinen + * + */ +public class BarSeriesTab2 extends LabelPropertyTabContributor implements Widget { + + private GraphExplorerComposite explorer; + private ScrolledComposite propertyContainer; + private WidgetSupportImpl additionalSupport; + private Button add, remove; + private Resource chartResource; + private BarSeriesPropertyComposite2 spc; + private int options; + + public BarSeriesTab2(int options) { + additionalSupport = new WidgetSupportImpl(); + this.options = options; + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, final ISessionContext context, WidgetSupport support) { + support.register(this); + Composite composite = new Composite(body, SWT.NONE); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // (Ontology-based) GraphExplorer displaying variables in a bar chart + explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE); + explorer.setBrowseContexts(JFreeChartResource.URIs.BarSeriesBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning + explorer.finish(); + + ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateSelection(context); + } + }); + GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer); + + // Scrolled composite for displaying properties of a selection in explorer + propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(propertyContainer); + GridLayoutFactory.fillDefaults().applyTo(propertyContainer); + propertyContainer.setExpandHorizontal(true); + propertyContainer.setExpandVertical(true); + + // Buttons for adding and removing variables from a pie plot + Composite buttonComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(buttonComposite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite); + + add = new Button(buttonComposite, additionalSupport, SWT.NONE); + add.setText("Add"); + add.addSelectionListener(new NewVariableListener(context)); + + remove = new Button(buttonComposite, additionalSupport, SWT.NONE); + remove.setText("Remove"); + remove.addSelectionListener(new RemoveListener(context)); + } + + /** + * Updates the content of propertyContainer + * @param context + */ + private void updateSelection(ISessionContext context) { + ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); + IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class); + if(resource == null) + return; + + for(Control child : propertyContainer.getChildren()) { + child.dispose(); + } + + try { + AllVariablesOfModel query = AllVariablesOfModel.withRandomResource(context, resource); + Collection variables = context.getSession().syncRequest(query); + + spc = new BarSeriesPropertyComposite2(propertyContainer, context, additionalSupport, variables, options, SWT.NONE); + + additionalSupport.fireInput(context, selection); + + propertyContainer.setContent(spc); + Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + } + + /** + * SelectionListener for adding a new variable to a plot + * @author Teemu Lempinen + * + */ + private class NewVariableListener extends SelectionListenerImpl { + + public NewVariableListener(ISessionContext context) { + super(context); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + Resource dataset = null; + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + if(input == null) { + if(chartResource != null) { + Resource plot = graph.syncRequest(new PossibleObjectWithType(chartResource, l0.ConsistsOf, jfree.Plot)); + if(plot != null) + dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + } + } else { + if(graph.isInstanceOf(input, jfree.Series)) { + dataset = graph.getPossibleObject(input, l0.PartOf); + } + } + + if(dataset != null) { + // Create series with no rvi + ChartUtils.createSeries(graph, dataset, null); + } + } + } + + /** + * SelectionListener for remove button + * @author Teemu Lempinen + * + */ + private class RemoveListener extends SelectionListenerImpl { + + public RemoveListener(ISessionContext context) { + super(context); + } + + /** + * Removes selected resource from explorer + */ + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(input == null) + return; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource list = null; + if(graph.isInstanceOf(input, jfree.Series)) { + // Remove series from dataset and seriesList + Resource dataset = graph.getPossibleObject(input, l0.PartOf); + if(dataset != null) + list = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + + if(list != null) + ListUtils.removeElement(graph, list, input); + RemoverUtil.remove(graph, input); + } + } + } + + @Override + public void setInput(ISessionContext context, Object input) { + chartResource = AdaptionUtils.adaptToSingle(input, Resource.class); + } + + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieGeneralPropertiesTab.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieGeneralPropertiesTab.java new file mode 100644 index 00000000..e7dfd430 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieGeneralPropertiesTab.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.pie; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.layout.LayoutConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.ChartPropertyOptions; +import org.simantics.jfreechart.chart.properties.BooleanPropertyFactory; +import org.simantics.jfreechart.chart.properties.BooleanSelectionListener; +import org.simantics.jfreechart.chart.properties.DoublePropertyFactory2; +import org.simantics.jfreechart.chart.properties.DoublePropertyModifier2; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.jfreechart.chart.properties.TitleFactory; +import org.simantics.jfreechart.chart.properties.TitleModifier; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; +import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * General properties of a pie chart + * @author Teemu Lempinen + * + */ +public class PieGeneralPropertiesTab extends LabelPropertyTabContributor { + + private ScrolledComposite sc; + private Composite composite; + private Button htitle, hlegend, hlabels; + private TrackedText name, title, time; + + private boolean showTime = true; + private boolean showFilter = false; + + public PieGeneralPropertiesTab() { + + } + + public PieGeneralPropertiesTab(int options) { + showTime = ((options & ChartPropertyOptions.SHOW_TIME) > 0); + showFilter = ((options & ChartPropertyOptions.SHOW_FILTER) > 0); + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + // Scrolled composite containing all of the properties in this tab + sc = new ScrolledComposite(body, SWT.NONE | SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().applyTo(sc); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + composite = new Composite(sc, SWT.NONE); + if (showFilter) + GridLayoutFactory.fillDefaults().numColumns(3).margins(3, 3).applyTo(composite); + else + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // General properties + Group general = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(general); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(4).applyTo(general); + general.setText("General"); + + // first column: labels + Composite labelColumn1 = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(labelColumn1); + GridLayoutFactory.fillDefaults().applyTo(labelColumn1); + + // first column: name and title + Composite propertyColumn1 = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(propertyColumn1); + GridLayoutFactory.fillDefaults().spacing(0, LayoutConstants.getSpacing().y).applyTo(propertyColumn1); + + // first column: labels + Composite labelColumn2 = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(labelColumn2); + GridLayoutFactory.fillDefaults().spacing(0, LayoutConstants.getSpacing().y).applyTo(labelColumn2); + + // first column: type and time + Composite propertyColumn2 = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(propertyColumn2); + GridLayoutFactory.fillDefaults().applyTo(propertyColumn2); + + // Name + Label label = new Label(labelColumn1, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Name:"); + + name = new org.simantics.browsing.ui.swt.widgets.TrackedText(propertyColumn1, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget()); + name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + name.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + // Dummy data for now. Waiting for different pie chart types + label = new Label(labelColumn2, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(label); + label.setText(""); + + label = new Label(propertyColumn2, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(label); + label.setText(""); + + // Title (Which is different than name) + label = new Label(labelColumn1, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Title:"); + + title = new org.simantics.browsing.ui.swt.widgets.TrackedText(propertyColumn1, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(title.getWidget()); + title.setTextFactory(new TitleFactory()); + title.addModifyListener(new TitleModifier()); + title.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + if (showTime) { + // Time + label = new Label(labelColumn2, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Time:"); + + time = new org.simantics.browsing.ui.swt.widgets.TrackedText(propertyColumn2, support, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(time.getWidget()); + time.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Chart_time)); + time.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Chart_time)); + time.setInputValidator(new DoubleValidator(true)); + time.setColorProvider(new JFreeChartPropertyColorProvider(time.getResourceManager())); + } + // Group for hide options + Group hideGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(hideGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(hideGroup); + hideGroup.setText("Hide"); + + htitle = new Button(hideGroup, support, SWT.CHECK); + htitle.setText("Title"); + htitle.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible, true)); + htitle.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible)); + hlegend = new Button(hideGroup, support, SWT.CHECK); + hlegend.setText("Legend"); + hlegend.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.Chart_visibleLegend, true)); + hlegend.addSelectionListener(new BooleanSelectionListener(context, null, JFreeChartResource.URIs.Chart_visibleLegend)); + hlabels = new Button(hideGroup, support, SWT.CHECK); + hlabels.setText("Section labels"); + hlabels.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleLabels, true)); + hlabels.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleLabels)); + + if (showFilter) { + Group filteringGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(filteringGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(filteringGroup); + filteringGroup.setText("Filter"); + label = new Label(filteringGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Use:"); + Button useFilter = new Button(filteringGroup, support, SWT.CHECK); + useFilter.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_used, false)); + useFilter.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_used)); + label = new Label(filteringGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Percent:"); + TrackedText fraction = new TrackedText(filteringGroup, support, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(fraction.getWidget()); + fraction.setTextFactory(new DoublePropertyFactory2(JFreeChartResource.URIs.Plot,JFreeChartResource.URIs.Filter_fraction)); + fraction.addModifyListener(new DoublePropertyModifier2(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Filter_fraction)); + fraction.setInputValidator(new DoubleValidator(true)); + fraction.setColorProvider(new JFreeChartPropertyColorProvider(fraction.getResourceManager())); + } + + sc.setContent(composite); + Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT); + sc.setMinSize(size); + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesPropertyComposite.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesPropertyComposite.java new file mode 100644 index 00000000..1dd80e8d --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesPropertyComposite.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.pie; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.ChartPropertyOptions; +import org.simantics.jfreechart.chart.properties.BooleanPropertyFactory; +import org.simantics.jfreechart.chart.properties.BooleanSelectionListener; +import org.simantics.jfreechart.chart.properties.ColorPicker; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.jfreechart.chart.properties.RVIFactory; +import org.simantics.jfreechart.chart.properties.RVIModifier; +import org.simantics.jfreechart.chart.properties.RangeComposite; +import org.simantics.jfreechart.chart.properties.VariableExistsValidator; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; +import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Composite containing the properties of a series + * @author Teemu Lempinen + * + */ +public class PieSeriesPropertyComposite extends Composite { + + private TrackedText variable, label, time; + + public PieSeriesPropertyComposite(Composite parent, ISessionContext context, WidgetSupport support, int options, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this); + + // Variable for the series + Label label = new Label(this, SWT.NONE); + label.setText("Variable:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + variable = new TrackedText(this, support, SWT.BORDER); + variable.setTextFactory(new RVIFactory()); + variable.addModifyListener(new RVIModifier(variable.getWidget(), support)); + variable.setInputValidator(new VariableExistsValidator(support, variable)); + variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget()); + + // Range + label = new Label(this, SWT.NONE); + label.setText("Range:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + RangeComposite rangeComposite = new RangeComposite(this, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeComposite); + + + // Label to be displayed in chart for this series + label = new Label(this, SWT.NONE); + label.setText("Label:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + this.label = new TrackedText(this, support, SWT.BORDER); + this.label.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + this.label.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + this.label.setColorProvider(new JFreeChartPropertyColorProvider(this.label.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.label.getWidget()); + + // Color + label = new Label(this, SWT.NONE); + label.setText("Color:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + Composite colorPicker = new ColorPicker(this, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(colorPicker); + + // Time + if ((options & ChartPropertyOptions.SHOW_TIME) > 0) { + label = new Label(this, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Time:"); + + Composite composite = new Composite(this, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(composite); + GridLayoutFactory.fillDefaults().applyTo(composite); + + time = new org.simantics.browsing.ui.swt.widgets.TrackedText(composite, support, SWT.BORDER); + time.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Series_time)); + time.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Series_time)); + time.setInputValidator(new DoubleValidator(true)); + time.setColorProvider(new JFreeChartPropertyColorProvider(time.getResourceManager())); + GridDataFactory.fillDefaults().applyTo(time.getWidget()); + } + // Exploded + label = new Label(this, SWT.NONE); + label.setText(""); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + Button exploded = new Button(this, support, SWT.CHECK); + exploded.setText("Exploded"); + exploded.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Series_exploded)); + exploded.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Series_exploded)); + GridDataFactory.fillDefaults().applyTo(exploded.getWidget()); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesPropertyComposite2.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesPropertyComposite2.java new file mode 100644 index 00000000..3f3c4aff --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesPropertyComposite2.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.pie; + +import java.util.Collection; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.ChartPropertyOptions; +import org.simantics.jfreechart.chart.properties.BooleanPropertyFactory; +import org.simantics.jfreechart.chart.properties.BooleanSelectionListener; +import org.simantics.jfreechart.chart.properties.ChartVariable; +import org.simantics.jfreechart.chart.properties.ChartVariableFactory; +import org.simantics.jfreechart.chart.properties.ChartVariableModifier; +import org.simantics.jfreechart.chart.properties.ColorPicker; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.jfreechart.chart.properties.RangeComposite; +import org.simantics.jfreechart.chart.properties.StringChooser; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; +import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Composite containing the properties of a series + * @author Teemu Lempinen + * + */ +public class PieSeriesPropertyComposite2 extends Composite { + + private TrackedText label, time; + private StringChooser variable; + + public PieSeriesPropertyComposite2(Composite parent, ISessionContext context, WidgetSupport support, Collection variables,int options, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this); + + // Variable for the series + Label label = new Label(this, SWT.NONE); + label.setText("Variable:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + + variable = new StringChooser(this, support, SWT.BORDER); + variable.setData(variables); + variable.setObjectFactory(new ChartVariableFactory(variables)); + variable.addModifyListener(new ChartVariableModifier(variable.getWidget(), support)); + + variable.setColorProvider(new JFreeChartPropertyColorProvider(this.variable.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.variable.getWidget()); + + // Range + label = new Label(this, SWT.NONE); + label.setText("Range:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + RangeComposite rangeComposite = new RangeComposite(this, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeComposite); + + + // Label to be displayed in chart for this series + label = new Label(this, SWT.NONE); + label.setText("Label:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + this.label = new TrackedText(this, support, SWT.BORDER); + this.label.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + this.label.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + this.label.setColorProvider(new JFreeChartPropertyColorProvider(this.label.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(this.label.getWidget()); + + // Color + label = new Label(this, SWT.NONE); + label.setText("Color:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + Composite colorPicker = new ColorPicker(this, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(colorPicker); + + if ((options & ChartPropertyOptions.SHOW_TIME) > 0) { + // Time + label = new Label(this, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Time:"); + + Composite composite = new Composite(this, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(composite); + GridLayoutFactory.fillDefaults().applyTo(composite); + + time = new org.simantics.browsing.ui.swt.widgets.TrackedText(composite, support, SWT.BORDER); + time.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Series_time)); + time.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Series_time)); + time.setInputValidator(new DoubleValidator(true)); + time.setColorProvider(new JFreeChartPropertyColorProvider(time.getResourceManager())); + GridDataFactory.fillDefaults().applyTo(time.getWidget()); + } + // Exploded + label = new Label(this, SWT.NONE); + label.setText(""); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + Button exploded = new Button(this, support, SWT.CHECK); + exploded.setText("Exploded"); + exploded.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Series_exploded)); + exploded.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Series_exploded)); + GridDataFactory.fillDefaults().applyTo(exploded.getWidget()); + } + + @Override + public void dispose() { + variable.dispose(); + variable = null; + super.dispose(); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesTab.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesTab.java new file mode 100644 index 00000000..4e4b7e80 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesTab.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.pie; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.jfreechart.chart.properties.xyline.AxisAndVariablesExplorerComposite; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Tab for modifying series in a pie chart configuration + * @author Teemu Lempinen + * + */ +public class PieSeriesTab extends LabelPropertyTabContributor implements Widget { + + private GraphExplorerComposite explorer; + private ScrolledComposite propertyContainer; + private WidgetSupportImpl additionalSupport; + private Button add, remove; + private Resource chartResource; + private int options; + + public PieSeriesTab(int options) { + additionalSupport = new WidgetSupportImpl(); + this.options = options; + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, final ISessionContext context, WidgetSupport support) { + support.register(this); + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // (Ontology-based) GraphExplorer displaying variables of a pie chart + explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE); + explorer.setBrowseContexts(JFreeChartResource.URIs.PieSeriesBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning + explorer.finish(); + + ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateSelection(context); + } + }); + GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer); + + // Scrolled composite for displaying properties of a selection in explorer + propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(propertyContainer); + GridLayoutFactory.fillDefaults().applyTo(propertyContainer); + propertyContainer.setExpandHorizontal(true); + propertyContainer.setExpandVertical(true); + + + // Buttons for adding and removing variables from a pie plot + Composite buttonComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(buttonComposite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite); + + add = new Button(buttonComposite, additionalSupport, SWT.NONE); + add.setText("Add"); + add.addSelectionListener(new NewVariableListener(context)); + + remove = new Button(buttonComposite, additionalSupport, SWT.NONE); + remove.setText("Remove"); + remove.addSelectionListener(new RemoveListener(context)); + } + + /** + * Updates the content of propertyContainer + * @param context + */ + private void updateSelection(ISessionContext context) { + ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); + IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class); + if(resource == null) + return; + + for(Control child : propertyContainer.getChildren()) { + child.dispose(); + } + + PieSeriesPropertyComposite spc = new PieSeriesPropertyComposite(propertyContainer, context, additionalSupport, options,SWT.NONE); + propertyContainer.setContent(spc); + Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + + additionalSupport.fireInput(context, selection); + } + + + /** + * SelectionListener for adding a new variable to a plot + * @author Teemu Lempinen + * + */ + private class NewVariableListener extends SelectionListenerImpl { + + public NewVariableListener(ISessionContext context) { + super(context); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource dataset = null; + if(input == null) { + if(chartResource != null) { + Resource plot = graph.syncRequest(new PossibleObjectWithType(chartResource, l0.ConsistsOf, jfree.Plot)); + if(plot != null) + dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + } + } else { + if(graph.isInstanceOf(input, jfree.Series)) { + dataset = graph.getPossibleObject(input, l0.PartOf); + } + } + if(dataset != null) { + // Create series with no rvi + Resource series = ChartUtils.createSeries(graph, dataset, null); + graph.claimLiteral(series, jfree.Series_exploded, false); + } + } + } + + /** + * SelectionListener for remove button + * @author Teemu Lempinen + * + */ + private class RemoveListener extends SelectionListenerImpl { + + public RemoveListener(ISessionContext context) { + super(context); + } + + /** + * Removes selected resource from explorer + */ + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(input == null) + return; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource list = null; + if(graph.isInstanceOf(input, jfree.Series)) { + // Remove series from dataset and seriesList + Resource dataset = graph.getPossibleObject(input, l0.PartOf); + if(dataset != null) + list = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + + if(list != null) + ListUtils.removeElement(graph, list, input); + RemoverUtil.remove(graph, input); + } + } + } + + @Override + public void setInput(ISessionContext context, Object input) { + chartResource = AdaptionUtils.adaptToSingle(input, Resource.class); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesTab2.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesTab2.java new file mode 100644 index 00000000..7103b6f8 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/pie/PieSeriesTab2.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.pie; + +import java.util.Collection; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.jfreechart.chart.properties.AllVariablesOfModel; +import org.simantics.jfreechart.chart.properties.ChartVariable; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.jfreechart.chart.properties.xyline.AxisAndVariablesExplorerComposite; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.ui.ExceptionUtils; + +/** + * Tab for modifying series in a pie chart configuration + * @author Teemu Lempinen + * + */ +public class PieSeriesTab2 extends LabelPropertyTabContributor implements Widget { + + private GraphExplorerComposite explorer; + private ScrolledComposite propertyContainer; + private WidgetSupportImpl additionalSupport; + private Button add, remove; + private Resource chartResource; + private int options; + + public PieSeriesTab2(int options) { + additionalSupport = new WidgetSupportImpl(); + this.options = options; + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, final ISessionContext context, WidgetSupport support) { + support.register(this); + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // (Ontology-based) GraphExplorer displaying variables of a pie chart + explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE); + explorer.setBrowseContexts(JFreeChartResource.URIs.PieSeriesBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning + explorer.finish(); + + ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateSelection(context); + } + }); + GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer); + + // Scrolled composite for displaying properties of a selection in explorer + propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(propertyContainer); + GridLayoutFactory.fillDefaults().applyTo(propertyContainer); + propertyContainer.setExpandHorizontal(true); + propertyContainer.setExpandVertical(true); + + + // Buttons for adding and removing variables from a pie plot + Composite buttonComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(buttonComposite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite); + + add = new Button(buttonComposite, additionalSupport, SWT.NONE); + add.setText("Add"); + add.addSelectionListener(new NewVariableListener(context)); + + remove = new Button(buttonComposite, additionalSupport, SWT.NONE); + remove.setText("Remove"); + remove.addSelectionListener(new RemoveListener(context)); + } + + /** + * Updates the content of propertyContainer + * @param context + */ + private void updateSelection(ISessionContext context) { + ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); + IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class); + if(resource == null) + return; + + for(Control child : propertyContainer.getChildren()) { + child.dispose(); + } + + try { + AllVariablesOfModel query = AllVariablesOfModel.withRandomResource(context, resource); + Collection variables = context.getSession().syncRequest(query); + PieSeriesPropertyComposite2 spc = new PieSeriesPropertyComposite2(propertyContainer, context, additionalSupport, variables, options, SWT.NONE); + propertyContainer.setContent(spc); + Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + + additionalSupport.fireInput(context, selection); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + } + + + /** + * SelectionListener for adding a new variable to a plot + * @author Teemu Lempinen + * + */ + private class NewVariableListener extends SelectionListenerImpl { + + public NewVariableListener(ISessionContext context) { + super(context); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource dataset = null; + if(input == null) { + if(chartResource != null) { + Resource plot = graph.syncRequest(new PossibleObjectWithType(chartResource, l0.ConsistsOf, jfree.Plot)); + if(plot != null) + dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + } + } else { + if(graph.isInstanceOf(input, jfree.Series)) { + dataset = graph.getPossibleObject(input, l0.PartOf); + } + } + if(dataset != null) { + // Create series with no rvi + Resource series = ChartUtils.createSeries(graph, dataset, null); + graph.claimLiteral(series, jfree.Series_exploded, false); + } + } + } + + /** + * SelectionListener for remove button + * @author Teemu Lempinen + * + */ + private class RemoveListener extends SelectionListenerImpl { + + public RemoveListener(ISessionContext context) { + super(context); + } + + /** + * Removes selected resource from explorer + */ + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(input == null) + return; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource list = null; + if(graph.isInstanceOf(input, jfree.Series)) { + // Remove series from dataset and seriesList + Resource dataset = graph.getPossibleObject(input, l0.PartOf); + if(dataset != null) + list = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + + if(list != null) + ListUtils.removeElement(graph, list, input); + RemoverUtil.remove(graph, input); + } + } + } + + @Override + public void setInput(ISessionContext context, Object input) { + chartResource = AdaptionUtils.adaptToSingle(input, Resource.class); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/AxisAndVariablesExplorerComposite.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/AxisAndVariablesExplorerComposite.java new file mode 100644 index 00000000..04b02097 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/AxisAndVariablesExplorerComposite.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.xyline; + +import java.util.ArrayList; +import java.util.Map; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.common.ErrorLogger; +import org.simantics.browsing.ui.model.InvalidContribution; +import org.simantics.browsing.ui.model.dnd.DndBrowseContext; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.Procedure; +import org.simantics.db.request.Read; +import org.simantics.ui.SimanticsUI; + +/** + * ExplorerComposite allowing ontology-based DnD definitions. DnD Copied from {@link ModelBrowser2} + * + * @author Teemu Lempinen + * + */ +public class AxisAndVariablesExplorerComposite extends GraphExplorerComposite { + + volatile DndBrowseContext dndBrowseContext; + + public AxisAndVariablesExplorerComposite(Map args, IWorkbenchSite site, Composite parent, + WidgetSupport support, int style) { + super(args, site, parent, support, style); + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + ArrayList browseContexts = new ArrayList(); + for (String uri : getBrowseContexts()) { + Resource browseContext = graph.getPossibleResource(uri); + if (browseContext != null) + browseContexts.add(browseContext); + } + try { + dndBrowseContext = DndBrowseContext.create(graph, browseContexts); + } catch (InvalidContribution e) { + ErrorLogger.defaultLogError(e); + } + } + }); + } + + @Override + protected void handleDrop(final Object data, final NodeContext target) { + if (target == null) + return; + + SimanticsUI.getSession().asyncRequest(new Read() { + @Override + public Runnable perform(ReadGraph graph) throws DatabaseException { + if (dndBrowseContext == null) + return null; + return dndBrowseContext.getAction(graph, target, data); + } + }, new Procedure() { + @Override + public void execute(Runnable result) { + if (result != null) + result.run(); + } + + @Override + public void exception(Throwable t) { + ErrorLogger.defaultLogError(t); + } + }); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/AxisPropertyComposite.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/AxisPropertyComposite.java new file mode 100644 index 00000000..14bdb4d4 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/AxisPropertyComposite.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.xyline; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.properties.AxisHidePropertyComposite; +import org.simantics.jfreechart.chart.properties.ColorPicker; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; +import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; +import org.simantics.sysdyn.JFreeChartResource; + +/** + * Composite for displaying axis properties in {@link XYLineAxisAndVariablesTab} + * + * @author Teemu Lempinen + * + */ +public class AxisPropertyComposite extends Composite { + + TrackedText name, units, min, max; + Button tlabels, tmarks; + + public AxisPropertyComposite(Composite parent, ISessionContext context, WidgetSupport support, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this); + + // Label (units) + Label label = new Label(this, SWT.NONE); + label.setText("Label: "); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + units = new TrackedText(this, support, SWT.BORDER); + units.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); // FIXME: Units + units.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); // FIXME: Units + units.setColorProvider(new JFreeChartPropertyColorProvider(units.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(units.getWidget()); + + + // Minimum and maximum values + label = new Label(this, SWT.NONE); + label.setText("Min:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + Composite minmax = new Composite(this, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(minmax); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(minmax); + min = new TrackedText(minmax, support, SWT.BORDER); + min.setColorProvider(new JFreeChartPropertyColorProvider(min.getResourceManager())); + min.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Axis_min)); + min.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Axis_min)); + min.setInputValidator(new DoubleValidator(true)); + + label = new Label(minmax, SWT.NONE); + label.setText("Max:"); + max = new TrackedText(minmax, support, SWT.BORDER); + max.setColorProvider(new JFreeChartPropertyColorProvider(max.getResourceManager())); + max.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Axis_max)); + max.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Axis_max)); + max.setInputValidator(new DoubleValidator(true)); + + + // Color + label = new Label(this, SWT.NONE); + label.setText("Color:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + Composite colorPicker = new ColorPicker(this, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(colorPicker); + + // Tick and label visibility + Composite c = new Composite(this, SWT.NONE); + GridDataFactory.fillDefaults().span(2, 1).applyTo(c); + GridLayoutFactory.fillDefaults().applyTo(c); + Composite axisHide = new AxisHidePropertyComposite(c, context, support, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(axisHide); + } + +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/SeriesPropertyComposite.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/SeriesPropertyComposite.java new file mode 100644 index 00000000..9557db78 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/SeriesPropertyComposite.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.xyline; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Spinner; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.properties.ColorPicker; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.jfreechart.chart.properties.RVIFactory; +import org.simantics.jfreechart.chart.properties.RVIModifier; +import org.simantics.jfreechart.chart.properties.RangeComposite; +import org.simantics.jfreechart.chart.properties.TrackedSpinner; +import org.simantics.jfreechart.chart.properties.VariableExistsValidator; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Composite for displaying series properties in {@link XYLineAxisAndVariablesTab} + * + * @author Teemu Lempinen + * + */ +public class SeriesPropertyComposite extends Composite { + + + public SeriesPropertyComposite(Composite parent, ISessionContext context, WidgetSupport support, int style) { + super(parent, style); + createContent(context, support); + } + + protected void createContent(ISessionContext context, WidgetSupport support) { + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this); + + // Variable for the series + variable(this, context, support); + + // Range + range(this, context, support); + + // Label to be displayed in chart for this series + seriesLabel(this, context, support); + + // Color + color(this, context, support); + + // Line width + lineWidth(this, support); + + } + + protected TrackedText variable(Composite container, ISessionContext context, WidgetSupport support) { + Label label = new Label(container, SWT.NONE); + label.setText("Variable:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + TrackedText variable = new TrackedText(container, support, SWT.BORDER); + variable.setTextFactory(new RVIFactory()); + variable.addModifyListener(new RVIModifier(variable.getWidget(), support)); + variable.setColorProvider(new JFreeChartPropertyColorProvider(variable.getResourceManager())); + variable.setInputValidator(new VariableExistsValidator(support, variable)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(variable.getWidget()); + return variable; + } + + protected RangeComposite range(Composite container, ISessionContext context, WidgetSupport support) { + Label label = new Label(container, SWT.NONE); + label.setText("Range:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + RangeComposite rangeComposite = new RangeComposite(container, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeComposite); + return rangeComposite; + } + + protected TrackedText seriesLabel(Composite container, ISessionContext context, WidgetSupport support) { + Label label = new Label(container, SWT.NONE); + label.setText("Label:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + TrackedText labelText = new TrackedText(container, support, SWT.BORDER); + labelText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + labelText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + labelText.setColorProvider(new JFreeChartPropertyColorProvider(labelText.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(labelText.getWidget()); + return labelText; + } + + protected ColorPicker color(Composite container, ISessionContext context, WidgetSupport support) { + Label label = new Label(container, SWT.NONE); + label.setText("Color:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + ColorPicker colorPicker = new ColorPicker(container, context, support, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(colorPicker); + return colorPicker; + } + + protected TrackedSpinner lineWidth(Composite container, WidgetSupport support) { + Label label = new Label(container, SWT.NONE); + label.setText("Line width:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + + TrackedSpinner width = new TrackedSpinner(container, support, SWT.BORDER); + width.setSelectionFactory(new WidthSelectionFactory()); + width.addModifyListener(new WidthModifyListener()); + width.setMinimum(1); + width.setMaximum(10); + return width; + } + + + /** + * ModifyListener for the width {@link TrackedSpinner} + * + * @author Teemu Lempinen + * + */ + private class WidthModifyListener implements TextModifyListener, Widget { + + private ISessionContext context; + private Object lastInput = null; + + @Override + public void modifyText(TrackedModifyEvent e) { + if(context == null) + return; + + // Get the text value from spinner and associated resource (input) + Spinner spinner = (Spinner)e.getWidget(); + final String textValue = spinner.getText(); + final Object input = lastInput; + + try { + context.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + // Apply with (textValue) to the series (input) + Resource series = AdaptionUtils.adaptToSingle(input, Resource.class); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + try { + // usually reliable, since the spinner does all the checks + Integer value = Integer.parseInt(textValue); + graph.claimLiteral(series, jfree.Series_lineWidth, value, Bindings.INTEGER); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + } + + @Override + public void setInput(ISessionContext context, Object parameter) { + this.context = context; + lastInput = parameter; + } + + } + + /** + * Class for setting the value for width {@link TrackedSpinner} + * @author Teemu Lempinen + * + */ + private class WidthSelectionFactory extends ReadFactoryImpl { + + @Override + public Integer perform(ReadGraph graph, Resource axis) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Integer width = graph.getPossibleRelatedValue(axis, jfree.Series_lineWidth); + if(width == null) + // Default width == 1 + width = 1; + return width; + } + + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/XYLineAxisAndVariablesTab.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/XYLineAxisAndVariablesTab.java new file mode 100644 index 00000000..4081ce04 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/XYLineAxisAndVariablesTab.java @@ -0,0 +1,300 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.xyline; + +import java.util.List; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * PropertyTab displaying properties of axis and variables of a chart + * + * @author Teemu Lempinen + * + */ +public class XYLineAxisAndVariablesTab extends LabelPropertyTabContributor { + + private GraphExplorerComposite explorer; + private ScrolledComposite propertyContainer; + private Button addAxis, addVariable, remove; + private WidgetSupportImpl additionalSupport; + + public XYLineAxisAndVariablesTab() { + additionalSupport = new WidgetSupportImpl(); + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, final ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // (Ontology-based) GraphExplorer displaying range axis and variables mapped to those axis + explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE); + explorer.setBrowseContexts(JFreeChartResource.URIs.ChartAxisAndVariablesBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning + explorer.finish(); + + ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateSelection(context); + } + }); + GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer); + + // Scrolled composite for displaying properties of a selection in explorer + propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(propertyContainer); + GridLayoutFactory.fillDefaults().applyTo(propertyContainer); + propertyContainer.setExpandHorizontal(true); + propertyContainer.setExpandVertical(true); + + // Buttons for adding axis and variables and removing selected items from explorer + Composite buttonComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(buttonComposite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite); + + addAxis = new Button(buttonComposite, support, SWT.NONE); + addAxis.setText("Add axis"); + addAxis.addSelectionListener(new NewAxisListener(context)); + + addVariable = new Button(buttonComposite, additionalSupport, SWT.NONE); + addVariable.setText("Add variable"); + addVariable.addSelectionListener(new NewVariableListener(context)); + + remove = new Button(buttonComposite, additionalSupport, SWT.NONE); + remove.setText("Remove"); + remove.addSelectionListener(new RemoveListener(context)); + } + + /** + * Updates the content of propertyContainer + * @param context + */ + private void updateSelection(ISessionContext context) { + ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); + IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class); + if(resource == null) + return; + + // Get the type of the selected node (axis or series) + String typeUri = null; + try { + typeUri = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + if(graph.isInstanceOf(resource, jfree.Axis)) + return graph.getURI(jfree.Axis); + else if (graph.isInstanceOf(resource, jfree.Series)) + return graph.getURI(jfree.Series); + return null; + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // Create a PropertyComposite for the selected node + if(typeUri != null) { + + for(Control child : propertyContainer.getChildren()) { + child.dispose(); + } + + if(typeUri.equals(JFreeChartResource.URIs.Axis)) { + AxisPropertyComposite apc = new AxisPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE); + propertyContainer.setContent(apc); + Point size = apc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } else if(typeUri.equals(JFreeChartResource.URIs.Series)) { + SeriesPropertyComposite spc = new SeriesPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE); + propertyContainer.setContent(spc); + Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } + } + + additionalSupport.fireInput(context, selection); + } + + /** + * SelectionListener for adding a new range axis to a plot + * @author Teemu Lempinen + * + */ + private class NewAxisListener extends SelectionListenerImpl { + + public NewAxisListener(ISessionContext context) { + super(context); + } + + @Override + public void apply(WriteGraph graph, Resource chart) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.Plot)); + if(plot != null) { + Resource rangeAxis = ChartUtils.createNumberRangeAxis(graph, plot); + if(rangeAxis != null) { + Resource domainAxis = graph.getPossibleObject(plot, jfree.Plot_domainAxis); + ChartUtils.createXYDataset(graph, plot, domainAxis, rangeAxis); + } + } + } + } + + + /** + * SelectionListener for adding a new variable to a plot + * @author Teemu Lempinen + * + */ + private class NewVariableListener extends SelectionListenerImpl { + + public NewVariableListener(ISessionContext context) { + super(context); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + NodeContext nc = explorer.getExplorer().getRoot(); + if(nc == null) + return; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + if(input == null) { + Resource chart = AdaptionUtils.adaptToSingle(nc, Resource.class); + if(chart == null) return; + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.Plot)); + if(plot == null) return; + Resource rangelist = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList); + if(rangelist == null) return; + List list = ListUtils.toList(graph, rangelist); + if(list == null || list.isEmpty()) return; + input = list.get(0); + } + + Resource dataset; + if(graph.isInstanceOf(input, jfree.Series)) { + // Selected resource is series. Add to same dataset + dataset = graph.getPossibleObject(input, l0.PartOf); + } else { + // Selected resource is axis. Find the dataset it is mapped to or create dataset if not created already + dataset = graph.getPossibleObject(input, jfree.Dataset_mapToRangeAxis_Inverse); + if(dataset == null) { + Resource plot = graph.getPossibleObject(input, l0.PartOf); + if(plot == null) return; + Resource domainAxis = graph.getPossibleObject(plot, jfree.Plot_domainAxis); + if(domainAxis == null) return; + ChartUtils.createXYDataset(graph, plot, domainAxis, input); + } + } + + if(dataset != null) { + // Create series with no rvi + ChartUtils.createSeries(graph, dataset, null); + } + } + } + + + /** + * SelectionListener for remove button + * @author Teemu Lempinen + * + */ + private class RemoveListener extends SelectionListenerImpl { + + public RemoveListener(ISessionContext context) { + super(context); + } + + /** + * Removes selected resource from explorer + */ + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(input == null) + return; + + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource list = null; + if(graph.isInstanceOf(input, jfree.Series)) { + // Remove series from dataset and seriesList + Resource dataset = graph.getPossibleObject(input, l0.PartOf); + if(dataset != null) + list = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + } else { + // Remove associated dataset + Resource dataset = graph.getPossibleObject(input, jfree.Dataset_mapToRangeAxis_Inverse); + if(dataset != null) { + graph.deny(dataset, jfree.Dataset_mapToDomainAxis); + graph.deny(dataset, jfree.Dataset_mapToRangeAxis); + RemoverUtil.remove(graph, dataset); + } + + // Remove axis from plot and rangeAxisList + Resource plot = graph.getPossibleObject(input, l0.PartOf); + if(plot != null) + list = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList); + } + if(list != null) + ListUtils.removeElement(graph, list, input); + RemoverUtil.remove(graph, input); + } + } +} diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/XYLineGeneralPropertiesTab.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/XYLineGeneralPropertiesTab.java new file mode 100644 index 00000000..51bd7136 --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/chart/properties/xyline/XYLineGeneralPropertiesTab.java @@ -0,0 +1,318 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.jfreechart.chart.properties.xyline; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.properties.AxisHidePropertyComposite; +import org.simantics.jfreechart.chart.properties.BooleanPropertyFactory; +import org.simantics.jfreechart.chart.properties.BooleanSelectionListener; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.jfreechart.chart.properties.JFreeChartPropertyColorProvider; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.jfreechart.chart.properties.RVIFactory; +import org.simantics.jfreechart.chart.properties.RVIModifier; +import org.simantics.jfreechart.chart.properties.TitleFactory; +import org.simantics.jfreechart.chart.properties.TitleModifier; +import org.simantics.jfreechart.chart.properties.VariableExistsValidator; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ui.chart.property.DoublePropertyFactory; +import org.simantics.modeling.ui.chart.property.DoublePropertyModifier; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * PropertyTab displaying general properties and x-axis properties of a chart + * + * @author Teemu Lempinen + * + */ +public class XYLineGeneralPropertiesTab extends LabelPropertyTabContributor implements Widget { + + private ScrolledComposite sc; + private Composite composite; + private TrackedText name, title, xlabel, xvariable, xmin, xmax; + private TrackedCombo type; + private Button hgrid, htitle, hlegend; + private WidgetSupportImpl domainAxisSupport = new WidgetSupportImpl(); + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + support.register(this); + + // Scrolled composite containing all of the properties in this tab + sc = new ScrolledComposite(body, SWT.NONE | SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().applyTo(sc); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + composite = new Composite(sc, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // General properties + Group general = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(general); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(general); + general.setText("General"); + + // Name + Label nameLabel = new Label(general, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(nameLabel); + nameLabel.setText("Name:"); + nameLabel.setAlignment(SWT.RIGHT); + + Composite c = new Composite(general, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(c); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(c); + + name = new org.simantics.browsing.ui.swt.widgets.TrackedText(c, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget()); + name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + name.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + // Type + Label label = new Label(c, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Type:"); + + type = new TrackedCombo(c, support, SWT.BORDER | SWT.READ_ONLY); + type.addModifyListener(new TypeModifyListener()); + type.setItemFactory(new TypeItemFactory()); + type.setSelectionFactory(new TypeSelectionFactory()); + GridDataFactory.fillDefaults().applyTo(type.getWidget()); + + // Title (Which is different than name) + label = new Label(general, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Title:"); + + title = new org.simantics.browsing.ui.swt.widgets.TrackedText(general, support, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(title.getWidget()); + title.setTextFactory(new TitleFactory()); + title.addModifyListener(new TitleModifier()); + title.setColorProvider(new JFreeChartPropertyColorProvider(name.getResourceManager())); + + // Group for hide options + Group hideGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(hideGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(hideGroup); + hideGroup.setText("Hide"); + + hgrid = new Button(hideGroup, support, SWT.CHECK); + hgrid.setText("Grid"); + hgrid.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleGrid, true)); + hgrid.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.Plot, JFreeChartResource.URIs.Plot_visibleGrid)); + htitle = new Button(hideGroup, support, SWT.CHECK); + htitle.setText("Title"); + htitle.setSelectionFactory(new BooleanPropertyFactory(JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible, true)); + htitle.addSelectionListener(new BooleanSelectionListener(context, JFreeChartResource.URIs.TextTitle, JFreeChartResource.URIs.visible)); + hlegend = new Button(hideGroup, support, SWT.CHECK); + hlegend.setText("Legend"); + hlegend.setSelectionFactory(new BooleanPropertyFactory(null, JFreeChartResource.URIs.Chart_visibleLegend, true)); + hlegend.addSelectionListener(new BooleanSelectionListener(context, null, JFreeChartResource.URIs.Chart_visibleLegend)); + + + // X-Axis properties + Group xgroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(xgroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(3).applyTo(xgroup); + xgroup.setText("X-axis"); + + // Variable for x-axis (default: empty == time) + Label xVariableLabel = new Label(xgroup, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(xVariableLabel); + xVariableLabel.setText("Variable:"); + + xvariable = new TrackedText(xgroup, domainAxisSupport, SWT.BORDER); + xvariable.setTextFactory(new RVIFactory()); + xvariable.addModifyListener(new RVIModifier(xvariable.getWidget(), domainAxisSupport)); + xvariable.setColorProvider(new JFreeChartPropertyColorProvider(xvariable.getResourceManager())); + xvariable.setInputValidator(new VariableExistsValidator(support, xvariable, true)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(xvariable.getWidget()); + + Composite axisHide = new AxisHidePropertyComposite(xgroup, context, domainAxisSupport, SWT.NONE); + GridDataFactory.fillDefaults().span(1, 3).applyTo(axisHide); + + // Label for x-axis + label = new Label(xgroup, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Label:"); + + xlabel = new TrackedText(xgroup, domainAxisSupport, SWT.BORDER); + xlabel.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel, "")); + xlabel.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + xlabel.setColorProvider(new JFreeChartPropertyColorProvider(xlabel.getResourceManager())); + GridDataFactory.fillDefaults().grab(true, false).applyTo(xlabel.getWidget()); + + // Min and max values for x-axis + label = new Label(xgroup, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + label.setText("Min:"); + + Composite minmax = new Composite(xgroup, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(minmax); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(minmax); + xmin = new TrackedText(minmax, domainAxisSupport, SWT.BORDER); + xmin.setColorProvider(new JFreeChartPropertyColorProvider(xmin.getResourceManager())); + xmin.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Axis_min)); + xmin.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Axis_min)); + xmin.setInputValidator(new DoubleValidator(true)); + + label = new Label(minmax, SWT.NONE); + label.setText("Max:"); + xmax = new TrackedText(minmax, domainAxisSupport, SWT.BORDER); + xmax.setColorProvider(new JFreeChartPropertyColorProvider(xmax.getResourceManager())); + xmax.setTextFactory(new DoublePropertyFactory(JFreeChartResource.URIs.Axis_max)); + xmax.addModifyListener(new DoublePropertyModifier(context, JFreeChartResource.URIs.Axis_max)); + xmax.setInputValidator(new DoubleValidator(true)); + + // Set the same width to both label rows + composite.layout(); + GridDataFactory.fillDefaults().hint(xVariableLabel.getBounds().width, SWT.DEFAULT).align(SWT.END, SWT.CENTER).applyTo(nameLabel); + + sc.setContent(composite); + Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT); + sc.setMinSize(size); + } + + @Override + public void setInput(final ISessionContext context, Object input) { + final Resource chart = AdaptionUtils.adaptToSingle(input, Resource.class); + if(chart == null) + return; + + context.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.Plot)); + if(plot == null) return; + Resource domainAxis = graph.getPossibleObject(plot, jfree.Plot_domainAxis); + if(domainAxis == null) return; + domainAxisSupport.fireInput(context, new StructuredSelection(domainAxis)); + } + }); + } + + /** + * + * @author Teemu Lempinen + * + */ + private class TypeSelectionFactory extends ReadFactoryImpl { + @Override + public String perform(ReadGraph graph, Resource chart) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.XYPlot)); + if(plot != null) { + Collection datasets = graph.syncRequest(new ObjectsWithType(plot, l0.ConsistsOf, jfree.XYDataset)); + if(!datasets.isEmpty()) { + Resource dataset = datasets.iterator().next(); + if(dataset != null) { + Resource renderer = graph.syncRequest(new PossibleObjectWithType(dataset, jfree.Dataset_renderer, jfree.Renderer)); + if(renderer != null && graph.isInstanceOf(renderer, jfree.XYAreaRenderer)) + return "Area"; + } + } + } + return "Line"; + } + } + + /** + * RangeItemFactory finds all inexes of a given enumeration + * and adds "Sum" and "All" to the returned indexes + * @author Teemu Lempinen + * + */ + private class TypeItemFactory extends ReadFactoryImpl> { + @Override + public Map perform(ReadGraph graph, Resource series) throws DatabaseException { + LinkedHashMap result = new LinkedHashMap(); + result.put("Line", "Line"); + result.put("Area", "Area"); +// result.put("Stacked Area", "Stacked Area"); + return result; + } + } + + /** + * TypeModifyListener for modifying the type of a bar chart + * @author Teemu Lempinen + * + */ + private class TypeModifyListener extends ComboModifyListenerImpl { + @Override + public void applyText(WriteGraph graph, Resource chart, String text) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.XYPlot)); + if(plot == null) + return; + + Collection datasets = graph.syncRequest(new ObjectsWithType(plot, l0.ConsistsOf, jfree.XYDataset)); + if(datasets == null || datasets.isEmpty()) + return; + + for(Resource dataset : datasets) { + graph.deny(dataset, jfree.Dataset_renderer); + + Resource renderer; + if(text.equals("Area")) + renderer = GraphUtils.create2(graph, jfree.XYAreaRenderer); + else + renderer = GraphUtils.create2(graph, jfree.XYLineRenderer); + + graph.claim(dataset, jfree.Dataset_renderer, renderer); + } + } + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/internal/Activator.java b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/internal/Activator.java new file mode 100644 index 00000000..97597b7e --- /dev/null +++ b/dev-jkauttio/org.simantics.jfreechart/src/org/simantics/jfreechart/internal/Activator.java @@ -0,0 +1,50 @@ +package org.simantics.jfreechart.internal; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.simantics.jfreechart"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/dev-jkauttio/org.simantics.modelica/.classpath b/dev-jkauttio/org.simantics.modelica/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.modelica/.project b/dev-jkauttio/org.simantics.modelica/.project new file mode 100644 index 00000000..2d4d7aa0 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/.project @@ -0,0 +1,28 @@ + + + org.simantics.modelica + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.modelica/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.modelica/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..f25d3a62 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Tue Jan 26 16:43:56 EET 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.modelica/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.modelica/META-INF/MANIFEST.MF new file mode 100644 index 00000000..48ba713d --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Modelica +Bundle-SymbolicName: org.simantics.modelica;singleton:=true +Bundle-Version: 1.1.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Require-Bundle: gnu.trove2;bundle-version="2.0.4", + org.eclipse.osgi;bundle-version="3.6.0", + org.eclipse.core.runtime;bundle-version="3.6.0", + org.simantics.utils;bundle-version="1.1.0", + org.simantics.utils.datastructures;bundle-version="1.1.0" +Export-Package: org.simantics.modelica, + org.simantics.modelica.data, + org.simantics.modelica.preferences, + org.simantics.modelica.reader +Bundle-Activator: org.simantics.modelica.Activator +Bundle-ActivationPolicy: lazy +Bundle-Vendor: VTT Technical Research Centre of Finland diff --git a/dev-jkauttio/org.simantics.modelica/build.properties b/dev-jkauttio/org.simantics.modelica/build.properties new file mode 100644 index 00000000..11ab1db4 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/build.properties @@ -0,0 +1,16 @@ +############################################################################### +# Copyright (c) 2010 Association for Decentralized Information Management in +# Industry THTH ry. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# VTT Technical Research Centre of Finland - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/dev-jkauttio/org.simantics.modelica/plugin.xml b/dev-jkauttio/org.simantics.modelica/plugin.xml new file mode 100644 index 00000000..1e192295 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/Activator.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/Activator.java new file mode 100644 index 00000000..bcbb8d58 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/Activator.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + public static final String PLUGIN_ID = "org.simantics.modelica"; + + static BundleContext context; + + @Override + public void start(BundleContext context) throws Exception { + Activator.context = context; + } + + @Override + public void stop(BundleContext context) throws Exception { + Activator.context = null; + } + + public static BundleContext getContext() { + return context; + } + +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/IModelicaMonitor.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/IModelicaMonitor.java new file mode 100644 index 00000000..56e6cccf --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/IModelicaMonitor.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica; + +public interface IModelicaMonitor { + public void message(String message); + public void clearConsole(); + public void showConsole(); +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/InitWriter.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/InitWriter.java new file mode 100644 index 00000000..e7dee74d --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/InitWriter.java @@ -0,0 +1,180 @@ +package org.simantics.modelica; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.HashMap; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Class to change values of parameters in modelica init.xml files + * + * @author tlteemu + */ +public class InitWriter { + + /** + * Change the given init parameter values for XML init file + * @param file path to the init.xml file + * @param inits name-value map + * @return + */ + public static boolean writeXML(String file, HashMap inits) { + Document doc; + try { + doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(file)); + + // Locate the node(s) + XPath xpath = XPathFactory.newInstance().newXPath(); + + for(String name : inits.keySet()) { + NodeList nodes = null; + try { + // First try normal variables + nodes = (NodeList)xpath.evaluate + ("//fmiModelDescription/ModelVariables/ScalarVariable[@name='" + name + "']/Real/@start", + doc, + XPathConstants.NODESET); + if(nodes.getLength() == 0) { + // If normal variables were not found, try if it is an experiment attribute + nodes = (NodeList)xpath.evaluate + ("//fmiModelDescription/DefaultExperiment/@" + name, + doc, + XPathConstants.NODESET); + } + } catch (XPathExpressionException e) { + + } + if (nodes != null) { + // make the change. There should be only one node. + for (int idx = 0; idx < nodes.getLength(); idx++) { + Node n = nodes.item(idx); + n.setNodeValue(inits.get(name).replaceAll("\"", "")); + } + } + } + + // Save the result + Transformer xformer = TransformerFactory.newInstance().newTransformer(); + xformer.transform + (new DOMSource(doc), new StreamResult(new File(file))); + + return true; + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (TransformerConfigurationException e) { + e.printStackTrace(); + } catch (TransformerFactoryConfigurationError e) { + e.printStackTrace(); + } catch (TransformerException e) { + e.printStackTrace(); + } + + return false; + + } + + /** + * Change the given init parameter values for TXT init file + * @param file path to the init.xml file + * @param inits name-value map + * @return + */ + public static boolean writeTXT(String file, HashMap inits) { + HashMap initials = new HashMap(); + HashMap order = new HashMap(); + + InputStream is; + try { + is = new FileInputStream(file); + int orderNumber = 0; + while(true) { + String line = getLine(is); + if(line == null) + return false; + if(line.isEmpty()) + break; + if(line.contains("//")) { + String[] nn = line.split("//", 2); + String key = nn[1].trim(); + String value = nn[0].trim(); + if(inits.containsKey(key)) { + value = inits.get(key); + } + initials.put(key, value); + order.put(orderNumber, key); + } + orderNumber++; + } + is.close(); + + PrintStream s = new PrintStream(file); + for(int j = 0; j < orderNumber ; j++) { + String key = order.get(j); + if (key != null) { + s.println(initials.get(key) + " // " + key); + } else { + s.println("0.0"); + } + } + s.close(); + + return true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + private static String getLine(InputStream stream) { + if(stream == null) + return null; + StringBuilder b = new StringBuilder(); + try { + while(true) { + int c = stream.read(); + if(c == -1) { + stream = null; + return b.toString(); + } + else if(c == '\n') + return b.toString(); + else if(c == '\r') + ; + else + b.append((char)c); + } + } catch (IOException e) { + return null; + } + + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/ModelicaException.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/ModelicaException.java new file mode 100644 index 00000000..32c99c96 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/ModelicaException.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica; + +public class ModelicaException extends Exception { + + private static final long serialVersionUID = 2712433918044442927L; + + public ModelicaException(String message) { + super(message); + } + +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/ModelicaKeys.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/ModelicaKeys.java new file mode 100644 index 00000000..d867fe83 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/ModelicaKeys.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica; + +/** + * Keys used by modelica to control simulations + * + * @author Teemu Lempinen + */ +public class ModelicaKeys { + + public static String START_VALUE = "startTime"; + public static String STOP_VALUE = "stopTime"; + public static String OUTPUT_FORMAT = "outputFormat"; + public static String STEP_VALUE = "stepSize"; + public static String NUMBER_OF_INTERVALS = "numberOfIntervals"; + public static String METHOD = "method"; + public static String TOLERANCE = "tolerance"; + public static String VARIABLE_FILTER = "variableFilter"; + public static String OUTPUT_INTERVAL = "outputInterval"; + +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java new file mode 100644 index 00000000..da8f6ba4 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java @@ -0,0 +1,812 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.osgi.framework.Bundle; +import org.osgi.service.prefs.Preferences; +import org.simantics.modelica.preferences.OpenModelicaPreferences; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Manager for OpenModelica compiler + * + * @author Teemu Lempinen + * @author Janne Kauttio + */ +public class ModelicaManager { + + private static final String OM_BUILTIN = "OpenModelica1.9.0"; + + public enum OSType { + APPLE, LINUX, SUN, WINDOWS, UNKNOWN + } + + public static final String OMC_VERSION = "OMC_VERSION"; + public static final String RESULT_FILE_NAME = "RESULT_FILE_NAME"; + + /** + * Get operating system type + * + * @return OSType + */ + private static OSType getOSType() { + String osName = System.getProperty("os.name").toLowerCase(); + + if (osName.startsWith("mac os x")) + return OSType.APPLE; + else if (osName.startsWith("linux")) + return OSType.LINUX; + else if (osName.startsWith("sun")) + return OSType.SUN; + else if (osName.startsWith("windows")) + return OSType.WINDOWS; + + return OSType.UNKNOWN; + } + + private static boolean onWindows() { + return System.getProperty("os.name").toLowerCase().startsWith("windows"); + } + + private static File getOMCBinary(File home) { + return new File(home, "bin" + File.separator + "omc" + (onWindows() ? ".exe" : "")); + } + + private static Process runWithEnvironment(File homeDir, File workDir, File executable, String... parameters) { + // construct the command + List command = new ArrayList(); + command.add(executable.getAbsolutePath()); + // this should iterate through the parameters in order + for (String parameter : parameters) { + command.add(parameter); + } + + // create the process + ProcessBuilder builder = new ProcessBuilder(command); + builder.redirectErrorStream(true); + builder.directory(workDir); + + // set the environment + Map env = builder.environment(); + env.put("OPENMODELICAHOME", homeDir.getAbsolutePath()); + + // TODO: these are probably not needed as most of the files do not exist + File lib = new File(homeDir, "lib"); + File omlib = new File(lib, "omlibrary"); + env.put("OPENMODELICALIBRARY", omlib.getAbsolutePath()); + File bin = new File(homeDir, "bin"); + env.put("OMPATH", bin.getAbsolutePath()); + File mingw = new File(homeDir, "MinGW"); + env.put("MINGW", mingw.getAbsolutePath()); + + File mbin = new File(mingw, "bin"); + File mlib = new File(mingw, "lib"); + env.put("PATH", env.get("PATH") + File.pathSeparator + bin.getAbsolutePath() + + File.pathSeparator + mbin.getAbsolutePath() + + File.pathSeparator + mlib.getAbsolutePath()); + + env.put("MODELICAUSERCFLAGS", "-O0"); + + // run the process + Process process = null; + try { + process = builder.start(); + } + catch (Exception e) { + e.printStackTrace(); + } + + return process; + } + + private static Process runOMC(File homeDir, File workDir, String... parameters) { + return runWithEnvironment(homeDir, workDir, getOMCBinary(homeDir), parameters); + } + + public static String getOMVersion(File home) { + return getProcessOutput(runOMC(home, home, "++v")); + } + + public static String getDefaultOMVersion() { + return getOMVersion(getOMHome()); + } + + public static boolean isOldOMVersion() { + try { + double version = Double.parseDouble(getOMVersion(getOMHome()).substring(0, 3)); + return version < 1.9; + } + catch (NumberFormatException e) { + // if the version string could not be parsed, assume that the + // version sufficiently new + return false; + } + } + + /** + * Get Open Modelica home directory. + * + * @return Open Modelica home directory + */ + private static File getOMHome() { + Preferences node = ConfigurationScope.INSTANCE.getNode(Activator.PLUGIN_ID); + String omHomePath = node.get(OpenModelicaPreferences.OM_HOME, null); + if (omHomePath != null) { + File omHome = new File(omHomePath); + if (omHome.isDirectory()) + return omHome; + } + + return getDefaultOMHome(); + } + + public static File getDefaultOMHome() { + if (onWindows()) { + File builtin = getBuiltinOMHome(); + if (builtin != null) + return builtin; + } + + File installed = getInstalledOMHome(); + if (installed != null) + return installed; + + // TODO: what is the correct error to throw? + throw new Error("OpenModelica could not be found"); + } + + public static File getInstalledOMHome() { + String omHomePath = System.getenv("OPENMODELICAHOME"); + if (omHomePath != null) { + File omHome = new File(omHomePath); + if (omHome.isDirectory()) + return omHome; + } + return null; + } + + public static File getBuiltinOMHome() { + Bundle bundle = Platform.getBundle("org.simantics.openmodelica.win32"); + if (bundle != null) { + try { + File omHome = new File(FileLocator.getBundleFile(bundle), OM_BUILTIN); + if (omHome.isDirectory()) + return omHome; + } + catch (Exception e) { + e.printStackTrace(); + } + } + return null; + } + + /** + * Gets the whole process output in one string + * + * @param process Process + * @return process output + */ + public static String getProcessOutput(final Process process) { + try { + BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); + StringBuilder output = new StringBuilder(); + String line; + boolean first = true; + while ((line = input.readLine()) != null) { + if(!first) + output.append(System.getProperty("line.separator")); + first = false; + output.append(line); + } + input.close(); + return output.toString(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * Prints the output of an ongoing process to IModelicaMonitor. + * + * @param process Process + * @param monitor IModelicaMonitor + */ + // TODO: clean up + public static void printProcessOutput(final Process process, final IModelicaMonitor monitor) { + Thread thread = new Thread() { + @Override + public void run() { + InputStream stream = process.getInputStream(); + StringBuilder b = new StringBuilder(); + while(true) { + try { + int c; + + c = stream.read(); + + if(c <= 0) + break; + if(monitor != null) { + if((char)c != '\n') + b.append((char)c); + else { + System.out.println("OMC output: " + b.toString()); + String message = b.toString(); + message = message.trim(); + if(message.startsWith("\"")) + message = message.substring(1); + + monitor.message(message); + b.delete(0, b.length()); + } + } + } catch (IOException e) { + e.printStackTrace(); + break; + } + } + } + }; + + thread.run(); + } + + public static SimulationLocation createSimulationLocation(File modelDir, String modelName, String modelContent) { + if (!modelDir.isDirectory()) { + return null; + } + + // there might be a better way to remove whitespace from the string + // but this apparently works fine in this context + modelName = modelName.replace(" ", ""); + + SimulationLocation location = new SimulationLocation(modelDir, modelName); + + location.modelFile = location.getFileInLocation(".mo"); + location.modelScriptFile = location.getFileInLocation(".mos"); + + try { + FileWriter writer = new FileWriter(location.modelFile); + writer.write(modelContent); + writer.close(); + } + catch (IOException e) { + e.printStackTrace(); + return null; + } + + // full model files are (apparently) only needed for old parameter comparison routines + if (isOldOMVersion()) { + location.fullModelDir = new File(location.getModelDir(), "fullModel"); + if (!location.fullModelDir.isDirectory()) { + location.fullModelDir.mkdir(); + } + location.fullModelFile = new File(location.fullModelDir, location.getModelName() + "_full.mo"); + location.fullModelScriptFile = new File(location.fullModelDir, location.getModelName() + "_full.mos"); + } + + location.omHome = getOMHome(); + + return location; + } + + public static void createSimulationScripts(SimulationLocation location, HashMap parameters, String additionalScript) + throws FileNotFoundException { + writeScriptFile(location, parameters, additionalScript); + + location.executableFile = location.getFileInLocation(onWindows() ? ".exe" : ""); + location.initFile = location.getFileInLocation("_init.xml"); + location.resultFile = location.getFileInLocation("_res." + parameters.get(ModelicaKeys.OUTPUT_FORMAT)); + + if (isOldOMVersion()) { + writeFullModelScriptFile(location, additionalScript); + } + } + + public static void createFMUSimulationScripts(SimulationLocation location, HashMap parameters, String additionalScript) + throws FileNotFoundException { + writeFMUScriptFile(location, additionalScript); + + location.executableFile = location.getFileInLocation(".fmu"); + location.initFile = location.getFileInLocation("_init.xml"); + location.resultFile = location.getFileInLocation("_res." + parameters.get(ModelicaKeys.OUTPUT_FORMAT)); + + if (isOldOMVersion()) { + writeFullModelScriptFile(location, additionalScript); + } + } + + /** + * + * @param location + * @param parameters + * @param additionalScript + * @throws FileNotFoundException + */ + private static void writeScriptFile(SimulationLocation location, HashMap parameters, String additionalScript) + throws FileNotFoundException { + PrintStream s = new PrintStream(location.modelScriptFile); + s.println("loadFile(\"" + location.modelFile.getName() + "\");"); + if(additionalScript != null) + s.println(additionalScript); + s.print("buildModel(" + location.getModelName()); + s.print(",startTime=" + parameters.get(ModelicaKeys.START_VALUE)); + s.print(",stopTime=" + parameters.get(ModelicaKeys.STOP_VALUE)); + s.print(",method=" + parameters.get(ModelicaKeys.METHOD)); + s.print(",outputFormat=\"" + parameters.get(ModelicaKeys.OUTPUT_FORMAT) + "\""); + s.print(",cflags=\"-O0\""); // disable c-compiler optimization => faster compilation + if(parameters.containsKey(ModelicaKeys.TOLERANCE)) { + s.print(",tolerance=" + parameters.get(ModelicaKeys.TOLERANCE)); + } + if(parameters.containsKey(ModelicaKeys.NUMBER_OF_INTERVALS)) { + s.print(",numberOfIntervals=" + parameters.get(ModelicaKeys.NUMBER_OF_INTERVALS)); + } + if(parameters.containsKey(ModelicaKeys.VARIABLE_FILTER)) { + s.print(",variableFilter=\"" + parameters.get(ModelicaKeys.VARIABLE_FILTER) + "\""); + } + s.print(");\n"); + s.println("getErrorString();"); + s.close(); + } + + /** + * + * @param location + * @param additionalScript + * @throws FileNotFoundException + */ + private static void writeFMUScriptFile(SimulationLocation location, String additionalScript) + throws FileNotFoundException { + PrintStream s = new PrintStream(location.modelScriptFile); + s.println("loadFile(\"" + location.modelFile.getName() + "\");"); + if(additionalScript != null) + s.println(additionalScript); + s.println("translateModelFMU(" + location.getModelName() + ");"); + s.println("getErrorString();"); + s.close(); + } + + /** + * + * @param location + * @param additionalScript + * @throws FileNotFoundException + */ + // TODO: try this + private static void writeFullModelScriptFile(SimulationLocation location, String additionalScript) + throws FileNotFoundException { + PrintStream s = new PrintStream(location.fullModelScriptFile); + s.println("loadFile(\"" + location.modelFile.getName() + "\");"); + if(additionalScript != null) + s.println(additionalScript); + s.print("saveTotalSCode("); + s.print("\"" + location.fullModelDir.getName() + "/" + location.fullModelFile.getName() + "\""); + s.print(", "); + s.print(location.getModelName()); + s.print(");\n"); + s.println("getErrorString();"); + s.close(); + } + + public static void buildFullModel(SimulationLocation location, IModelicaMonitor monitor) + throws ModelicaException { + Process process = runOMC(location.omHome, location.getModelDir(), location.fullModelScriptFile.getAbsolutePath()); + printProcessOutput(process, monitor); + + try { + process.waitFor(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + + trimExtraFromFullModel(location); + } + + private static void trimExtraFromFullModel(SimulationLocation location) { + try { + FileInputStream fs = new FileInputStream(location.fullModelFile); + InputStreamReader in = new InputStreamReader(fs); + BufferedReader br = new BufferedReader(in); + StringBuffer sb = new StringBuffer(); + + String textinLine; + boolean openmodelicaflag = false; + int breakpoint = 0; + while((textinLine = br.readLine()) != null) { + if(openmodelicaflag == true) { + breakpoint = sb.length(); + openmodelicaflag = false; + } + + if(textinLine.contains("end OpenModelica;")) + openmodelicaflag = true; + + sb.append(textinLine + "\n"); // if you don’t put the \n you will have all the code on one line as fer said + } + + br.close(); + in.close(); + fs.close(); + + FileWriter fstream = new FileWriter(location.fullModelFile); + BufferedWriter outobj = new BufferedWriter(fstream); + outobj.write(sb.substring(breakpoint)); + outobj.close(); + fstream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Builds a model with omc. The location of required files is + * defined in simulationLocation. + * + * @param location Location of model files + * @param monitor Monitor for printing build process output + * @throws ModelicaException + */ + public static void buildModel(SimulationLocation location, IModelicaMonitor monitor) + throws ModelicaException { + + Process process = runOMC(location.omHome, location.getModelDir(), location.modelScriptFile.getAbsolutePath()); + printProcessOutput(process, monitor); + + try { + process.waitFor(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + + if (!location.executableFile.isFile()) { + // If executable file was not created, something went wrong + throw new ModelicaException("executable file not created"); + } + } + + /** + * Runs a model that has been built to simulationLocation. + * Some initial values can be set for a compiled model without + * re-compiling it. + * + * @param location Location of a built model + * @param monitor Monitor for printing process output + * @param inits Initial values for a simulation run + * @param structureChanged + * @return Simulation process + * @throws IOException + */ + public static Process runModelica(SimulationLocation location, IModelicaMonitor monitor, HashMap experimentParameters, HashMap parameterChanges) throws IOException { + ArrayList commands = new ArrayList(); + try { + if(experimentParameters.get(RESULT_FILE_NAME) != null) { + commands.add("-r="+experimentParameters.get(RESULT_FILE_NAME)); + } + + // Write new initial values (parameters). No need to update xml if structure has changed. In that case also xml is up-to-date + if(parameterChanges != null) { + String version = experimentParameters.get(OMC_VERSION); + // TODO: clean up + if(version == null) + version = getOMVersion(location.omHome); + + Double versionNumber = 1.9; + try { + versionNumber = Double.parseDouble(version.substring(0,3)); + } catch (NumberFormatException e) {} + + if(versionNumber < 1.9) { + writeInits(location, experimentParameters, null); + } else { + // Handled in experiment + if(parameterChanges.size() == 1) { + commands.add("-override"); + commands.add(parameterChanges.keySet().iterator().next() + "=" + parameterChanges.values().iterator().next()); + } else { + // FIXME: if you change 1 parameter AND some experiment parameters, only the parameter change takes effect + updateInitFile(location, experimentParameters, parameterChanges); + } + } + + } + + } + catch (Exception e) { + e.printStackTrace(); + } + + // Commands to String[] + String[] commandString = new String[commands.size()]; + for (int i = 0; i < commands.size(); ++i) + commandString[i] = commands.get(i); + + return runWithEnvironment(location.omHome, location.getModelDir(), location.executableFile, commandString); + } + + public static String getFlatModelText(SimulationLocation location, IModelicaMonitor monitor, List additional) { + String[] command = new String[additional.size()+1]; + command[0] = location.modelFile.getAbsolutePath(); + for (int i = 0; i < additional.size(); i++) { + command[i+1] = additional.get(i); + } + return getProcessOutput(runOMC(location.omHome, location.getModelDir(), command)); + } + + + /** + * Get all parameter variables and their values from model. + * + * @param model model text + * @return a map containing all parameters and values + */ + public static HashMap getModelParameters(String model) { + HashMap result = new HashMap(); + + try { + BufferedReader in = new BufferedReader(new StringReader(model)); + + String line; + String name; + String value; + + while ((line = in.readLine()) != null) { + line = line.trim(); + if (line.startsWith("parameter") && line.contains("=") && line.contains(";")) { + String[] split = line.split(" = "); + name = split[0].trim(); + name = name.substring(name.lastIndexOf(" ") + 1); + value = split[1].trim(); + value = value.substring(0, value.indexOf(";")); + result.put(name, value); + } + } + + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + return result; + } + + + /** + * Updates inits.xml with the latest values. This is not needed if the model structure + * has changed. When model structure is changed, the model is compiled and a new xml is + * created. + * + * Works with version 1.8.1 and previous versions. 1.9 version does not support this, since + * the init.xml file format has been changed. With 1.9, use updateInitFile() + * + * @param simulationLocation Location of the model + * @param monitor + */ + private static void writeInits(SimulationLocation simulationLocation, HashMap experimentParameters, IModelicaMonitor monitor) { + + try { + // Create the full model code into one file + buildFullModel(simulationLocation, null); + + // Create simulation files from the full description + ArrayList parameters = new ArrayList(); + parameters.add("+s"); + parameters.add(simulationLocation.fullModelFile.getAbsolutePath()); + + Process process = runOMC(simulationLocation.omHome, simulationLocation.fullModelDir, "+s", simulationLocation.fullModelFile.getAbsolutePath()); + + process.waitFor(); + + // Find the new init file + FilenameFilter initFilter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + if(name.endsWith("_init.xml")) + return true; + else + return false; + } + }; + + File initFile = null; + for(File f : simulationLocation.fullModelDir.listFiles(initFilter)) { + initFile = f; + break; + } + + if(initFile != null && initFile.isFile()) { + // Replace original init contents with the new contents + replaceInitFileContents(simulationLocation.initFile.getAbsolutePath(), initFile.getAbsolutePath(), experimentParameters); + } + + } catch (ModelicaException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * Replaces variable and experiment information from oldFile with contents of newFile. + * + * The file is not simply replaced because guid must match with guid in created exe. + * + * @param oldFile old init.xml + * @param newFile new init.xml + */ + private static void replaceInitFileContents(String oldFile, String newFile, HashMap experimentParameters) { + try { + XPath xpath = XPathFactory.newInstance().newXPath(); + + Document oldInit = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(new InputSource(oldFile)); + Document newInit = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(new InputSource(newFile)); + + // Find the original model description. This will be modified + Node oldModelDescription = (Node)xpath.evaluate("fmiModelDescription", oldInit, XPathConstants.NODE); + + // + // VARIABLES + // + // First, remove old model variables + Node oldModelVariables = (Node)xpath.evaluate("fmiModelDescription/ModelVariables", oldInit, XPathConstants.NODE); + + oldModelDescription.removeChild(oldModelVariables); + + // Second, find variables in the new model description + Node newModelVariables = (Node)xpath.evaluate("fmiModelDescription/ModelVariables", newInit, XPathConstants.NODE); + + // Import new variables to old xml + Node importedModelVariables = oldInit.importNode(newModelVariables, true); + oldModelDescription.appendChild(importedModelVariables); + + // + // EXPERIMENT PARAMETERS + // + for(String key : experimentParameters.keySet()) { + // Find parameter + Node parameter = (Node)xpath.evaluate + ("fmiModelDescription/DefaultExperiment/@" + key, + oldInit, + XPathConstants.NODE); + + if(parameter != null) { + // Change parameter value + parameter.setNodeValue(experimentParameters.get(key)); + } + } + + // Write transformed init.xml + Transformer xformer = TransformerFactory.newInstance().newTransformer(); + xformer.transform(new DOMSource(oldInit), new StreamResult(new File(oldFile))); + + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (XPathExpressionException e) { + e.printStackTrace(); + } catch (TransformerConfigurationException e) { + e.printStackTrace(); + } catch (TransformerFactoryConfigurationError e) { + e.printStackTrace(); + } catch (TransformerException e) { + e.printStackTrace(); + } + } + + /** + * Updates init file contents with the given experiment and variable changes. + * + * @param simulationLocation Location of simulation files + * @param experimentParameters Experiment parameters + * @param changes Parameter variable changes + */ + public static void updateInitFile(SimulationLocation simulationLocation, HashMap experimentParameters, HashMap changes) { + try { + XPath xpath = XPathFactory.newInstance().newXPath(); + + Document init = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(simulationLocation.initFile); + + // + // EXPERIMENT PARAMETERS + // + for(String key : experimentParameters.keySet()) { + // Find parameter + Node parameter = (Node)xpath.evaluate + ("fmiModelDescription/DefaultExperiment/@" + key, + init, + XPathConstants.NODE); + + if(parameter != null) { + // Change parameter value + parameter.setNodeValue(experimentParameters.get(key)); + } + } + + // + // PARAMETER VARIABLES + // + for(String name : changes.keySet()) { + Node node = (Node)xpath.evaluate + ("//fmiModelDescription/ModelVariables/ScalarVariable[@name='" + name + "']/Real/@start", + init, + XPathConstants.NODE); + if(node != null) { + node.setNodeValue(changes.get(name)); + } + } + + // Write transformed init.xml + Transformer xformer = TransformerFactory.newInstance().newTransformer(); + xformer.transform(new DOMSource(init), new StreamResult(simulationLocation.initFile)); + + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (XPathExpressionException e) { + e.printStackTrace(); + } catch (TransformerConfigurationException e) { + e.printStackTrace(); + } catch (TransformerFactoryConfigurationError e) { + e.printStackTrace(); + } catch (TransformerException e) { + e.printStackTrace(); + } + } +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/SimulationLocation.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/SimulationLocation.java new file mode 100644 index 00000000..70aa6f8b --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/SimulationLocation.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica; + +import java.io.File; + +/** + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * @author Janne Kauttio + */ +public class SimulationLocation { + + private String modelName; + + public File modelDir; + public File modelFile; + public File modelScriptFile; + public File fullModelDir; + public File fullModelFile; + public File fullModelScriptFile; + public File initFile; + public File executableFile; + public File resultFile; + public File omHome; + + public SimulationLocation(File modelDir, String modelName) { + this.modelDir = modelDir; + this.modelName = modelName; + } + + public File getModelDir() { + return modelDir; + } + + public String getModelName() { + return modelName; + } + + public File getFileInLocation(String name, String affix) { + return new File(modelDir, name + affix); + } + + public File getFileInLocation(String affix) { + return getFileInLocation(modelName, affix); + } + + public SimulationLocation(File modelDir, File modelFile, File modelScriptFile, + File resultFile, File initFile, File executableFile, File omHome) { + this.modelDir = modelDir; + this.modelFile = modelFile; + this.modelScriptFile = modelScriptFile; + this.fullModelDir = null; + this.fullModelFile = null; + this.fullModelScriptFile = null; + this.resultFile = resultFile; + this.initFile = initFile; + this.executableFile = executableFile; + this.omHome = omHome; + } + + public SimulationLocation(File modelDir, File model, File modelScriptFile, + File fullModelDir, File fullModelFile, File fullModelScriptFile, + File resultFile, File initFile, File executableFile, File omHome) { + this.modelDir = modelDir; + this.modelFile = model; + this.modelScriptFile = modelScriptFile; + this.fullModelDir = fullModelDir; + this.fullModelFile = fullModelFile; + this.fullModelScriptFile = fullModelScriptFile; + this.resultFile = resultFile; + this.initFile = initFile; + this.executableFile = executableFile; + this.omHome = omHome; + } + + // TODO: remove this later +// public SimulationLocation(File modelDir, File modelScriptFile, File fullModelDir, File fullModelScriptFile, +// File resultFile, File initFile, File executableFile) { +// this.modelDir = modelDir; +// this.modelScriptFile = modelScriptFile; +// this.fullModelDir = fullModelDir; +// this.fullModelScriptFile = fullModelScriptFile; +// this.resultFile = resultFile; +// this.initFile = initFile; +// this.executableFile = executableFile; +// this.fullModel = new File(getFullModelPath()); +// this.omc = ModelicaManager.getOpenModelicaHome(); +// } + + private String getFullModelPath() { + if(fullModelScriptFile == null) + return null; + + String fullScriptPath = fullModelScriptFile.getAbsolutePath(); + return fullScriptPath.substring(0, fullScriptPath.length()-1); // ..._full.mos -> ..._full.mo + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/CSVSimulationResult.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/CSVSimulationResult.java new file mode 100644 index 00000000..8787adf9 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/CSVSimulationResult.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.data; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * class for supporting csv-format simulation results + * @author Teemu Lempinen + * + */ +public class CSVSimulationResult extends SimulationResult { + + HashMap valueMap = new HashMap(); + + /** + * Overridden method to support csv-formatted simulation results + */ + @Override + public void read(InputStream stream, int outputInterval) { + errors.clear(); + + // First line contains the variable names in format "name" (including quotes); + String line = getLine(stream); + if(line == null) + return; + + line = line.substring(1, line.lastIndexOf("\"")); + String[] names = line.split("\",\""); + + // Create lists for receiving values for each variable. Names still with quotes. + for(String name : names) { + if(!name.isEmpty()) + valueMap.put(name, new DataSet(name, new double[numberOfLines], new double[numberOfLines])); + } + + int row = 0; + // Data sets + while((line = getLine(stream)) != null) { + if(line.isEmpty()) + break; + String[] values = line.split(","); + for(int valueIndex = 0; valueIndex list = errors.get(names[valueIndex]); + if(list == null) { + list = new ArrayList(); + errors.put(names[valueIndex], list); + } + list.add(new TimeValuePair(values[0], values[valueIndex])); + } + } + } + row++; + } + + // Add time values for each dataset and add them to variables. + for(DataSet ds : valueMap.values()) { + ds.times = valueMap.get("time").values; + variables.add(ds); + } + } +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/DataSet.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/DataSet.java new file mode 100644 index 00000000..c1c4bae9 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/DataSet.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.data; + +/** + * Simulation result for one variable. + * @author Hannu Niemistö + */ +public class DataSet { + public String name; + public double[] times; + public double[] values; + + public DataSet(String name, double[] times, double[] values) { + this.name = name; + this.times = times; + this.values = values; + } +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/DoubleMatrix.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/DoubleMatrix.java new file mode 100644 index 00000000..d8ace791 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/DoubleMatrix.java @@ -0,0 +1,38 @@ +package org.simantics.modelica.data; + +/** + * Copied from Hannu's DoubleMatrix in org.simantics.modelica.data + * + * To be replaced with the original when SysDyn and Modelica tools + * are synchronized to use the same OpenModelica plugin + * + * @author Teemu Lempinen + * + */ +public class DoubleMatrix extends Matrix { + public final int rows; + public final int columns; + public final double[] data; + + public DoubleMatrix(String name, int rows, int columns) { + super(name); + this.rows = rows; + this.columns = columns; + this.data = new double[rows*columns]; + } + + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("double " + name + "(" + rows + "," + columns + ")\n"); + for(int i=0;i 0) + b.append(' '); + b.append(data[i*rows + j]); + } + b.append('\n'); + } + return b.toString(); + } +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/IntMatrix.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/IntMatrix.java new file mode 100644 index 00000000..6f3d6d4e --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/IntMatrix.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.data; + +/** + * Copied from Hannu's IntMatrix in org.simantics.modelica.data + * + * To be replaced with the original when SysDyn and Modelica tools + * are synchronized to use the same OpenModelica plugin + * + * @author Teemu Lempinen + * + */ +public class IntMatrix extends Matrix { + public final int rows; + public final int columns; + public final int[] data; + + public IntMatrix(String name, int rows, int columns) { + super(name); + this.rows = rows; + this.columns = columns; + this.data = new int[rows*columns]; + } + + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("int " + name + "(" + rows + "," + columns + ")\n"); + for(int i=0;i 0) + b.append(' '); + b.append(data[i*rows + j]); + } + b.append('\n'); + } + return b.toString(); + } +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/Mat4Reader.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/Mat4Reader.java new file mode 100644 index 00000000..635fc778 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/Mat4Reader.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.data; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * Copied from Hannu's Mat4Reader in org.simantics.modelica.data + * + * To be replaced with the original when SysDyn and Modelica tools + * are synchronized to use the same OpenModelica plugin + * + * @author Teemu Lempinen + * + */ +public class Mat4Reader { + + InputStream in; + + public Mat4Reader(InputStream in) { + this.in = in; + } + + private final int getInt() throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + int ch3 = in.read(); + int ch4 = in.read(); + return ((ch1 << 0) + (ch2 << 8) + (ch3 << 16) + (ch4 << 24)); + } + + private final long getLong() throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + int ch3 = in.read(); + int ch4 = in.read(); + int ch5 = in.read(); + int ch6 = in.read(); + int ch7 = in.read(); + int ch8 = in.read(); + return ((((long)ch1) << 0) + (((long)ch2) << 8) + (((long)ch3) << 16) + (((long)ch4) << 24) + + (((long)ch5) << 32) + (((long)ch6) << 40) + (((long)ch7) << 48) + (((long)ch8) << 56)); + } + + private final double getDouble() throws IOException { + return Double.longBitsToDouble(getLong()); + } + + private String getString(int length) throws IOException { + byte[] buffer = new byte[length]; + int pos = 0; + while(pos < length) + pos += in.read(buffer, pos, length-pos); + return new String(buffer, "UTF-8"); + } + + public Matrix readMatrix() throws IOException { + int type = getInt(); + int rows = getInt(); + int columns = getInt(); + int imagf = getInt(); + int namlen = getInt(); + + String name = getString(namlen-1); + in.read(); + + if(imagf > 0) + throw new IOException("Imaginary part of the matrix is not supported (matrix " + name + ")."); + + switch(type) { + case 0: { + DoubleMatrix matrix = new DoubleMatrix(name, rows, columns); + int size = rows*columns; + double[] data = matrix.data; + for(int i=0;i read(InputStream in, int outputInterval) throws IOException { + Mat4Reader reader = new Mat4Reader(in); + reader.readMatrix(); // Header + StringMatrix names = (StringMatrix)reader.readMatrix(); // Variable names + reader.readMatrix(); // Variable descriptions + IntMatrix info = (IntMatrix)reader.readMatrix(); // Data info + if(info.rows != 4 || info.columns != names.rows ) + throw new IOException("Invalid result data."); + + HashMap result = new HashMap(); + DoubleMatrix parameters = (DoubleMatrix)reader.readMatrix(); // Some result data matrix? + readDoubleMatrix(parameters, names, 1, 1, info, 1, result); + DoubleMatrix values = (DoubleMatrix)reader.readMatrix(); + readDoubleMatrix(values, names, 2, 0, info, outputInterval, result); + in.close(); + + return result; + + } + + private static void readDoubleMatrix(DoubleMatrix matrix, StringMatrix names, int dataMatrixNumber, int startIndex, IntMatrix info, int outputInterval, HashMap result) { + double[] valueData = matrix.data; + int[] infoData = info.data; + int rows = matrix.rows; + //System.out.println("cols="+values.columns+", rows=" +values.rows+ ", data.length="+valueData.length); + for(int i=startIndex;i 0 ? sc-1 : -sc-1; + //System.out.println("i=" + i + ", sc=" + sc + ", c=" + c); + for(int j=0;j= matrix.columns) adjusted = matrix.columns - 1; + v[j] = valueData[rows * adjusted + c]; + } if(sc < 0) + for(int j=0;j valueMap = null; + try { + valueMap = Mat4Reader.read(stream, interval); + } catch (IOException e) { + e.printStackTrace(); + return; + } + + DataSet ds; + double[] allTimes = valueMap.get("time"); + if(allTimes.length > 0) { + double[] parameterTimes = new double[] {allTimes[0], allTimes[allTimes.length - 1]}; + for(String key : valueMap.keySet()) { + double[] values = valueMap.get(key); + if(values.length == 2) + ds = new DataSet(key, parameterTimes, values); + else + ds = new DataSet(key, allTimes, values); + variables.add(ds); + } + } + } + + @Override + public void initRead(File file) throws FileNotFoundException, IOException { + super.initRead(file); + resultFileReader = new MatFileReader(file); + } +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/Matrix.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/Matrix.java new file mode 100644 index 00000000..1e68c1b6 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/Matrix.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.data; + +/** + * Copied from Hannu's Matrix in org.simantics.modelica.data + * + * To be replaced with the original when SysDyn and Modelica tools + * are synchronized to use the same OpenModelica plugin + * + * @author Teemu Lempinen + * + */ +public abstract class Matrix { + public final String name; + + public Matrix(String name) { + this.name = name; + } +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java new file mode 100644 index 00000000..315b1fc8 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java @@ -0,0 +1,520 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - Bug #4180 + *******************************************************************************/ +package org.simantics.modelica.data; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.LineNumberReader; +import java.util.ArrayList; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.simantics.modelica.reader.ResultFileReader; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Class that reads OpenModelica result files. + * + * SimulationResult class reads plt-files. Extended classes read other types. + * + * Will be replaced with a common OpenModelica plugin + * @author Hannu Niemistö + * @author Tuomas Miettinen + */ +public class SimulationResult { + + protected List variables = new ArrayList(); + protected List initials = new ArrayList(); + protected int numberOfLines = 0; + protected ResultFileReader resultFileReader; + protected double[] allTimes; + protected int skip; + + /** + * Private class used in displaying errors + */ + protected class TimeValuePair { + public String time; + public String value; + + public TimeValuePair(String time, String value) { + this.time = time; + this.value = value; + } + } + + protected HashMap> errors = new HashMap>(); + + /** + * Get the next line in the plt-file + * @param stream plt-file input stream + * @return next line in the stream + */ + static String getLine(InputStream stream) { + if(stream == null) + return null; + StringBuilder b = new StringBuilder(); + try { + while(true) { + int c = stream.read(); + if(c == -1) { + stream = null; + return b.toString(); + } + else if(c == '\n') + return b.toString(); + else if(c == '\r') + ; + else + b.append((char)c); + } + } catch (IOException e) { + return null; + } + + } + + + /** + * Read parameters that are located in the inits-file to the simulation result. + * Supports both txt and xml type inits. + * + * @param file inits-file + * @throws FileNotFoundException + * @throws IOException + */ + public void readInits(File file) throws FileNotFoundException, IOException { + + if(file.getName().endsWith("txt")) { + InputStream is = openStream(file); + readInitsTXT(is); + is.close(); + } else if(file.getName().endsWith("xml")) { + readInitsXML(file.getAbsolutePath()); + } + } + + /** + * Read xml inits + * + * @param file xml-formatted inits file + */ + public void readInitsXML(String file) { + Document doc; + try { + doc = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(new InputSource(file)); + + XPath xpath = XPathFactory.newInstance().newXPath(); + + double[] times = new double[2]; + Node node; + // Find start time + node = (Node)xpath.evaluate + ("//fmiModelDescription/DefaultExperiment/@startTime", + doc, + XPathConstants.NODE); + times[0] = Double.parseDouble(node.getNodeValue()); + // Find end time + node = (Node)xpath.evaluate + ("//fmiModelDescription/DefaultExperiment/@stopTime", + doc, + XPathConstants.NODE); + times[1] = Double.parseDouble(node.getNodeValue()); + + NodeList nodes; + + // Find parameters and constants + nodes = (NodeList)xpath.evaluate + ("//fmiModelDescription/ModelVariables/ScalarVariable[@variability='parameter']", + doc, + XPathConstants.NODESET); + + // Add parameters and constants to initials + for (int idx = 0; idx < nodes.getLength(); idx++) { + Node n = nodes.item(idx); + String name = n.getAttributes().getNamedItem("name").getNodeValue(); + addToInitials(name, n, times); + + } + + // Find all alias variables + NodeList allAliasVariables = (NodeList)xpath.evaluate + ("//fmiModelDescription/ModelVariables/ScalarVariable[@alias='alias']", + doc, + XPathConstants.NODESET); + + for(int i = 0; i < allAliasVariables.getLength(); i++) { + Node n = allAliasVariables.item(i); + String name = n.getAttributes().getNamedItem("name").getNodeValue(); + + // Find the original variable + Node aliasVariableProperty = n.getAttributes().getNamedItem("aliasVariable"); + String aliasVariableName = aliasVariableProperty.getNodeValue(); + n = (Node)xpath.evaluate + ("//fmiModelDescription/ModelVariables/ScalarVariable[@name='" + aliasVariableName +"' and @variability='parameter']", + doc, + XPathConstants.NODE); + // Add the value of the original value to initials with the name of the alias variable + if(n != null) + addToInitials(name, n, times); + } + + + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (TransformerFactoryConfigurationError e) { + e.printStackTrace(); + } catch (XPathExpressionException e) { + e.printStackTrace(); + } + } + + /** + * Adds a new dataset to initials using start name, value from + * node and times. + * + * @param name Name for the dataset to be added to initials + * @param node Node containing the start value attribute + * @param times Array of times (length == 2) + */ + private void addToInitials(String name, Node node, double[] times) { + // Find the start value for this + double[] values; + NodeList children; + children = node.getChildNodes(); + for(int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if(child.getNodeName().equals("Real")) { + Double d = Double.parseDouble(child.getAttributes().getNamedItem("start").getNodeValue()); + values = new double[] {d,d}; + initials.add( + new DataSet(name, + times , + values)); + break; + } + } + } + + /** + * Read txt inits + * @param stream txt-formatted init file + */ + public void readInitsTXT(InputStream stream) { + HashMap mappedInitials = new HashMap(); + while(true) { + String line = getLine(stream); + if(line == null) + return; + if(line.isEmpty()) + break; + + if(line.contains("//")) { + String[] nn = line.split("//", 2); + try { + double value = Double.parseDouble(nn[0].trim()); + String key = nn[1].trim(); + mappedInitials.put(key, value); + } catch (NumberFormatException nfe) { + continue; // Not a valid double + } + + } + + } + + double startTime = mappedInitials.get("start value"); + double stopTime = mappedInitials.get("stop value"); + double[] times = new double[] {startTime, stopTime}; + + for(String key : mappedInitials.keySet()) { + double d = mappedInitials.get(key); + double[] values = new double[] {d, d}; + initials.add(new DataSet(key, times , values)); + } + } + + /** + * Read result file. Read all values in the result file. + * + * @param file result file + * @throws FileNotFoundException + * @throws IOException + */ + public void read(File file) throws FileNotFoundException, IOException { + read(file, 1); + } + + /** + * Initialize result file reading and read the whole result file + * + * @param file result file + * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc... + * @throws FileNotFoundException + * @throws IOException + */ + public void read(File file, int interval) throws FileNotFoundException, IOException { + initRead(file); + readAll(file, interval); + } + + /** + * Initialize result file reading + * + * @param file result file + * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc... + * @throws FileNotFoundException + * @throws IOException + */ + public void initRead(File file) throws FileNotFoundException, IOException { + // First check the number of time steps. + // With *.mat result file this is not necessary + if (!(this instanceof MatSimulationResult)) { + FileReader fr = new FileReader(file); + LineNumberReader lnr = new LineNumberReader(fr); + lnr.skip(Long.MAX_VALUE); + numberOfLines = lnr.getLineNumber() - 1; // minus the first row, which is for names + lnr.close(); + fr.close(); + } + } + + /** + * Read the whole result file + * + * @param file result file + * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc... + * @throws FileNotFoundException + * @throws IOException + */ + public void readAll(File file, int interval) throws FileNotFoundException, IOException { + InputStream is = openStream(file); + read(is, interval); + is.close(); + } + + + protected InputStream openStream(File file) throws FileNotFoundException { + return new BufferedInputStream(new FileInputStream(file)); + } + + final static Pattern p1 = Pattern.compile("DataSet: ([^ ]*)"); + + /** + * Read result file. The basic implementation supports + * plt-formatted results. Overridden to support other formats. + * @param stream FileInputStream for the result file + * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc... + */ + public void read(InputStream stream, int outputInterval) { + while(true) { + String line = getLine(stream); + if(line == null) + return; + if(line.isEmpty()) + break; + } + + // Data sets + while(true) { + Matcher matcher = p1.matcher(getLine(stream)); + if(!matcher.matches()) + return; + String name = matcher.group(1); + double[] dtimes = new double[numberOfLines]; + double[] dvalues = new double[numberOfLines]; + int i = 0; + while(true) { + String line = getLine(stream); + if(line == null) + return; + if(line.isEmpty()) + break; + String[] nn = line.split(", ", 2); + dtimes[i] = Double.parseDouble(nn[0]); + dvalues[i] = Double.parseDouble(nn[1]); + i++; + } + + variables.add(new DataSet(name, dtimes, dvalues)); + } + } + + /** + * Filter result set + */ + public void filter() { + ArrayList newVariables = new ArrayList(); + for(DataSet dataSet : variables) { + if(!dataSet.name.contains("$") && !dataSet.name.contains("der(")) + newVariables.add(dataSet); + } + variables = newVariables; + } + + /** + * Get datasets for the variables in this result + * @return variable datasets + */ + public List getVariableDataSets() { + return variables; + } + + /** + * Get datasets for the initial values in this simulation + * @return initial value datasets + */ + public List getInitialValueDataSets() { + return initials; + } + + /** + * Gets DataSet for variable. Loops first the variables and then initials. + * @param name the name of the variable + * @return DataSet for the variable or null if DataSet not found + */ + public DataSet getDataSet(String name) { + for(DataSet set : variables) + if(set.name.equalsIgnoreCase(name)) + return set; + for(DataSet set : initials) + if(set.name.equalsIgnoreCase(name)) + return set; + return null; + } + + + /** + * Return errors encountered during reading of the results. + * + * @return + */ + public String getResultReadErrors() { + StringBuilder errorString = new StringBuilder(); + if(!errors.isEmpty()) { + errorString.append("Number format errors (Time, Value):\n"); + for(String key : errors.keySet()) { + errorString.append("\n" + key + ":\n"); + for(TimeValuePair tv : errors.get(key)) { + errorString.append(" " + tv.time + ", " + tv.value + "\n"); + } + } + } + return errorString.toString(); + } + + /** + * Read a defined variable from result file + * + * @param file result file + * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc... + * @return The added dataset + * @throws FileNotFoundException + * @throws IOException + */ + public DataSet readVariable(String variable, File file) throws FileNotFoundException, IOException { + if(resultFileReader == null) + return null; + + DataSet ds; + List names = resultFileReader.getNames(); + if (names.contains(variable)) { + double[] resArray = resultFileReader.readData(variable, 0, allTimes.length, skip); + double[] timesArray = allTimes; + if(resArray.length == 2 && timesArray.length > 2) + timesArray = new double[] {timesArray[0], timesArray[timesArray.length - 1]}; + ds = new DataSet(variable, timesArray, resArray); + try { + for (DataSet tempds : variables){ + if (tempds.name.equals(variable)) { + // We should never need to go there unless some change in + // the logic of reading variables are made. + // Also helps in seeking memory leaks. + return null; + } + } + } catch (ConcurrentModificationException e) { + } + variables.add(ds); + return ds; + } + return null; + } + + /** + * Read a all missing variable from the result file + * + * @param file result file + * @throws FileNotFoundException + * @throws IOException + */ + public void readMissingVariables(File file) throws FileNotFoundException, IOException { + List names = resultFileReader.getNames(); + for (String variable : names) { + boolean matchFound = false; + for (DataSet tempDs : variables) { + if (tempDs.name.equals(variable)) { + matchFound = true; + break; + } + } + if (matchFound) { + continue; + } + readVariable(variable, file); + } + } + + /** + * Read time array from result file + * + * @param file result file + * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc... + * @throws FileNotFoundException + * @throws IOException + */ + public void readTime(File file, int interval) throws FileNotFoundException, IOException { + skip = interval - 1; + int totalCount = resultFileReader.getCount("time"); + int count = totalCount / interval; + if (totalCount % interval != 0) + count++; + allTimes = resultFileReader.readData("time", 0, count, skip); + } + +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/StringMatrix.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/StringMatrix.java new file mode 100644 index 00000000..8cfbea02 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/data/StringMatrix.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.data; + +/** + * Copied from Hannu's StringMatrix in org.simantics.modelica.data + * + * To be replaced with the original when SysDyn and Modelica tools + * are synchronized to use the same OpenModelica plugin + * + * @author Teemu Lempinen + * + */ +public class StringMatrix extends Matrix { + public final int rows; + public final String[] data; + + public StringMatrix(String name, int rows) { + super(name); + this.rows = rows; + this.data = new String[rows]; + } + + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("char " + name + "(" + rows + ")\n"); + for(String row : data) + b.append(row + "\n"); + return b.toString(); + } +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/preferences/ModelicaPreferenceInitializer.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/preferences/ModelicaPreferenceInitializer.java new file mode 100644 index 00000000..553aeaba --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/preferences/ModelicaPreferenceInitializer.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.preferences; + +import java.io.File; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.osgi.service.prefs.Preferences; +import org.simantics.modelica.Activator; +import org.simantics.modelica.ModelicaManager; + +public class ModelicaPreferenceInitializer extends AbstractPreferenceInitializer { + + @Override + public void initializeDefaultPreferences() { + IScopeContext context = ConfigurationScope.INSTANCE; + Preferences node = context.getNode(Activator.PLUGIN_ID); + String omHome = node.get(OpenModelicaPreferences.OM_HOME, null); + if (omHome == null) { + // OM_HOME not set + useDefault(node); + } else { + File dir = new File(omHome); + if(dir == null || !dir.isDirectory()) + // OM_HOME is not a directory + useDefault(node); + // TODO: does not make much sense +// try { +// ModelicaManager.getOpenModelicaVersion(); +// } catch (IOException e) { +// // OpenModelica not found from directory +// useDefault(node); +// } + } + } + + private void useDefault(Preferences node) { + node.put(OpenModelicaPreferences.OM_HOME, ModelicaManager.getDefaultOMHome().getAbsolutePath()); + } + +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/preferences/OpenModelicaPreferences.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/preferences/OpenModelicaPreferences.java new file mode 100644 index 00000000..e8b0e6ae --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/preferences/OpenModelicaPreferences.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modelica.preferences; + +public class OpenModelicaPreferences { + + public static String OM_HOME = "OPENMODELICA_HOME"; + +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/reader/MatFileReader.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/reader/MatFileReader.java new file mode 100644 index 00000000..79db0d6c --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/reader/MatFileReader.java @@ -0,0 +1,619 @@ +package org.simantics.modelica.reader; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.simantics.modelica.data.DoubleMatrix; +import org.simantics.modelica.data.IntMatrix; +import org.simantics.modelica.data.Matrix; +import org.simantics.modelica.data.StringMatrix; +import org.simantics.utils.datastructures.MapList; + +public class MatFileReader implements ResultFileReader { + private final File file; + + private final List names = new ArrayList(); + private final Map indices = new HashMap(); + + private HashMap parameterValues; + + long readBytes = 0; // tracking read data + long dataMark = 0; // mark for actual data + + IntMatrix info; + int[] infoData; + + MatrixHeader dataHeader; + + public MatFileReader(File file) throws IOException { + this.file = file; + readVariables(); + } + + @Override + public List getNames() { + return names; + } + + @Override + public int getCount(String item) { + return dataHeader.columns; + } + + /** + * Reads all data of a given item + */ + @Override + public double[] readData(String item) throws IOException { + readBytes = 0; + Integer index = indices.get(item); + if (index == null) + if (parameterValues.containsKey(item)) { + return parameterValues.get(item); + } else { + throw new IOException("Unknown item: " + item); + } + InputStream in = openStream(); + skip(dataMark, in); + + Object data = readRow(dataHeader, index, in); + + in.close(); + + return (double[])data; + } + + /** + * Reads data of a given item + * @param item name of a item. + * @param start index of starting sample. + * @param count number of samples to read. + * @param skip number of samples to skip. 0 : all data is read. 1: every second sample is read. + * @return + * @throws IOException + */ + @Override + public double[] readData(String item, int start, int count, int skip) throws IOException { + readBytes = 0; + Integer index = indices.get(item); + if (index == null) + if (parameterValues.containsKey(item)) { + return parameterValues.get(item); + } else { + throw new IOException("Unknown item: " + item); + } + InputStream in = openStream(); + skip(dataMark, in); + + Object data = readRow(dataHeader, index, start, count, skip, in); + + in.close(); + + return (double[])data; + + } + + @Override + public double[][] readData(List items) throws IOException { + readBytes = 0; + List indexes = new ArrayList(items.size()); + for (String item : items) { + Integer index = indices.get(item); + if (index == null) + // Parameters cannot be accessed via this method; instead, + // methods with only a single item should be used + throw new IOException("Unknown item: " + item); + indexes.add(index); + } + + InputStream in = openStream(); + skip(dataMark, in); + + + + Object data = readRows(dataHeader, indexes, in); + + in.close(); + + return (double[][])data; + + } + + private InputStream openStream() throws FileNotFoundException { + return new BufferedInputStream(new FileInputStream(file)); + } + + @Override + public double[][] readData(List items, int start, int count, + int skip) throws IOException { + readBytes = 0; + + List indexes = new ArrayList(items.size()); + for (String item : items) { + Integer index = indices.get(item); + if (index == null) + // Parameters cannot be accessed via this method; instead, + // methods with only a single item should be used + throw new IOException("Unknown item: " + item); + indexes.add(index); + } + + InputStream in = openStream(); + skip(dataMark, in); + + + + Object data = readRows(dataHeader, indexes,start,count,skip, in); + + in.close(); + + return (double[][])data; + } + + private void readVariables() throws IOException { + InputStream in = openStream(); + readMatrix(in); // Header + StringMatrix names = (StringMatrix)readMatrix(in); // Variable names + readMatrix(in); // Variable descriptions + + for (int i = 0; i < names.data.length; i++) { + String s = names.data[i]; + this.names.add(s); + indices.put(s, i); + } + + + + info = (IntMatrix)readMatrix(in); // Data info + + if(info.rows != 4 || info.columns != names.rows ) + throw new IOException("Invalid result data."); + + infoData = info.data; + + //Read parameters + parameterValues = new HashMap(); + DoubleMatrix parameters = (DoubleMatrix)readMatrix(in); // Some result data matrix? + readDoubleMatrix(parameters, names, 1, 1, info, 1, parameterValues); + + dataHeader = new MatrixHeader(in); + + dataMark = readBytes; + + in.close(); + + // filter incompatible? data. + for (int i = this.names.size() -1; i >= 0; i--) { + if (infoData[i * 4] != 2) { + String name = this.names.get(i); + // Remove parameters from indices but not from names list + this.indices.remove(name); + } + + } + + Collections.sort(this.names); + + } + + private final int getInt(InputStream in) throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + int ch3 = in.read(); + int ch4 = in.read(); + readBytes += 4; + return ((ch1 << 0) + (ch2 << 8) + (ch3 << 16) + (ch4 << 24)); + } + + private final long getLong(InputStream in) throws IOException { + int ch1 = in.read(); + int ch2 = in.read(); + int ch3 = in.read(); + int ch4 = in.read(); + int ch5 = in.read(); + int ch6 = in.read(); + int ch7 = in.read(); + int ch8 = in.read(); + readBytes += 8; + return ((((long)ch1) << 0) + (((long)ch2) << 8) + (((long)ch3) << 16) + (((long)ch4) << 24) + + (((long)ch5) << 32) + (((long)ch6) << 40) + (((long)ch7) << 48) + (((long)ch8) << 56)); + } + + private final double getDouble(InputStream in) throws IOException { + return Double.longBitsToDouble(getLong(in)); + } + + private String getString(InputStream in,int length) throws IOException { + byte[] buffer = new byte[length]; + int pos = 0; + while(pos < length) + pos += in.read(buffer, pos, length-pos); + readBytes += length; + return new String(buffer, "UTF-8"); + } + + private Matrix readMatrix(InputStream in) throws IOException { + + int type = getInt(in); + int rows = getInt(in); + int columns = getInt(in); + int imagf = getInt(in); + int namlen = getInt(in); + + String name = getString(in,namlen-1); + in.read(); + readBytes++; + + if(imagf > 0) + throw new IOException("Imaginary part of the matrix is not supported (matrix " + name + ")."); + + switch(type) { + case 0: { + DoubleMatrix matrix = new DoubleMatrix(name, rows, columns); + int size = rows*columns; + double[] data = matrix.data; + for(int i=0;i 0 ? sc-1 : -sc-1; + + skip(c * 8, in); + for (int j = 0; j < v.length; ++j) { + + double d = getDouble(in); + v[j] = d; + skip((rows-1)*8,in); + } + + if(sc < 0) + for(int j=0;j size) + throw new IndexOutOfBoundsException(); // TODO: we could just read available data, instead of throwing exception. + int rows = header.rows; + double[] v = new double[count]; + int sc = infoData[row * 4 + 1]; + long c = sc > 0 ? sc-1 : -sc-1; + + skip((c+((long)start*(long)rows)) * 8L, in); + for (int j = 0; j < v.length; ++j) { + + double d = getDouble(in); + v[j] = d; + skip((rows*skip + rows-1)*8,in); + } + + if(sc < 0) + for(int j=0;j unSortedRows, InputStream in)throws IOException { + + if (header.type != 0) + throw new IOException("Only double type supported"); + for (int row : unSortedRows) + if (infoData[row * 4] != 2) + throw new IOException(); // this is checked in initialization phase. + int size = header.columns; + int rows = header.rows; + int usc[] = new int[unSortedRows.size()]; + int uc[] = new int[unSortedRows.size()]; + double vs[][] = new double[unSortedRows.size()][]; + for (int i = 0; i < unSortedRows.size(); i++) { + int row = unSortedRows.get(i); + //vs[i] = new double[size]; + usc[i] = infoData[row * 4 + 1]; + uc[i] = usc[i] > 0 ? usc[i]-1 : -usc[i]-1; + } + + MapList cToRow = new MapList(); + List sortedCs = new ArrayList(); + for (int i = 0; i < unSortedRows.size(); i++) { + cToRow.add(uc[i], unSortedRows.get(i)); + sortedCs.add(uc[i]); + } + + List sortedRows = new ArrayList(); + int sc[] = new int[sortedCs.size()]; + int c[] = new int[sortedCs.size()]; + + Collections.sort(sortedCs); + + for (int i = 0; i < sortedCs.size(); i++) { + int row = cToRow.getValues(sortedCs.get(i)).get(0); + sortedRows.add(row); + sc[i] = usc[unSortedRows.indexOf(row)]; + c[i] = uc[unSortedRows.indexOf(row)]; + vs[i] = new double[size]; + } + + skip(c[0] * 8L, in); + for (int j = 0; j < size; ++j) { + for (int index = 0; index < sortedRows.size(); index++) { + + double d = getDouble(in); + vs[index][j] = d; + + if (index < sortedRows.size() - 1) { + skip((c[index+1] - c[index] -1 )*8, in); + } else { + skip((rows - c[index]-1 + c[0])*8,in); + } + } + } + + + for (int i = 0; i < sortedRows.size(); i++) { + if(sc[i] < 0) + for(int j=0;j unSortedRows, int start, int count, int skip, InputStream in)throws IOException { + + if (header.type != 0) + throw new IOException("Only double type supported"); + for (int row : unSortedRows) + if (infoData[row * 4] != 2) + throw new IOException(); // this is checked in initialization phase. + + int size = header.columns; + int rows = header.rows; + + if (start+count*(skip+1) > size) + throw new IndexOutOfBoundsException(); // TODO: we could just read available data, instead of throwing exception. + + int usc[] = new int[unSortedRows.size()]; + int uc[] = new int[unSortedRows.size()]; + double vs[][] = new double[unSortedRows.size()][]; + for (int i = 0; i < unSortedRows.size(); i++) { + int row = unSortedRows.get(i); + usc[i] = infoData[row * 4 + 1]; + uc[i] = usc[i] > 0 ? usc[i]-1 : -usc[i]-1; + } + + MapList cToRow = new MapList(); + List sortedCs = new ArrayList(); + for (int i = 0; i < unSortedRows.size(); i++) { + cToRow.add(uc[i], unSortedRows.get(i)); + if (!sortedCs.contains(uc[i])) + sortedCs.add(uc[i]); + } + + List sortedRows = new ArrayList(); + int sc[] = new int[sortedCs.size()]; + int c[] = new int[sortedCs.size()]; + + Collections.sort(sortedCs); + for (int i = 0; i < sortedCs.size(); i++) { + int row = cToRow.getValues(sortedCs.get(i)).get(0); + sortedRows.add(row); + sc[i] = usc[unSortedRows.indexOf(row)]; + c[i] = uc[unSortedRows.indexOf(row)]; + vs[i] = new double[count]; + } + + long s = start; + s *= rows; + s *= 8L; + skip(s, in); + skip(c[0] * 8, in); + for (int j = 0; j < count; ++j) { + for (int index = 0; index < sortedRows.size(); index++) { + + double d = getDouble(in); + vs[index][j] = d; + + if (index < sortedRows.size() - 1) { + skip((c[index+1] - c[index] -1 )*8, in); + } else { + skip((rows - c[index]-1 + c[0])*8,in); + } + } + if (skip > 0) + skip((skip*rows)*8,in); + } + + + for (int i = 0; i < sortedRows.size(); i++) { + if(sc[i] < 0) + for(int j=0;j result) { + double[] valueData = matrix.data; + int[] infoData = info.data; + int rows = matrix.rows; + + for(int i=startIndex;i 0 ? sc-1 : -sc-1; + for(int j=0;j= matrix.columns) adjusted = matrix.columns - 1; + v[j] = valueData[rows * adjusted + c]; + } if(sc < 0) + for(int j=0;j 0) + throw new IOException("Imaginary part of the matrix is not supported (matrix " + name + ")."); + + } + } + + @Override + public String toString() { + return file.getName(); + } +} diff --git a/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/reader/ResultFileReader.java b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/reader/ResultFileReader.java new file mode 100644 index 00000000..e82619e2 --- /dev/null +++ b/dev-jkauttio/org.simantics.modelica/src/org/simantics/modelica/reader/ResultFileReader.java @@ -0,0 +1,42 @@ +package org.simantics.modelica.reader; + +import java.io.IOException; +import java.util.List; + +public interface ResultFileReader { + + /** + * List items in the file. + * @return + */ + public List getNames(); + + /** + * Return number of samples. + * @param item + * @return + */ + public int getCount(String item); + + /** + * Reads all data of a given item + * @param item + * @return + * @throws IOException + */ + public double[] readData(String item) throws IOException; + public double[][] readData(List items) throws IOException; + + /** + * Reads data of a given item + * @param item name of a item. + * @param start index of starting sample. + * @param count number of samples to read. + * @param skip number of samples to skip. 0 : all data is read. 1: every second sample is read. + * @return + * @throws IOException + */ + public double[] readData(String item, int start, int count, int skip) throws IOException; + public double[][] readData(List items, int start, int count, int skip) throws IOException; + +} diff --git a/dev-jkauttio/org.simantics.objmap/.classpath b/dev-jkauttio/org.simantics.objmap/.classpath new file mode 100644 index 00000000..23e107f9 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/dev-jkauttio/org.simantics.objmap/.hgignore b/dev-jkauttio/org.simantics.objmap/.hgignore new file mode 100644 index 00000000..73df90f6 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/.hgignore @@ -0,0 +1,5 @@ +syntax: regexp +^bin/ + +syntax: glob +*.svn/* \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.objmap/.project b/dev-jkauttio/org.simantics.objmap/.project new file mode 100644 index 00000000..82c191c2 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/.project @@ -0,0 +1,28 @@ + + + org.simantics.objmap + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.objmap/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.objmap/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..fc058b8d --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Wed Nov 11 10:38:27 EET 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.objmap/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.objmap/META-INF/MANIFEST.MF new file mode 100644 index 00000000..2b3664f7 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Objmap +Bundle-SymbolicName: org.simantics.objmap +Bundle-Version: 0.1.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Require-Bundle: gnu.trove2;bundle-version="2.0.4", + org.apache.log4j;bundle-version="1.2.15", + org.simantics.layer0;bundle-version="1.0.0", + org.simantics.db.common;bundle-version="1.1.0" +Export-Package: org.simantics.objmap, + org.simantics.objmap.annotations, + org.simantics.objmap.annotations.meta, + org.simantics.objmap.rules, + org.simantics.objmap.rules.adapters, + org.simantics.objmap.rules.domain, + org.simantics.objmap.rules.factory, + org.simantics.objmap.rules.range, + org.simantics.objmap.schema +Bundle-Vendor: VTT Technical Research Centre of Finland diff --git a/dev-jkauttio/org.simantics.objmap/build.properties b/dev-jkauttio/org.simantics.objmap/build.properties new file mode 100644 index 00000000..de6a2f5c --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/build.properties @@ -0,0 +1,17 @@ +############################################################################### +# Copyright (c) 2007, 2010 Association for Decentralized Information Management +# in Industry THTH ry. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# VTT Technical Research Centre of Finland - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . +src.includes = doc/,\ + examples/ diff --git a/dev-jkauttio/org.simantics.objmap/doc/bidirectionalModel.graphml b/dev-jkauttio/org.simantics.objmap/doc/bidirectionalModel.graphml new file mode 100644 index 00000000..2a52aa11 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/doc/bidirectionalModel.graphml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + Intermediate model + + + + + + + + + + + + Database + + + + + + + + + + + + Editor + + + + + + + + + + + + + reads + + + + + + + + + + + + + visualizes + + + + + + + + + + + + + modifies + + + + + + + + + + + + + writes + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.objmap/doc/bidirectionalModel.png b/dev-jkauttio/org.simantics.objmap/doc/bidirectionalModel.png new file mode 100644 index 00000000..77bcc302 Binary files /dev/null and b/dev-jkauttio/org.simantics.objmap/doc/bidirectionalModel.png differ diff --git a/dev-jkauttio/org.simantics.objmap/doc/main.mediawiki b/dev-jkauttio/org.simantics.objmap/doc/main.mediawiki new file mode 100644 index 00000000..97c2fb31 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/doc/main.mediawiki @@ -0,0 +1,26 @@ +'''org.simantics.objmap''' is a framework for bidirectional synchronization between Simantics database and Java objects. + +See [[org.simantics.template_Manual|Manual]] for details. + += Dependencies= + +* [[org.simantics.db]] +* gnu.trove2 + +There is a plan to split the plugin into two plugins such that the other will be database-independent and contain all annotations. + +=Download= + +{| style="background-color: #e9e9e9; border: 1px solid #aaaaaa; width: 75%;" +| '''Version''' +| '''Date''' +| '''Download''' +|- style="background-color: #f9f9f9; " | +| 0.1.0 +| 12.11.2009 +| [[Media:org.simantics.objmap-0.1.0.zip|org.simantics.objmap-0.1.0.zip]] +|} + +=Current Development= +The current version is released mostly for comments and is not yet ready for deployment. The development plan is at the end of the [[org.simantics.objmap_Manual#TODO|manual]]. + diff --git a/dev-jkauttio/org.simantics.objmap/doc/manual.mediawiki b/dev-jkauttio/org.simantics.objmap/doc/manual.mediawiki new file mode 100644 index 00000000..c3bab964 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/doc/manual.mediawiki @@ -0,0 +1,167 @@ += Introduction = + +When implementing an editor in Simantics platform, it is very common that the graph representation cannot be directly used, but the editor needs to create an intermediate model of the subgraph it edits. Some reasons for this: +* Accessing the database directly is not fast enough. +* An editor using the database directly holds frequently long read locks and cannot operate during write transactions. +* The editor needs to store auxiliary objects attached to the model. +* Editor modifies the intermediate model speculatively before the modification is committed to the database or canceled. +* The modifications in database cannot be applied in the editor immediately (for example during rendering). +* Third-party component requires certain classes to be used. +* Editor needs to be backend agnostic and cannot directly use database api. + +There are two different approaches for implementing the intermediate model: +; Triangle model +: The editor modifies the database directly and the changes in the database are eventually propagated to the intermediate model. The editor doesn't change the intermediate model directly. +[[Image:triangleModel.png]] +; Bidirectional model +: The editor operates only using the intermediate model and modifications are updated from intermediate model to the database and vice versa. +[[Image:bidirectionalModel.png]] + +By experience, the triangle model is easier to implement correctly in particular when resources are linked to each other in complex fashion. The org.simantics.objmap-plugin tries to make the implementation of bidirectional model easier by providing a framework for defining declaratively the update procedure between database and intermediate model. It can also be used with triangle model only for one direction or with hybrid model where some operations are implemented using the intermediate model and other modifying the database directly. + += Design principles = + +; Symmetric +: For every operation from database to Java objects there is a corresponding operation from Java objects to database. This makes the framework easier to learn and undestand. +; Non-intrusive +: The Java objects used with the framework do not need to implement any specific interface or follow some specific naming convention. The mapping schema can be defined using annotations or separately from the class definition. +; Support for different use scenarios +:* bidirectional / unidirectional +:* one shot / continuous +:* automatic listening / manual updating +; One-to-one +: For every resource there is a single corresponding Java object and vise versa. This makes the framework easier to understand. It is not a transformation framework. + += Concepts = + +''Mapping'' consists of a set of resources called a ''domain'', a set of Java objects called a ''range'' and a collection of ''links''. Each link is attached to exactly one domain and range element and each domain and range element has at most one link attached to it. Additionally the link has a ''link type'' that contains requirements for the domain and range elements in the same link. + +[[Image:objectMappingTerminology.png]] + +A mapping is ''up-to-date'' if every domain and range element has a link and all links satisfy the requirements of their link types. The links of up-to-date mapping form a bijection from domain to range. + +A ''mapping schema'' associates all domain and range elements with a link type. It is used to add new domain and range elements to the mapping. + += Mapping interface = + +The plugin represents a mapping with interface org.simantics.objmap.IMapping. The interface is symmetric in the sense that every operation on the domain of the mapping has also a counterpart that operates on the range. Typically, if one of the operations requires a read graph, its counterpart requires a write graph. We will describe only the methods operating on the domain of the mapping: + + Set getDomain(); + +Returns the domain of the mapping. All set operations are supported. Adding a new domain element does not automatically create a link to it. Removal of a domain element removes also a link and the target element, but does not remove the element from the database. + + Collection updateDomain(WriteGraph g) throws MappingException; + +Updates all domain elements whose counterpart is modified and creates new domain elements for previously added range elements. Returns the collection of domain elements that were modified or created in the update process. + + Object get(Resource domainElement); + +Returns the counterpart of a domain element or null if the element does not belong to the domain or does not have a link. + + Object map(ReadGraph g, Resource domainElement) throws MappingException; + +A convenience method that adds a domain element to the mapping and immediately updates the mapping and returns the corresponding range element. + + void domainModified(Resource domainElement); + +Tells the mapping that the domain element has been modified. + + boolean isDomainModified(); + +Tells if some domain elements have been modified or added. + + Collection getConflictingDomainElements(); + +Returns a collection of domain elements which have been modified and also their counterparts in the mapping are modified. These elements are in conflict in the sense that the updating domain and range in different orders may produce different results. + + void addMappingListener(IMappingListener listener); + void removeMappingListener(IMappingListener listener); + +Adds or removes a listener for domain and range modifications. + += Defining a mapping schema = + +The primary way for defining a mapping schema is to use Java annotations. The current annotation support is still lacking. Only the following annotations are supported: +; GraphType(uri) +: Specifies the domain type that the class corresponds to. +; RelatedValue(uri) +: Specifies a correspondence between a field and functional property. +; RelatedElement(uri) +: Specifies a correspondence between a field and functional relation +; RelatedElements(uri) +: Specifies a correspondence between a field and a relation. The type of the field has to be a collection. + +== Example == + +Suppose we have the following annotated classes: + @GraphType("http://www.simantics.org/Sysdyn#Configuration") + static class Configuration { + @RelatedElements("http://www.vtt.fi/Simantics/Layer0/1.0/Relations#ConsistsOf") + Collection components; + } + + static abstract class Component { + } + + @GraphType("http://www.simantics.org/Sysdyn#Dependency") + static class Dependency extends Component { + @RelatedElement("http://www.simantics.org/Sysdyn#HasTail") + Variable tail; + @RelatedElement("http://www.simantics.org/Sysdyn#HasHead") + Auxiliary head; + } + + static abstract class Variable extends Component { + @RelatedValue("http://www.vtt.fi/Simantics/Layer0/1.0/Relations#HasName") + String name; + } + + @GraphType("http://www.simantics.org/Sysdyn#Auxiliary") + static class Auxiliary extends Variable { + } + +Them the schema can be defined as follows: + SimpleSchema schema = new SimpleSchema(); + schema.addLinkType(MappingSchemas.fromAnnotations(g, Configuration.class)); + schema.addLinkType(MappingSchemas.fromAnnotations(g, Dependency.class)); + schema.addLinkType(MappingSchemas.fromAnnotations(g, Auxiliary.class)); + += Using the mapping interface = + +Assume that a mapping scheme scheme has already been defined and modelRoot is the root resource of the model that the editor edits. Then the model is created as follows: + IMapping mapping = Mappings.create(scheme); + in read transaction { + MyModel model = (MyModel)mapping.map(graph, modelRoot); + } + +There are different ways how the mapping can be updated. The following code forces update for all domain elements. + in read transaction { + for(Resource r : mapping.getDomain()) + mapping.domainModified(r); + mapping.updateRange(graph); + } + +If the range elements have some kind of "dirty" flags, the update can be optimized: + in write transaction { + for(Object obj : mapping.getRange()) + if(obj implements MyObject && ((MyObject)obj).isDirty()) + mapping.rangeModified(obj); + mapping.updateDomain(graph); + } + +Often the editor has to update some auxiliary structures when the mapping modifies the range. This can be implemented for example as: + for(Object obj : mapping.updateRange(graph)) + if(obj implements MyObject) + ((MyObject)obj).updateAuxiliary(); + +The most convenient way for updating the target would be to add graph request listeners for each domain element in the mapping. This is not yet implemented although the current interface should support this without modifications. Currently the only way to listen the database changes is to listen the request that is used to call the updateRange-method. + += Development plan = + +By priority: +* Automatic listening of database changes: marks domain elements modified. +* More complete annotations +* Utilizing declarations in ontologies: for example full URIs of relations are not needed because relations are declared in types. Also the validity of annotation can be checked. +* A separate plugin containing only mapping annotations so that the plugin can be used without introducing a dependency to org.simantics.db. +* Composition annotation that can be used to remove elements whose parents are removed or update elements whose parents are marked modified. +* Support for copy-paste and other extra mapping issues. diff --git a/dev-jkauttio/org.simantics.objmap/doc/objectMappingTerminology.graphml b/dev-jkauttio/org.simantics.objmap/doc/objectMappingTerminology.graphml new file mode 100644 index 00000000..c3cc6b27 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/doc/objectMappingTerminology.graphml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + mapping + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + domain element + + + + + + + + + + + link + + + + + + + + + + + range element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + link type + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.objmap/doc/objectMappingTerminology.png b/dev-jkauttio/org.simantics.objmap/doc/objectMappingTerminology.png new file mode 100644 index 00000000..e9ee1fba Binary files /dev/null and b/dev-jkauttio/org.simantics.objmap/doc/objectMappingTerminology.png differ diff --git a/dev-jkauttio/org.simantics.objmap/doc/triangleModel.graphml b/dev-jkauttio/org.simantics.objmap/doc/triangleModel.graphml new file mode 100644 index 00000000..9ab3b29f --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/doc/triangleModel.graphml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + Intermediate model + + + + + + + + + + + + Database + + + + + + + + + + + + Editor + + + + + + + + + + + reads + + + + + + + + + + + visualizes + + + + + + + + + + + modifies + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.objmap/doc/triangleModel.png b/dev-jkauttio/org.simantics.objmap/doc/triangleModel.png new file mode 100644 index 00000000..0918ef8a Binary files /dev/null and b/dev-jkauttio/org.simantics.objmap/doc/triangleModel.png differ diff --git a/dev-jkauttio/org.simantics.objmap/examples/org/simantics/objmap/examples/SysdynExample.java b/dev-jkauttio/org.simantics.objmap/examples/org/simantics/objmap/examples/SysdynExample.java new file mode 100644 index 00000000..bb6df661 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/examples/org/simantics/objmap/examples/SysdynExample.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.examples; + +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.IMappingSchema; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.objmap.schema.MappingSchemas; +import org.simantics.objmap.schema.SimpleSchema; + +public class SysdynExample { + + @GraphType("http://www.simantics.org/Sysdyn-1.1/Configuration") + static class Configuration { + @RelatedElements("http://www.simantics.org/Layer0-1.0/ConsistsOf") + Collection components; + } + + static abstract class Component { + } + + @GraphType("http://www.simantics.org/Sysdyn-1.1/Dependency") + static class Dependency extends Component { + @RelatedElement("http://www.simantics.org/Sysdyn-1.1/HasTail") + Variable tail; + @RelatedElement("http://www.simantics.org/Sysdyn-1.1/HasHead") + Auxiliary head; + } + + static abstract class Variable extends Component { + @RelatedValue("http://www.simantics.org/Layer0-1.0/HasName") + String name; + } + + @GraphType("http://www.simantics.org/Sysdyn-1.1/Auxiliary") + static class Auxiliary extends Variable { + } + + public static IMappingSchema createSchema(ReadGraph g) throws DatabaseException, InstantiationException, IllegalAccessException { + SimpleSchema schema = new SimpleSchema(); + schema.addLinkType(MappingSchemas.fromAnnotations(g, Configuration.class)); + schema.addLinkType(MappingSchemas.fromAnnotations(g, Dependency.class)); + schema.addLinkType(MappingSchemas.fromAnnotations(g, Auxiliary.class)); + return schema; + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IFunction.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IFunction.java new file mode 100644 index 00000000..8a7f9fea --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IFunction.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap; + +/** + * A generic function object that throws MappingExceptions. + * + * @author Hannu Niemistö + * + * @param Domain of the function + * @param Range of the function + */ +public interface IFunction { + R get(D element) throws MappingException; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/ILinkType.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/ILinkType.java new file mode 100644 index 00000000..91a985a5 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/ILinkType.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; + +/** + * Contains rules for how a link should be created and maintained. + * @author Hannu Niemistö + */ +public interface ILinkType extends IMappingRule { + /** + * Creates a domain element based on known range element. + */ + Resource createDomainElement(WriteGraph g, Object rangeElement) throws MappingException; + + /** + * Creates a range element based on known domain element. + */ + Object createRangeElement(ReadGraph g, Resource domainElement) throws MappingException; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMapping.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMapping.java new file mode 100644 index 00000000..bb22a3b6 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMapping.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap; + +import java.util.Collection; +import java.util.Set; + +import org.simantics.db.Disposable; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; + +/** + * A mapping consists of domain (a set of resources), range (a set of Java objects) and + * a set of links relating them. The mapping is used to propagate modifications of + * domain elements to range and vice versa. + * + * @see Manual + * + * @author Hannu Niemistö + */ +public interface IMapping extends Disposable { + + /** + * Returns the domain of the mapping. All set operations are supported. + * Adding a new domain element does not automatically create a link to it. + * Removal of a domain element removes also a link and the target element, + * but does not remove the element from the database. + */ + Set getDomain(); + + /** + * Returns the range of the mapping. All set operations are supported. + * Adding a new range element does not automatically create a link to it. + * Removal of a range element removes also a link and the domain element, + * but does not remove the domain element from the database. + */ + Set getRange(); + + /** + * Updates all domain elements whose counterpart is modified and creates new + * domain elements for previously added range elements. Returns the + * collection of domain elements that were modified or created in the update + * process. + */ + Collection updateDomain(WriteGraph g) throws MappingException; + + /** + * Updates all range elements whose counterpart is modified and creates new + * range elements for previously added domain elements. Returns the + * collection of range elements that were modified or created in the update + * process. + */ + Collection updateRange(ReadGraph g) throws MappingException; + + /** + * Returns the counterpart of a domain element or null if the element does + * not belong to the domain or does not have a link. + */ + Object get(Resource domainElement); + + /** + * Returns the counterpart of a range element or null if the element does + * not belong to the range or does not have a link. + */ + Resource inverseGet(Object rangeElement); + + /** + * A convenience method that adds a domain element to the mapping and + * immediately updates the mapping and returns the corresponding range + * element. + */ + Object map(ReadGraph g, Resource domainElement) throws MappingException; + + /** + * A convenience method that adds a range element to the mapping and + * immediately updates the mapping and returns the corresponding domain + * element. + */ + Resource inverseMap(WriteGraph g, Object rangeElement) + throws MappingException; + + /** + * Tells the mapping that the domain element has been modified. + */ + void domainModified(Resource domainElement); + + /** + * Tells the mapping that the range element has been modified. + */ + void rangeModified(Object rangeElement); + + /** + * Tells if some domain elements have been modified or added. + */ + boolean isDomainModified(); + + /** + * Tells if some range elements have been modified or added. + */ + boolean isRangeModified(); + + /** + * Returns a collection of domain elements which have been modified and also + * their counterparts in the mapping are modified. These elements are in + * conflict in the sense that the updating domain and range in different + * orders may produce different results. + */ + Collection getConflictingDomainElements(); + + /** + * Returns a collection of range elements which have been modified and also + * their counterparts in the mapping are modified. These elements are in + * conflict in the sense that the updating domain and range in different + * orders may produce different results. + */ + Collection getConflictingRangeElements(); + + /** + * Adds a listener for domain and range modifications. + */ + void addMappingListener(IMappingListener listener); + + /** + * Removes a previously added listener. + */ + void removeMappingListener(IMappingListener listener); + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMappingListener.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMappingListener.java new file mode 100644 index 00000000..b7c39700 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMappingListener.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap; + +/** + * Listens modifications in a mapping. + * @author Hannu Niemistö + */ +public interface IMappingListener { + /** + * Called when some domain element is modified or created + * and the mapping was previously up to date. + */ + void domainModified(); + + /** + * Called when some range element is modified or created + * and the mapping was previously up to date. + */ + void rangeModified(); +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMappingRule.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMappingRule.java new file mode 100644 index 00000000..75f3bb5d --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMappingRule.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; + +/** + * A rule for how domain and range elements are related to each other. + * @author Hannu Niemistö + */ +public interface IMappingRule { + /** + * Modifies the domain element so that it corresponds to the range element. + * @param g write transaction + * @param map unidirectional view of the current mapping + * @param domainElement the domain element that is updated + * @param rangeElement the range element that corresponds to the domain element + * @return true if the rule made some modifications + * @throws MappingException + */ + boolean updateDomain(WriteGraph g, IFunction map, Resource domainElement, Object rangeElement) throws MappingException; + + /** + * Modifies the range element so that it corresponds to the domain element. + * @param g read transaction + * @param map unidirectional view of the current mapping + * @param domainElement the domain element that corresponds to the range element + * @param rangeElement the range element that is updated + * @return true if the rule made some modifications + * @throws MappingException + */ + boolean updateRange(ReadGraph g, IFunction map, Resource domainElement, Object rangeElement) throws MappingException; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMappingSchema.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMappingSchema.java new file mode 100644 index 00000000..a403954c --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/IMappingSchema.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +/** + * Specifies the link types of new elements added to a mapping. + * @author Hannu Niemistö + */ +public interface IMappingSchema { + /** + * @return Link type that should be used for the element. + */ + ILinkType linkTypeOfDomainElement(ReadGraph g, Resource element) throws MappingException; + + /** + * @return Link type that should be used for the element. + */ + ILinkType linkTypeOfRangeElement(Object element) throws MappingException; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/MappingException.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/MappingException.java new file mode 100644 index 00000000..290345e7 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/MappingException.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap; + +import org.simantics.db.exception.DatabaseException; + +/** + * An exception thrown for any error during mapping methods. + * @author Hannu Niemistö + */ +public class MappingException extends DatabaseException { + + private static final long serialVersionUID = -4026122899414272427L; + + public MappingException() { + super(); + } + + public MappingException(String message, Throwable cause) { + super(message, cause); + } + + public MappingException(String message) { + super(message); + } + + public MappingException(Throwable cause) { + super(cause); + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/Mappings.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/Mappings.java new file mode 100644 index 00000000..a0153d0c --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/Mappings.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap; + +import org.simantics.objmap.impl.Mapping; +import org.simantics.objmap.impl.UnidirectionalMapping; + +/** + * Static utility methods for mappings. + * @author Hannu Niemistö + */ +public class Mappings { + private Mappings() {} + + /** + * Creates a new mapping based on the given mapping schema. + * The created mapping is not thread-safe and will not + * listen database changes automatically. + */ + public static IMapping createWithoutListening(IMappingSchema schema) { + return new Mapping(schema, false); + } + + /** + * Creates a new mapping based on the given mapping schema. + * The created mapping is not thread-safe. It listens database + * changes automatically. + */ + public static IMapping createWithListening(IMappingSchema schema) { + return new Mapping(schema, true); + } + + /** + * Creates a mapping that supports only the direction from domain to range. + * Does not listen the database. + */ + public static IMapping createUnidirectional(IMappingSchema schema) { + return new UnidirectionalMapping(schema); + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/Composition.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/Composition.java new file mode 100644 index 00000000..e260c948 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/Composition.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD,ElementType.METHOD}) +public @interface Composition { +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/GraphType.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/GraphType.java new file mode 100644 index 00000000..532539b9 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/GraphType.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Specifies the domain type that the class corresponds to. + * @author Hannu Niemistö + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface GraphType { + String value(); +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/OptionalRelatedElements.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/OptionalRelatedElements.java new file mode 100644 index 00000000..da747929 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/OptionalRelatedElements.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.annotations.factories.OptionalRelatedElementsRuleFactory; +import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@HasFieldRuleFactory(OptionalRelatedElementsRuleFactory.class) +public @interface OptionalRelatedElements { + String value(); + boolean composition() default false; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedElement.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedElement.java new file mode 100644 index 00000000..901db265 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedElement.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.annotations.factories.RelatedElementRuleFactory; +import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@HasFieldRuleFactory(RelatedElementRuleFactory.class) +public @interface RelatedElement { + String value(); +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedElements.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedElements.java new file mode 100644 index 00000000..d7e68859 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedElements.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.annotations.factories.RelatedElementsRuleFactory; +import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@HasFieldRuleFactory(RelatedElementsRuleFactory.class) +public @interface RelatedElements { + String value(); + boolean composition() default false; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedListElements.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedListElements.java new file mode 100644 index 00000000..0c38770b --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedListElements.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.annotations.factories.RelatedListElementsRuleFactory; +import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@HasFieldRuleFactory(RelatedListElementsRuleFactory.class) +public @interface RelatedListElements { + String value(); +} + diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedOrderedSetElements.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedOrderedSetElements.java new file mode 100644 index 00000000..21b3e171 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedOrderedSetElements.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.annotations.factories.RelatedOrderedSetElementsRuleFactory; +import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@HasFieldRuleFactory(RelatedOrderedSetElementsRuleFactory.class) +public @interface RelatedOrderedSetElements { + boolean composition() default false; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedValue.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedValue.java new file mode 100644 index 00000000..23d3e9a8 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/RelatedValue.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.annotations.factories.RelatedValueRuleFactory; +import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; +import org.simantics.objmap.rules.adapters.IdentityAdapter; +import org.simantics.objmap.rules.adapters.ValueAdapter; + +/** + * Specifies a correspondence between a field and + * functional property. + * @author Hannu Niemistö + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@HasFieldRuleFactory(RelatedValueRuleFactory.class) +public @interface RelatedValue { + String value(); + Class adapter() default IdentityAdapter.class; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/UpdateMethod.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/UpdateMethod.java new file mode 100644 index 00000000..f8431f52 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/UpdateMethod.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.annotations.factories.UpdateMethodFactory; +import org.simantics.objmap.annotations.meta.HasMethodRuleFactory; + +/** + * Specifies that the annotated method should be called + * to update range object. + * @author Hannu Niemistö + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@HasMethodRuleFactory(UpdateMethodFactory.class) +public @interface UpdateMethod { +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/DataTypeUtils.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/DataTypeUtils.java new file mode 100644 index 00000000..97cbf184 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/DataTypeUtils.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.factories; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.layer0.Layer0; + +public class DataTypeUtils { + + public static Resource dataTypeOfClass(ReadGraph g, Class clazz) { + Layer0 b = Layer0.getInstance(g); + if(clazz.equals(Double.class) || clazz.equals(double.class)) + return b.Double; + else if(clazz.equals(String.class)) + return b.String; + else if(clazz.equals(Integer.class) || clazz.equals(int.class)) + return b.Integer; + else if(clazz.equals(Float.class) || clazz.equals(float.class)) + return b.Float; + else if(clazz.equals(Boolean.class) || clazz.equals(boolean.class)) + return b.Boolean; + else if(clazz.equals(Long.class) || clazz.equals(long.class)) + return b.Long; + else if(clazz.equals(Byte.class) || clazz.equals(byte.class)) + return b.Byte; + + else if(clazz.equals(double[].class)) + return b.DoubleArray; + else if(clazz.equals(int[].class)) + return b.IntegerArray; + else if(clazz.equals(byte[].class)) + return b.ByteArray; + else if(clazz.equals(float[].class)) + return b.FloatArray; + else if(clazz.equals(boolean[].class)) + return b.BooleanArray; + else if(clazz.equals(String[].class)) + return b.StringArray; + else if(clazz.equals(long[].class)) + return b.LongArray; + else { + System.out.println("Couldn't find a data type for " + clazz); + return null; + } + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/OptionalRelatedElementsRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/OptionalRelatedElementsRuleFactory.java new file mode 100644 index 00000000..e1974fec --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/OptionalRelatedElementsRuleFactory.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.factories; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.Collections; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.exception.ValidationException; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.annotations.OptionalRelatedElements; +import org.simantics.objmap.rules.MappedElementsRule; +import org.simantics.objmap.rules.domain.RelatedObjectsAccessor; +import org.simantics.objmap.rules.factory.IFieldRuleFactory; +import org.simantics.objmap.rules.range.FieldAccessorWithDefault; + +public class OptionalRelatedElementsRuleFactory implements IFieldRuleFactory { + + @Override + public IMappingRule create(ReadGraph g, Annotation _annotation, Field field) throws ResourceNotFoundException, ValidationException, ServiceException { + OptionalRelatedElements annotation = (OptionalRelatedElements)_annotation; + return new MappedElementsRule( + new RelatedObjectsAccessor(g.getResource(annotation.value()), + annotation.composition()), + new FieldAccessorWithDefault>(field, Collections.emptyList()) + ); + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedElementRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedElementRuleFactory.java new file mode 100644 index 00000000..6d128eac --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedElementRuleFactory.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.factories; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.exception.ValidationException; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.rules.MappedElementRule; +import org.simantics.objmap.rules.domain.RelatedObjectAccessor; +import org.simantics.objmap.rules.factory.IFieldRuleFactory; +import org.simantics.objmap.rules.range.FieldAccessor; + +public class RelatedElementRuleFactory implements IFieldRuleFactory { + + @Override + public IMappingRule create(ReadGraph g, Annotation _annotation, Field field) throws ResourceNotFoundException, ValidationException, ServiceException { + RelatedElement annotation = (RelatedElement)_annotation; + return new MappedElementRule( + new RelatedObjectAccessor(g.getResource(annotation.value())), + new FieldAccessor(field) + ); + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedElementsRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedElementsRuleFactory.java new file mode 100644 index 00000000..44127853 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedElementsRuleFactory.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.factories; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.exception.ValidationException; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.objmap.rules.MappedElementsRule; +import org.simantics.objmap.rules.domain.RelatedObjectsAccessor; +import org.simantics.objmap.rules.factory.IFieldRuleFactory; +import org.simantics.objmap.rules.range.FieldAccessor; + +public class RelatedElementsRuleFactory implements IFieldRuleFactory { + + @Override + public IMappingRule create(ReadGraph g, Annotation _annotation, Field field) throws ResourceNotFoundException, ValidationException, ServiceException { + RelatedElements annotation = (RelatedElements)_annotation; + return new MappedElementsRule( + new RelatedObjectsAccessor(g.getResource(annotation.value()), + annotation.composition()), + new FieldAccessor>(field) + ); + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedListElementsRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedListElementsRuleFactory.java new file mode 100644 index 00000000..eff53549 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedListElementsRuleFactory.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.factories; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.exception.ValidationException; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.annotations.RelatedListElements; +import org.simantics.objmap.rules.MappedElementsRule; +import org.simantics.objmap.rules.domain.RelatedListElementsAccessor; +import org.simantics.objmap.rules.factory.IFieldRuleFactory; +import org.simantics.objmap.rules.range.FieldAccessor; + +public class RelatedListElementsRuleFactory implements IFieldRuleFactory { + + @Override + public IMappingRule create(ReadGraph g, Annotation _annotation, Field field) throws ResourceNotFoundException, ValidationException, ServiceException { + RelatedListElements annotation = (RelatedListElements)_annotation; + return new MappedElementsRule( + new RelatedListElementsAccessor(g.getResource(annotation.value())), + new FieldAccessor>(field) + ); + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedOrderedSetElementsRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedOrderedSetElementsRuleFactory.java new file mode 100644 index 00000000..fb78847e --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedOrderedSetElementsRuleFactory.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.factories; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.exception.ValidationException; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.annotations.RelatedOrderedSetElements; +import org.simantics.objmap.rules.MappedElementsRule; +import org.simantics.objmap.rules.domain.RelatedOrderedSetElementsAccessor; +import org.simantics.objmap.rules.factory.IFieldRuleFactory; +import org.simantics.objmap.rules.range.FieldAccessor; + +public class RelatedOrderedSetElementsRuleFactory implements IFieldRuleFactory { + + @Override + public IMappingRule create(ReadGraph g, Annotation _annotation, Field field) throws ResourceNotFoundException, ValidationException, ServiceException { + RelatedOrderedSetElements annotation = (RelatedOrderedSetElements)_annotation; + return new MappedElementsRule( + new RelatedOrderedSetElementsAccessor(annotation.composition()), + new FieldAccessor>(field) + ); + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedValueRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedValueRuleFactory.java new file mode 100644 index 00000000..828bb59f --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/RelatedValueRuleFactory.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.factories; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.exception.ValidationException; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.objmap.rules.ValueRule; +import org.simantics.objmap.rules.adapters.IdentityAdapter; +import org.simantics.objmap.rules.adapters.ValueAdapter; +import org.simantics.objmap.rules.domain.RelatedValueAccessor; +import org.simantics.objmap.rules.factory.IFieldRuleFactory; +import org.simantics.objmap.rules.range.AdaptedRangeAccessor; +import org.simantics.objmap.rules.range.FieldAccessor; +import org.simantics.objmap.rules.range.IRangeAccessor; + +public class RelatedValueRuleFactory implements IFieldRuleFactory { + + @Override + public IMappingRule create(ReadGraph g, Annotation _annotation, Field field) throws ResourceNotFoundException, + ValidationException, ServiceException { + RelatedValue annotation = (RelatedValue) _annotation; + Class adapterClass = annotation.adapter(); + IRangeAccessor rangeAccessor = new FieldAccessor(field); + Resource valueType; + if (adapterClass == IdentityAdapter.class) { + valueType = DataTypeUtils.dataTypeOfClass(g, field.getType()); + } else { + try { + ValueAdapter adapter = adapterClass.newInstance(); + rangeAccessor = new AdaptedRangeAccessor(rangeAccessor, adapter); + valueType = adapter.rangeTypeToDomainType(g, field.getType()); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + return new ValueRule(new RelatedValueAccessor(g.getResource(annotation.value()), valueType), rangeAccessor); + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/UpdateMethodFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/UpdateMethodFactory.java new file mode 100644 index 00000000..5cab576f --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/factories/UpdateMethodFactory.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.factories; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.IFunction; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.MappingException; +import org.simantics.objmap.rules.factory.IMethodRuleFactory; + +public class UpdateMethodFactory implements IMethodRuleFactory { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + @Override + public IMappingRule create(ReadGraph g, + Annotation annotation, + final Method method) + throws DatabaseException { + method.setAccessible(true); + return new IMappingRule() { + + @Override + public boolean updateRange(ReadGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + LOGGER.info(" UpdateMethodFactory.updateRange"); + try { + return (Boolean)method.invoke(rangeElement, g, domainElement); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return false; + } + + @Override + public boolean updateDomain(WriteGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + return false; + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/meta/HasClassRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/meta/HasClassRuleFactory.java new file mode 100644 index 00000000..304c8e2f --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/meta/HasClassRuleFactory.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.meta; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.rules.factory.IClassRuleFactory; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) +public @interface HasClassRuleFactory { + Class value(); +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/meta/HasFieldRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/meta/HasFieldRuleFactory.java new file mode 100644 index 00000000..877606af --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/meta/HasFieldRuleFactory.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.meta; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.rules.factory.IFieldRuleFactory; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) +public @interface HasFieldRuleFactory { + Class value(); +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/meta/HasMethodRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/meta/HasMethodRuleFactory.java new file mode 100644 index 00000000..ecdc521b --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/annotations/meta/HasMethodRuleFactory.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.annotations.meta; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.rules.factory.IMethodRuleFactory; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) +public @interface HasMethodRuleFactory { + Class value(); +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/Link.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/Link.java new file mode 100644 index 00000000..42aed779 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/Link.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +/** + * + */ +package org.simantics.objmap.impl; + +import org.simantics.db.Resource; +import org.simantics.objmap.ILinkType; + +/** + * An indication that the domain element corresponds to the range element + * in the mapping. The link type describes how source and target objects + * are updated. There are additionally flags for dirtiness of the link. + * @author Hannu Niemistö + */ +public class Link { + public ILinkType type; + public Resource domainElement; + public Object rangeElement; + + public boolean domainModified = false; + public boolean rangeModified = false; + public boolean removed = false; + + public Link(ILinkType type, Resource domainElement, Object rangeElement) { + this.type = type; + this.domainElement = domainElement; + this.rangeElement = rangeElement; + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/Mapping.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/Mapping.java new file mode 100644 index 00000000..abb726e7 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/Mapping.java @@ -0,0 +1,426 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.impl; + +import gnu.trove.THashMap; +import gnu.trove.TObjectIdentityHashingStrategy; + +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.IFunction; +import org.simantics.objmap.ILinkType; +import org.simantics.objmap.IMapping; +import org.simantics.objmap.IMappingListener; +import org.simantics.objmap.IMappingSchema; +import org.simantics.objmap.MappingException; + +/** + * An implementation of IMapping. The class should not be created + * directly but using methods in Mappings. + * @see org.simantics.objmap.Mappings + * @author Hannu Niemistö + */ +public class Mapping implements IMapping { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + private static final TObjectIdentityHashingStrategy IDENTITY_HASHING = + new TObjectIdentityHashingStrategy(); + + IMappingSchema schema; + + THashMap domain = new THashMap(); + THashMap range = new THashMap(IDENTITY_HASHING); + ArrayList listeners = new ArrayList(); + + ArrayList modifiedDomainLinks = new ArrayList(); + ArrayList modifiedRangeLinks = new ArrayList(); + boolean disposed = false; + + boolean listensDomain; + + public Mapping(IMappingSchema schema, boolean listensDomain) { + this.schema = schema; + this.listensDomain = listensDomain; + } + + private void removeLink(Link link) { + if(link.domainModified) + modifiedDomainLinks.remove(link); + if(link.rangeModified) + modifiedRangeLinks.remove(link); + link.removed = true; + } + + private void createDomain(WriteGraph g, Link link) throws MappingException { + LOGGER.info(" createDomain for " + link.rangeElement); + ILinkType type = schema.linkTypeOfRangeElement(link.rangeElement); + Resource domainElement = type.createDomainElement(g, link.rangeElement); + + link.type = type; + link.domainElement = domainElement; + domain.put(domainElement, link); + + // TODO Should we do this only if the mapping is listening? + domainModified(link); + } + + private void createRange(ReadGraph g, Link link) throws MappingException { + ILinkType type = schema.linkTypeOfDomainElement(g, link.domainElement); + Object rangeElement = type.createRangeElement(g, link.domainElement); + + link.type = type; + link.rangeElement = rangeElement; + range.put(rangeElement, link); + } + + Set domainSet = new AbstractSet() { + + public boolean add(Resource e) { + if(domain.containsKey(e)) + return false; + Link link = new Link(null, e, null); + domain.put(e, link); + modifiedDomainLinks.add(link); + return true; + } + + public boolean contains(Object o) { + return domain.contains(o); + } + + public boolean remove(Object o) { + Link link = domain.remove(o); + if(link == null) + return false; + removeLink(link); + if(link.rangeElement != null) + range.remove(link.rangeElement); + return true; + } + + @Override + public Iterator iterator() { + // FIXME does not implement Iterator.remove correctly + return domain.keySet().iterator(); + } + + @Override + public int size() { + return domain.size(); + } + + }; + + Set rangeSet = new AbstractSet() { + + public boolean add(Object e) { + if(range.containsKey(e)) + return false; + Link link = new Link(null, null, e); + range.put(e, link); + modifiedRangeLinks.add(link); + return true; + } + + public boolean contains(Object o) { + return range.contains(o); + } + + public boolean remove(Object o) { + Link link = range.remove(o); + if(link == null) + return false; + removeLink(link); + if(link.domainElement != null) + domain.remove(link.domainElement); + return true; + } + + @Override + public Iterator iterator() { + // FIXME does not implement Iterator.remove correctly + return range.keySet().iterator(); + } + + @Override + public int size() { + return range.size(); + } + + }; + + class DomainToRange implements IFunction { + + ReadGraph g; + + public DomainToRange(ReadGraph g) { + this.g = g; + } + + @Override + public Object get(Resource element) throws MappingException { + Link link = domain.get(element); + if(link == null) { + link = new Link(null, element, null); + link.domainModified = true; + modifiedDomainLinks.add(link); + domain.put(element, link); + createRange(g, link); + } + else if(link.type == null) + createRange(g, link); + return link.rangeElement; + } + + }; + + class RangeToDomain implements IFunction { + + WriteGraph g; + + public RangeToDomain(WriteGraph g) { + this.g = g; + } + + @Override + public Resource get(Object element) throws MappingException { + Link link = range.get(element); + if(link == null) { + link = new Link(null, null, element); + link.rangeModified = true; + modifiedRangeLinks.add(link); + range.put(element, link); + createDomain(g, link); + } + else if(link.type == null) + createDomain(g, link); + return link.domainElement; + } + + }; + + @Override + public Set getDomain() { + return domainSet; + } + + @Override + public Set getRange() { + return rangeSet; + } + + @Override + public synchronized Collection updateDomain(WriteGraph g) throws MappingException { + LOGGER.info("Mapping.updateDomain"); + RangeToDomain map = new RangeToDomain(g); + ArrayList updated = new ArrayList(); + while(!modifiedRangeLinks.isEmpty()) { + LOGGER.info(" modifiedRangeLinks.size() = " + modifiedRangeLinks.size()); + + Link link = modifiedRangeLinks.remove(modifiedRangeLinks.size()-1); + link.rangeModified = false; + /*if(link.domainModified) { + link.domainModified = false; + modifiedDomainLinks.remove(link); + }*/ + + if(link.type == null) { + createDomain(g, link); + } + + if(link.type.updateDomain(g, map, link.domainElement, link.rangeElement)) + updated.add(link.domainElement); + } + return updated; + } + + @Override + public synchronized Collection updateRange(ReadGraph g) throws MappingException { + LOGGER.info("Mapping.updateRange"); + DomainToRange map = new DomainToRange(g); + ArrayList updated = new ArrayList(); + while(!modifiedDomainLinks.isEmpty()) { + LOGGER.info(" modifiedDomainLinks.size() = " + modifiedDomainLinks.size()); + + Link link = modifiedDomainLinks.remove(modifiedDomainLinks.size()-1); + link.domainModified = false; + /*if(link.rangeModified) { + link.rangeModified = false; + modifiedRangeLinks.remove(link); + }*/ + + if(link.type == null) { + createRange(g, link); + } + + if(listensDomain) { + RangeUpdateRequest request = new RangeUpdateRequest(link, map, this); + try { + boolean modified = g.syncRequest(request, request); + if(modified) { + updated.add(link.rangeElement); + } + } catch (DatabaseException e) { + throw new MappingException(e); + } + + } + else + if(link.type.updateRange(g, map, link.domainElement, link.rangeElement)) + updated.add(link.rangeElement); + } + return updated; + } + + @Override + public Object get(Resource domainElement) { + Link link = domain.get(domainElement); + if(link == null) + return null; + return link.rangeElement; + } + + @Override + public Resource inverseGet(Object rangeElement) { + Link link = range.get(rangeElement); + if(link == null) + return null; + return link.domainElement; + } + + @Override + public Resource inverseMap(WriteGraph g, Object rangeElement) throws MappingException { + getRange().add(rangeElement); + updateDomain(g); + return inverseGet(rangeElement); + } + + @Override + public Object map(ReadGraph g, Resource domainElement) throws MappingException { + getDomain().add(domainElement); + updateRange(g); + return get(domainElement); + } + + void domainModified(Link link) { + if(!link.domainModified) { + synchronized(modifiedDomainLinks) { + LOGGER.info(" domainModified for " + link.rangeElement); + link.domainModified = true; + modifiedDomainLinks.add(link); + if(modifiedDomainLinks.size() == 1) { + for(IMappingListener listener : listeners) + listener.domainModified(); + } + } + } + } + + @Override + public void domainModified(Resource domainElement) { + Link link = domain.get(domainElement); + if(link != null) + domainModified(link); + } + + void rangeModified(Link link) { + if(!link.rangeModified) { + synchronized(modifiedRangeLinks) { + link.rangeModified = true; + modifiedRangeLinks.add(link); + if(modifiedRangeLinks.size() == 1) { + for(IMappingListener listener : listeners) + listener.rangeModified(); + } + } + } + } + + @Override + public void rangeModified(Object rangeElement) { + Link link = range.get(rangeElement); + if(link != null) + rangeModified(link); + } + + @Override + public boolean isDomainModified() { + return !modifiedDomainLinks.isEmpty(); + } + + @Override + public boolean isRangeModified() { + return !modifiedRangeLinks.isEmpty(); + } + + @Override + public void addMappingListener(IMappingListener listener) { + listeners.add(listener); + } + + @Override + public void removeMappingListener(IMappingListener listener) { + listeners.remove(listener); + } + + @Override + public Collection getConflictingDomainElements() { + ArrayList result = new ArrayList(); + if(modifiedDomainLinks.size() < modifiedRangeLinks.size()) { + for(Link link : modifiedDomainLinks) + if(link.rangeModified) + result.add(link.domainElement); + } + else { + for(Link link : modifiedRangeLinks) + if(link.domainModified) + result.add(link.domainElement); + } + return result; + } + + @Override + public Collection getConflictingRangeElements() { + ArrayList result = new ArrayList(); + if(modifiedDomainLinks.size() < modifiedRangeLinks.size()) { + for(Link link : modifiedDomainLinks) + if(link.rangeModified) + result.add(link.rangeElement); + } + else { + for(Link link : modifiedRangeLinks) + if(link.domainModified) + result.add(link.rangeElement); + } + return result; + } + + @Override + public void dispose() { + disposed = true; + } + + public boolean isDisposed() { + return disposed; + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/RangeUpdateRequest.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/RangeUpdateRequest.java new file mode 100644 index 00000000..4c190658 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/RangeUpdateRequest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.impl; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.SyncListener; +import org.simantics.db.request.Read; +import org.simantics.objmap.IFunction; +import org.simantics.objmap.MappingException; + +public class RangeUpdateRequest implements Read, SyncListener { + + Link link; + /* + * Note that this map uses a read request that it has got from caller and + * not the one that is used in updateRange. This is intentional. + */ + IFunction map; // map==null is used to flag that request is performed once + Mapping mapping; // mapping==null is used as a flag the request disposed + + public RangeUpdateRequest(Link link, IFunction map, Mapping mapping) { + this.link = link; + this.map = map; + this.mapping = mapping; + } + + @Override + public Boolean perform(ReadGraph g) throws DatabaseException { + if(map != null) { + boolean updated = link.type.updateRange(g, map, link.domainElement, link.rangeElement); + map = null; + return updated; + } + else if(mapping != null) { + mapping.domainModified(link); + mapping = null; + return Boolean.FALSE; + } + else + return null; + } + + @Override + public void exception(ReadGraph graph, Throwable throwable) + throws DatabaseException { + if(throwable instanceof DatabaseException) + throw (DatabaseException)throwable; + else + throw new MappingException(throwable); + } + + @Override + public void execute(ReadGraph graph, Boolean result) + throws DatabaseException { + } + + @Override + public boolean isDisposed() { + return mapping == null || link.removed || mapping.isDisposed(); + } + + + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/UnidirectionalMapping.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/UnidirectionalMapping.java new file mode 100644 index 00000000..fd41f405 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/impl/UnidirectionalMapping.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.impl; + +import gnu.trove.THashMap; +import gnu.trove.TObjectIdentityHashingStrategy; + +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.objmap.IFunction; +import org.simantics.objmap.ILinkType; +import org.simantics.objmap.IMapping; +import org.simantics.objmap.IMappingListener; +import org.simantics.objmap.IMappingSchema; +import org.simantics.objmap.MappingException; + +/** + * An implementation of IMapping. The class should not be created + * directly but using methods in Mappings. + * @see org.simantics.objmap.Mappings + * @author Hannu Niemistö + */ +public class UnidirectionalMapping implements IMapping { + + private static final TObjectIdentityHashingStrategy IDENTITY_HASHING = + new TObjectIdentityHashingStrategy(); + + IMappingSchema schema; + + THashMap domain = new THashMap(); + ArrayList listeners = new ArrayList(); + + ArrayList modifiedDomainLinks = new ArrayList(); + boolean disposed = false; + + public UnidirectionalMapping(IMappingSchema schema) { + this.schema = schema; + } + + private void removeLink(Link link) { + if(link.domainModified) + modifiedDomainLinks.remove(link); + link.removed = true; + } + + private void createDomain(WriteGraph g, Link link) throws MappingException { + ILinkType type = schema.linkTypeOfRangeElement(link.rangeElement); + Resource domainElement = type.createDomainElement(g, link.rangeElement); + + link.type = type; + link.domainElement = domainElement; + domain.put(domainElement, link); + } + + private void createRange(ReadGraph g, Link link) throws MappingException { + ILinkType type = schema.linkTypeOfDomainElement(g, link.domainElement); + Object rangeElement = type.createRangeElement(g, link.domainElement); + + link.type = type; + link.rangeElement = rangeElement; + } + + Set domainSet = new AbstractSet() { + + public boolean add(Resource e) { + if(domain.containsKey(e)) + return false; + Link link = new Link(null, e, null); + domain.put(e, link); + modifiedDomainLinks.add(link); + return true; + } + + public boolean contains(Object o) { + return domain.contains(o); + } + + public boolean remove(Object o) { + Link link = domain.remove(o); + if(link == null) + return false; + removeLink(link); + return true; + } + + @Override + public Iterator iterator() { + // FIXME does not implement Iterator.remove correctly + return domain.keySet().iterator(); + } + + @Override + public int size() { + return domain.size(); + } + + }; + + class DomainToRange implements IFunction { + + ReadGraph g; + + public DomainToRange(ReadGraph g) { + this.g = g; + } + + @Override + public Object get(Resource element) throws MappingException { + Link link = domain.get(element); + if(link == null) { + ILinkType type = schema.linkTypeOfDomainElement(g, element); + Object rangeElement = type.createRangeElement(g, element); + + link = new Link(type, element, rangeElement); + domain.put(element, link); + link.domainModified = true; + modifiedDomainLinks.add(link); + + return rangeElement; + } + else { + if(link.type == null) + createRange(g, link); + return link.rangeElement; + } + } + + }; + + @Override + public Set getDomain() { + return domainSet; + } + + @Override + public Set getRange() { + throw new UnsupportedOperationException(); + } + + @Override + public Collection updateDomain(WriteGraph g) throws MappingException { + throw new UnsupportedOperationException(); + } + + @Override + public Collection updateRange(ReadGraph g) throws MappingException { + DomainToRange map = new DomainToRange(g); + ArrayList updated = new ArrayList(); + while(!modifiedDomainLinks.isEmpty()) { + Link link = modifiedDomainLinks.remove(modifiedDomainLinks.size()-1); + link.domainModified = false; + if(link.type == null) { + createRange(g, link); + } + + link.type.updateRange(g, map, link.domainElement, link.rangeElement); + updated.add(link.rangeElement); + } + return updated; + } + + @Override + public Object get(Resource domainElement) { + Link link = domain.get(domainElement); + if(link == null) + return null; + return link.rangeElement; + } + + @Override + public Resource inverseGet(Object rangeElement) { + throw new UnsupportedOperationException(); + } + + @Override + public Resource inverseMap(WriteGraph g, Object rangeElement) throws MappingException { + throw new UnsupportedOperationException(); + } + + @Override + public Object map(ReadGraph g, Resource domainElement) throws MappingException { + getDomain().add(domainElement); + updateRange(g); + return get(domainElement); + } + + void domainModified(Link link) { + if(!link.domainModified) { + link.domainModified = true; + modifiedDomainLinks.add(link); + if(modifiedDomainLinks.size() == 1) { + for(IMappingListener listener : listeners) + listener.domainModified(); + } + } + } + + @Override + public void domainModified(Resource domainElement) { + Link link = domain.get(domainElement); + if(link != null) + domainModified(link); + } + + @Override + public boolean isDomainModified() { + return !modifiedDomainLinks.isEmpty(); + } + + @Override + public boolean isRangeModified() { + throw new UnsupportedOperationException(); + } + + @Override + public void addMappingListener(IMappingListener listener) { + listeners.add(listener); + } + + @Override + public void removeMappingListener(IMappingListener listener) { + listeners.remove(listener); + } + + @Override + public Collection getConflictingDomainElements() { + throw new UnsupportedOperationException(); + } + + @Override + public Collection getConflictingRangeElements() { + throw new UnsupportedOperationException(); + } + + @Override + public void dispose() { + disposed = true; + } + + public boolean isDisposed() { + return disposed; + } + + @Override + public void rangeModified(Object rangeElement) { + throw new UnsupportedOperationException(); + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/MappedElementRule.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/MappedElementRule.java new file mode 100644 index 00000000..9ce33598 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/MappedElementRule.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.objmap.IFunction; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.MappingException; +import org.simantics.objmap.rules.domain.IDomainAccessor; +import org.simantics.objmap.rules.range.IRangeAccessor; + +/** + * A rule that synchronizes collection of elements between + * domain and range accessors. Elements are mapped from + * between domain and range during the synchronization. + * @author Hannu Niemistö + */ +public class MappedElementRule implements IMappingRule { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + IDomainAccessor domainAccessor; + IRangeAccessor rangeAccessor; + + public MappedElementRule(IDomainAccessor domainAccessor, + IRangeAccessor rangeAccessor) { + this.domainAccessor = domainAccessor; + this.rangeAccessor = rangeAccessor; + } + + @Override + public boolean updateDomain(WriteGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + LOGGER.info(" MappedElementRule.updateDomain"); + Object value = rangeAccessor.get(rangeElement); + Resource mappedValue = value == null ? null : map.get(value); + return domainAccessor.set(g, domainElement, mappedValue); + } + + @Override + public boolean updateRange(ReadGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + LOGGER.info(" MappedElementRule.updateRange"); + Resource value = domainAccessor.get(g, domainElement); + Object mappedValue = value == null ? null : map.get(value); + return rangeAccessor.set(rangeElement, mappedValue); + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/MappedElementsRule.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/MappedElementsRule.java new file mode 100644 index 00000000..750926d4 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/MappedElementsRule.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.objmap.IFunction; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.MappingException; +import org.simantics.objmap.rules.domain.IDomainAccessor; +import org.simantics.objmap.rules.range.IRangeAccessor; + +/** + * A rule that synchronizes collection of elements between + * domain and range accessors. Elements are mapped from + * between domain and range during the synchronization. + * @author Hannu Niemistö + */ +public class MappedElementsRule implements IMappingRule { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + IDomainAccessor> domainAccessor; + IRangeAccessor> rangeAccessor; + + public MappedElementsRule(IDomainAccessor> domainAccessor, + IRangeAccessor> rangeAccessor) { + this.domainAccessor = domainAccessor; + this.rangeAccessor = rangeAccessor; + } + + @Override + public boolean updateDomain(WriteGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + LOGGER.info(" MappedElementsRule.updateDomain"); + // Snapshot the accessed range value for concurrency safety. + // NOTE: still assumes that the accessed collection is concurrent or + // synchronized for toArray to be atomic. + Collection value = rangeAccessor.get(rangeElement); + Object[] rangeSnapshot = value.toArray(); + ArrayList mappedValue = new ArrayList(rangeSnapshot.length); + for (Object obj : rangeSnapshot) + mappedValue.add(map.get(obj)); + return domainAccessor.set(g, domainElement, mappedValue); + } + + @Override + public boolean updateRange(ReadGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + LOGGER.info(" MappedElementsRule.updateRange"); + Collection value = domainAccessor.get(g, domainElement); + ArrayList mappedValue = new ArrayList(value.size()); + for(Resource r : value) + mappedValue.add(map.get(r)); + return rangeAccessor.set(rangeElement, mappedValue); + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/ValueRule.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/ValueRule.java new file mode 100644 index 00000000..8135d2d0 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/ValueRule.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.objmap.IFunction; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.MappingException; +import org.simantics.objmap.rules.domain.IDomainAccessor; +import org.simantics.objmap.rules.range.IRangeAccessor; + +/** + * A rule that synchronizes values between domain and + * range accessors. + * @author Hannu Niemistö + */ +public class ValueRule implements IMappingRule { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + IDomainAccessor domainAccessor; + IRangeAccessor rangeAccessor; + + public ValueRule(IDomainAccessor domainAccessor, + IRangeAccessor rangeAccessor) { + this.domainAccessor = domainAccessor; + this.rangeAccessor = rangeAccessor; + } + + @Override + public boolean updateDomain(WriteGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + LOGGER.info(" ValueRule.updateDomain"); + Object value = rangeAccessor.get(rangeElement); + return domainAccessor.set(g, domainElement, value); + } + + @Override + public boolean updateRange(ReadGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + LOGGER.info(" ValueRule.updateRange"); + Object value = domainAccessor.get(g, domainElement); + return rangeAccessor.set(rangeElement, value); + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/adapters/IdentityAdapter.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/adapters/IdentityAdapter.java new file mode 100644 index 00000000..913357b2 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/adapters/IdentityAdapter.java @@ -0,0 +1,23 @@ +package org.simantics.objmap.rules.adapters; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +public enum IdentityAdapter implements ValueAdapter { + INSTANCE; + + @Override + public Object domainToRange(Object domainValue) { + return domainValue; + } + + @Override + public Object rangeToDomain(Object rangeValue) { + return rangeValue; + } + + @Override + public Resource rangeTypeToDomainType(ReadGraph graph, Class rangeType) { + return null; + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/adapters/ValueAdapter.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/adapters/ValueAdapter.java new file mode 100644 index 00000000..85e40169 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/adapters/ValueAdapter.java @@ -0,0 +1,10 @@ +package org.simantics.objmap.rules.adapters; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; + +public interface ValueAdapter { + Resource rangeTypeToDomainType(ReadGraph graph, Class rangeType); + Object domainToRange(Object domainValue); + Object rangeToDomain(Object rangeValue); +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/IDomainAccessor.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/IDomainAccessor.java new file mode 100644 index 00000000..4dc94dd0 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/IDomainAccessor.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.domain; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.objmap.MappingException; + +/** + * Provides access to some property of domain elements. + * @author Hannu Niemistö + */ +public interface IDomainAccessor { + T get(ReadGraph g, Resource element) throws MappingException; + boolean set(WriteGraph g, Resource element, T value) throws MappingException; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/MappingUtils.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/MappingUtils.java new file mode 100644 index 00000000..927d0121 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/MappingUtils.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.domain; + +import java.util.Arrays; +import java.util.Collection; + +import org.apache.log4j.Logger; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; + +/** + * Static utility methods for rule implementations. + * @author Hannu Niemistö + */ +public class MappingUtils { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + /** + * Adds and removes statements to/from the database so that objects + * will be exactly the objects connected to subject by predicate. + * Returns true if the method made modifications to the database. + */ + public static boolean synchronizeStatements(WriteGraph g, Resource subject, Resource predicate, Resource[] objects, + boolean deleteExtraObjects) + throws DatabaseException { + Collection currentObjects0 = g.getObjects(subject, predicate); + Resource[] currentObjects = currentObjects0.toArray(new Resource[currentObjects0.size()]); + + Arrays.sort(objects); + Arrays.sort(currentObjects); + + boolean modified = false; + int i=0, j=0; + if(currentObjects.length > 0 && objects.length > 0) + while(true) { + int cmp = currentObjects[i].compareTo(objects[j]); + if(cmp < 0) { + LOGGER.info(" remove statement"); + if(deleteExtraObjects) + g.deny(currentObjects[i]); + else + g.denyStatement(subject, predicate, currentObjects[i]); + modified = true; + ++i; + if(i >= currentObjects.length) + break; + } + else if(cmp > 0) { + LOGGER.info(" add statement"); + g.claim(subject, predicate, objects[j]); + modified = true; + ++j; + if(j >= objects.length) + break; + } + else { + ++i; ++j; + if(i >= currentObjects.length) + break; + if(j >= objects.length) + break; + } + } + while(i < currentObjects.length) { + if(deleteExtraObjects) + g.deny(currentObjects[i]); + else + g.denyStatement(subject, predicate, currentObjects[i]); + modified = true; + ++i; + } + while(j < objects.length) { + g.claim(subject, predicate, objects[j]); + modified = true; + ++j; + } + return modified; + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedListElementsAccessor.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedListElementsAccessor.java new file mode 100644 index 00000000..59b544f0 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedListElementsAccessor.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.domain; + +import java.util.Collection; +import java.util.Collections; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.MappingException; + +public class RelatedListElementsAccessor implements IDomainAccessor> { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + Resource relation; + + public RelatedListElementsAccessor(Resource relation) { + super(); + this.relation = relation; + } + + @Override + public Collection get(ReadGraph g, Resource element) throws MappingException { + try { + LOGGER.info(" RelatedListElementsAccessor.get"); + Resource listResource = g.getPossibleObject(element, relation); + if(listResource != null) + return ListUtils.toList(g, listResource); + else + return Collections.emptyList(); + } catch (DatabaseException e) { + throw new MappingException(e); + } + } + + @Override + public boolean set(WriteGraph g, Resource element, Collection value) + throws MappingException { + try { + LOGGER.info(" RelatedListElementsAccessor.set"); + Resource listResource = g.getPossibleObject(element, relation); + if(listResource != null) + ListUtils.createExisting(g, listResource, value); + else { + listResource = ListUtils.create(g, value); + g.claim(element, relation, listResource); + } + + return true; + // FIXME Implement deleteExtraObjects + } catch (DatabaseException e) { + throw new MappingException(e); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedObjectAccessor.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedObjectAccessor.java new file mode 100644 index 00000000..10761d6c --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedObjectAccessor.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.domain; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.MappingException; + +/** + * Accesses a resource attached to the element by given functional relation. + * @author Hannu Niemistö + */ +public class RelatedObjectAccessor implements IDomainAccessor { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + Resource relation; + + public RelatedObjectAccessor(Resource relation) { + this.relation = relation; + } + + @Override + public Resource get(ReadGraph g, Resource element) throws MappingException { + try { + LOGGER.info(" RelatedObjectAccessor.get"); + return g.getPossibleObject(element, relation); + } catch (DatabaseException e) { + throw new MappingException(e); + } + } + + @Override + public boolean set(WriteGraph g, Resource element, Resource value) + throws MappingException { + try { + LOGGER.info(" RelatedObjectAccessor.set"); + Resource resource = g.getPossibleObject(element, relation); + if(resource == null) { + if(value == null) + return false; + g.claim(element, relation, value); + return true; + } + else if(resource.equals(value)) + return false; + else { + g.deny(element, relation); + if(value != null) + g.claim(element, relation, value); + return true; + } + } catch (DatabaseException e) { + throw new MappingException(e); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedObjectsAccessor.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedObjectsAccessor.java new file mode 100644 index 00000000..c7b6cabb --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedObjectsAccessor.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.domain; + +import java.util.Collection; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.MappingException; + +/** + * Accesses the set of objects attached to the element by the given relation. + * @author Hannu Niemistö + */ +public class RelatedObjectsAccessor implements IDomainAccessor> { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + Resource relation; + boolean deleteExtraObjects; + + public RelatedObjectsAccessor(Resource relation, boolean deleteExtraObjects) { + super(); + this.relation = relation; + this.deleteExtraObjects = deleteExtraObjects; + } + + @Override + public Collection get(ReadGraph g, Resource element) throws MappingException { + try { + LOGGER.info(" RelatedObjectsAccessor.get"); + return g.getObjects(element, relation); + } catch (DatabaseException e) { + throw new MappingException(e); + } + } + + @Override + public boolean set(WriteGraph g, Resource element, Collection value) + throws MappingException { + try { + LOGGER.info(" RelatedObjectsAccessor.set"); + return MappingUtils.synchronizeStatements(g, element, relation, + value.toArray(new Resource[value.size()]), deleteExtraObjects); + } catch (DatabaseException e) { + throw new MappingException(e); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedOrderedSetElementsAccessor.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedOrderedSetElementsAccessor.java new file mode 100644 index 00000000..35c5e3f8 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedOrderedSetElementsAccessor.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.domain; + +import java.util.Collection; +import java.util.Collections; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.MappingException; + +/** + * Accesses the set of objects attached to the element by the given relation. + * @author Hannu Niemistö + */ +public class RelatedOrderedSetElementsAccessor implements IDomainAccessor> { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + boolean deleteExtraObjects; + + public RelatedOrderedSetElementsAccessor(boolean deleteExtraObjects) { + super(); + this.deleteExtraObjects = deleteExtraObjects; + } + + @Override + public Collection get(ReadGraph g, Resource element) throws MappingException { + try { + LOGGER.info(" RelatedOrderedSetElementsAccessor.get"); + if(g.hasStatement(element)) + return OrderedSetUtils.toList(g, element); + else + return Collections.emptyList(); + } catch (DatabaseException e) { + throw new MappingException(e); + } + } + + @Override + public boolean set(WriteGraph g, Resource element, Collection value) + throws MappingException { + try { + LOGGER.info(" RelatedOrderedSetElementsAccessor.set"); + return OrderedSetUtils.set(g, element, value); + // FIXME Implement deleteExtraObjects + } catch (DatabaseException e) { + throw new MappingException(e); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedValueAccessor.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedValueAccessor.java new file mode 100644 index 00000000..4cf7ecde --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/domain/RelatedValueAccessor.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.domain; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.objmap.MappingException; + +/** + * Accesses a value attached to the element by given functional relation. + * @author Hannu Niemist� + */ +public class RelatedValueAccessor implements IDomainAccessor { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + Resource relation; + Resource valueType; + + public RelatedValueAccessor(Resource relation, Resource valueType) { + this.relation = relation; + this.valueType = valueType; + } + + @Override + public Object get(ReadGraph g, Resource element) throws MappingException { + try { + LOGGER.info(" RelatedValueAccessor.get"); + Resource valueResource = g.getPossibleObject(element, relation); + if(valueResource == null) + return null; + return g.getValue(valueResource); + } catch (DatabaseException e) { + throw new MappingException(e); + } + } + + @Override + public boolean set(WriteGraph g, Resource element, Object value) + throws MappingException { + try { + LOGGER.info(" RelatedValueAccessor.set"); + Resource valueResource = g.getPossibleObject(element, relation); + if(valueResource == null) { + if(value == null) + return false; + valueResource = g.newResource(); + g.claim(valueResource, Layer0.getInstance(g).InstanceOf, null, + valueType); + g.claim(element, relation, valueResource); + g.claimValue(valueResource, value); + return true; + } + else { + if(value == null) { + g.deny(valueResource); + return true; + } + Object currentValue = g.getValue(valueResource); + if(currentValue.equals(value)) + return false; + g.claimValue(valueResource, value); + return true; + } + } catch (DatabaseException e) { + throw new MappingException(e); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/factory/IClassRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/factory/IClassRuleFactory.java new file mode 100644 index 00000000..b9b69065 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/factory/IClassRuleFactory.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.factory; + +import java.lang.annotation.Annotation; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.IMappingRule; + +public interface IClassRuleFactory { + IMappingRule create(ReadGraph g, Annotation annotation, Class clazz) throws DatabaseException; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/factory/IFieldRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/factory/IFieldRuleFactory.java new file mode 100644 index 00000000..02688e02 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/factory/IFieldRuleFactory.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.factory; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.IMappingRule; + +public interface IFieldRuleFactory { + IMappingRule create(ReadGraph g, Annotation annotation, Field field) throws DatabaseException; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/factory/IMethodRuleFactory.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/factory/IMethodRuleFactory.java new file mode 100644 index 00000000..32bb98b7 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/factory/IMethodRuleFactory.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.factory; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.IMappingRule; + +public interface IMethodRuleFactory { + IMappingRule create(ReadGraph g, Annotation annotation, Method method) throws DatabaseException; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/AdaptedRangeAccessor.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/AdaptedRangeAccessor.java new file mode 100644 index 00000000..a6df00b0 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/AdaptedRangeAccessor.java @@ -0,0 +1,25 @@ +package org.simantics.objmap.rules.range; + +import org.simantics.objmap.MappingException; +import org.simantics.objmap.rules.adapters.ValueAdapter; + +public class AdaptedRangeAccessor implements IRangeAccessor { + IRangeAccessor baseAccessor; + ValueAdapter adapter; + + public AdaptedRangeAccessor(IRangeAccessor baseAccessror, + ValueAdapter adapter) { + this.baseAccessor = baseAccessror; + this.adapter = adapter; + } + + @Override + public Object get(Object element) throws MappingException { + return adapter.rangeToDomain(baseAccessor.get(element)); + } + + @Override + public boolean set(Object element, Object value) throws MappingException { + return baseAccessor.set(element, adapter.domainToRange(value)); + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/FieldAccessor.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/FieldAccessor.java new file mode 100644 index 00000000..e731e3e9 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/FieldAccessor.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.range; + +import java.lang.reflect.Field; + +import org.apache.log4j.Logger; +import org.simantics.objmap.MappingException; + +/** + * Accesses the given field of the element. + * @author Hannu Niemistö + */ +public class FieldAccessor implements IRangeAccessor { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + Field field; + + public FieldAccessor(Field field) { + this.field = field; + } + + @Override + public T get(Object element) throws MappingException { + try { + @SuppressWarnings("unchecked") + T result = (T)field.get(element); + + if(LOGGER.isInfoEnabled()) + LOGGER.info(" FieldAccessor.get " + + field.getName() + " -> " + result + ); + + return result; + } catch (IllegalArgumentException e) { + throw new MappingException(e); + } catch (IllegalAccessException e) { + throw new MappingException(e); + } + } + + @Override + public boolean set(Object element, T value) throws MappingException { + try { + Object currentValue = field.get(element); + + if(LOGGER.isInfoEnabled()) + LOGGER.info(" FieldAccessor.set " + + field.getName() + " " + currentValue + + " -> " + value + ); + + if(value == null + ? (currentValue == null || field.getType().isPrimitive()) + : value.equals(currentValue)) + return false; + field.set(element, value); + return true; + } catch (IllegalArgumentException e) { + throw new MappingException(e); + } catch (IllegalAccessException e) { + throw new MappingException(e); + } + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/FieldAccessorWithDefault.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/FieldAccessorWithDefault.java new file mode 100644 index 00000000..688de95c --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/FieldAccessorWithDefault.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.range; + +import java.lang.reflect.Field; + +import org.simantics.objmap.MappingException; + +/** + * Accesses the given field of the element. + * @author Hannu Niemist� + */ +public class FieldAccessorWithDefault extends FieldAccessor { + + T defaultValue; + + public FieldAccessorWithDefault(Field field, T defaultValue) { + super(field); + this.defaultValue = defaultValue; + } + + @Override + public T get(Object element) throws MappingException { + T value = super.get(element); + if(value == null) + return defaultValue; + else + return value; + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/IRangeAccessor.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/IRangeAccessor.java new file mode 100644 index 00000000..01625a1c --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/rules/range/IRangeAccessor.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.rules.range; + +import org.simantics.objmap.MappingException; + +/** + * Provides access to some property of range elements. + * @author Hannu Niemistö + */ +public interface IRangeAccessor { + T get(Object element) throws MappingException; + boolean set(Object element, T value) throws MappingException; +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/schema/MappingSchemas.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/schema/MappingSchemas.java new file mode 100644 index 00000000..09984fe6 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/schema/MappingSchemas.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.schema; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.objmap.annotations.meta.HasClassRuleFactory; +import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; +import org.simantics.objmap.annotations.meta.HasMethodRuleFactory; + +/** + * Static utility methods for mapping schemas + * @author Hannu Niemistö + */ +public class MappingSchemas { + + /** + * Creates a new SimpleLinkType based on the annotations in the given class. + * @throws IllegalAccessException + * @throws InstantiationException + * @see GraphType + * @see RelatedValue + */ + public static SimpleLinkType fromAnnotations(ReadGraph g, Class clazz) throws DatabaseException, InstantiationException, IllegalAccessException { + GraphType graphType = clazz.getAnnotation(GraphType.class); + + ArrayList rules = new ArrayList(); + collectRulesFromAnnotations(g, clazz, rules); + + return new SimpleLinkType( + g.getResource(graphType.value()), + clazz, rules); + } + + public static void collectRulesFromAnnotations(ReadGraph g, Class clazz, Collection rules) throws DatabaseException, InstantiationException, IllegalAccessException { + Class superclass = clazz.getSuperclass(); + if(superclass != null) + collectRulesFromAnnotations(g, superclass, rules); + + for(Annotation annotation : clazz.getAnnotations()) { + HasClassRuleFactory factory = + annotation.annotationType().getAnnotation(HasClassRuleFactory.class); + if(factory != null) { + rules.add(factory.value().newInstance() + .create(g, annotation, clazz)); + } + } + + for(Field f : clazz.getDeclaredFields()) { + f.setAccessible(true); + + for(Annotation annotation : f.getAnnotations()) { + HasFieldRuleFactory factory = + annotation.annotationType().getAnnotation(HasFieldRuleFactory.class); + if(factory != null) { + rules.add(factory.value().newInstance() + .create(g, annotation, f)); + } + } + } + + for(Method m : clazz.getDeclaredMethods()) { + m.setAccessible(true); + + for(Annotation annotation : m.getAnnotations()) { + HasMethodRuleFactory factory = + annotation.annotationType().getAnnotation(HasMethodRuleFactory.class); + if(factory != null) { + rules.add(factory.value().newInstance() + .create(g, annotation, m)); + } + } + } + } + +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleLinkType.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleLinkType.java new file mode 100644 index 00000000..7cbfbb3d --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleLinkType.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.schema; + +import java.util.ArrayList; + +import org.apache.log4j.Logger; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.objmap.IFunction; +import org.simantics.objmap.ILinkType; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.MappingException; + +/** + * A link type that is associated with single domain and range type (class). + * SimpleLinkType is composed of simpler rules whose combination determines + * its update policy. + * @author Hannu Niemist� + */ +public class SimpleLinkType implements ILinkType { + + static Logger LOGGER = Logger.getLogger("org.simantics.objmap"); + + public Resource domainType; + public Class rangeType; + ArrayList rules; + + public SimpleLinkType(Resource domainType, Class rangeType, + ArrayList rules) { + this.domainType = domainType; + this.rangeType = rangeType; + this.rules = rules; + } + + public SimpleLinkType(Resource domainType, Class rangeType) { + this(domainType, rangeType, new ArrayList()); + } + + /** + * Adds a new rule to this link type that is enforced + * during updates. + */ + public void addRule(IMappingRule rule) { + rules.add(rule); + } + + @Override + public Resource createDomainElement(WriteGraph g, Object rangeElement) + throws MappingException { + try { + if(LOGGER.isInfoEnabled()) + LOGGER.info("SimpleLinkType.createDomainElement " + + rangeElement.toString() + ); + Resource result = g.newResource(); + g.claim(result, Layer0.getInstance(g).InstanceOf, null, domainType); + return result; + } catch(DatabaseException e) { + throw new MappingException(e); + } + } + @Override + public Object createRangeElement(ReadGraph g, Resource domainElement) + throws MappingException { + try { + if(LOGGER.isInfoEnabled()) + try { + LOGGER.info("SimpleLinkType.createRangeElement " + + NameUtils.getSafeName(g, domainElement) + ); + } catch(DatabaseException e) { + throw new MappingException(e); + } + return rangeType.newInstance(); + } catch (InstantiationException e) { + throw new MappingException(e); + } catch (IllegalAccessException e) { + throw new MappingException(e); + } + } + @Override + public boolean updateDomain(WriteGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + if(LOGGER.isInfoEnabled()) + try { + LOGGER.info("SimpleLinkType.updateDomain " + + NameUtils.getSafeName(g, domainElement) + " " + + rangeElement.toString() + ); + } catch(DatabaseException e) { + throw new MappingException(e); + } + + boolean updated = false; + for(IMappingRule rule : rules) + updated |= rule.updateDomain(g, map, domainElement, rangeElement); + return updated; + } + @Override + public boolean updateRange(ReadGraph g, IFunction map, + Resource domainElement, Object rangeElement) + throws MappingException { + if(LOGGER.isInfoEnabled()) + try { + LOGGER.info("SimpleLinkType.updateRange " + + NameUtils.getSafeName(g, domainElement) + " " + + rangeElement.toString() + ); + } catch(DatabaseException e) { + throw new MappingException(e); + } + + boolean updated = false; + for(IMappingRule rule : rules) + updated |= rule.updateRange(g, map, domainElement, rangeElement); + return updated; + } +} diff --git a/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleSchema.java b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleSchema.java new file mode 100644 index 00000000..5c15c009 --- /dev/null +++ b/dev-jkauttio/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleSchema.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.objmap.schema; + +import gnu.trove.THashMap; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.ILinkType; +import org.simantics.objmap.IMappingSchema; +import org.simantics.objmap.MappingException; + +/** + * An implementation of IMappingSchema that contains + * only SimpleLinkTypes. The link type of any domain + * element is based solely on its type in database and + * the link type of any range element is based on its class. + * @author Hannu Niemistö + */ +public class SimpleSchema implements IMappingSchema { + + THashMap domainLinkTypes = + new THashMap(); + THashMap, SimpleLinkType> rangeLinkTypes = + new THashMap, SimpleLinkType>(); + + public void addLinkType(SimpleLinkType linkType) { + domainLinkTypes.put(linkType.domainType, linkType); + rangeLinkTypes.put(linkType.rangeType, linkType); + } + + @Override + public ILinkType linkTypeOfDomainElement(ReadGraph g, Resource element) throws MappingException { + try { + + for(Resource type : g.getTypes(element)) { + + ILinkType linkType = domainLinkTypes.get(type); + if(linkType != null) return linkType; + + } + + throw new MappingException("Didn't find a link type for " + + NameUtils.getSafeName(g, element) + "."); + + } catch (DatabaseException e) { + throw new MappingException(e); + } + } + + @Override + public ILinkType linkTypeOfRangeElement(Object element) throws MappingException { + ILinkType type = rangeLinkTypes.get(element.getClass()); + if(type == null) + throw new MappingException("Didn't find a link type for " + element + "."); + return type; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.feature/.project b/dev-jkauttio/org.simantics.sysdyn.feature/.project new file mode 100644 index 00000000..60643f3e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.feature/.project @@ -0,0 +1,17 @@ + + + org.simantics.sysdyn.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/dev-jkauttio/org.simantics.sysdyn.feature/build.properties b/dev-jkauttio/org.simantics.sysdyn.feature/build.properties new file mode 100644 index 00000000..6ec1948b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.feature/build.properties @@ -0,0 +1,16 @@ +############################################################################### +# Copyright (c) 2014 Association for Decentralized Information Management in +# Industry THTH ry. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# VTT Technical Research Centre of Finland - initial API and implementation +############################################################################### +bin.includes = feature.xml +root=rootfiles/ + +root.win32.win32.x86.folder.jre=jre/win32.x86 +root.win32.win32.x86_64.folder.jre=jre/win32.x86_64 \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.feature/feature.xml b/dev-jkauttio/org.simantics.sysdyn.feature/feature.xml new file mode 100644 index 00000000..e9e11f98 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.feature/feature.xml @@ -0,0 +1,156 @@ + + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/puzzle_green.ico b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/puzzle_green.ico new file mode 100644 index 00000000..61e3f866 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/puzzle_green.ico differ diff --git a/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Discovery And Exploitation Of Resources.tg b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Discovery And Exploitation Of Resources.tg new file mode 100644 index 00000000..c00a8865 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Discovery And Exploitation Of Resources.tg differ diff --git a/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Global Carbon Cycle.tg b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Global Carbon Cycle.tg new file mode 100644 index 00000000..cedf440a Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Global Carbon Cycle.tg differ diff --git a/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Predator And Limited Prey.tg b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Predator And Limited Prey.tg new file mode 100644 index 00000000..3a1c507a Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Predator And Limited Prey.tg differ diff --git a/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Resource Exploitation Use Recycling.tg b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Resource Exploitation Use Recycling.tg new file mode 100644 index 00000000..4c49bbb3 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Resource Exploitation Use Recycling.tg differ diff --git a/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Tourists Environments And Hotel Facilities.tg b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Tourists Environments And Hotel Facilities.tg new file mode 100644 index 00000000..1dc23316 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.feature/rootfiles/sampleModels/Tourists Environments And Hotel Facilities.tg differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/.classpath b/dev-jkauttio/org.simantics.sysdyn.ontology/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/.project b/dev-jkauttio/org.simantics.sysdyn.ontology/.project new file mode 100644 index 00000000..b975ea97 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/.project @@ -0,0 +1,34 @@ + + + org.simantics.sysdyn.ontology + + + + + + org.simantics.graph.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.simantics.graph.nature + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.sysdyn.ontology/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..888b17ed --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Thu Jul 22 15:15:41 EEST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.sysdyn.ontology/META-INF/MANIFEST.MF new file mode 100644 index 00000000..dfa33be9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/META-INF/MANIFEST.MF @@ -0,0 +1,25 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: http://www.simantics.org/Sysdyn +Bundle-SymbolicName: org.simantics.sysdyn.ontology +Bundle-Version: 1.1.0.qualifier +Require-Bundle: org.simantics.layer0, + org.simantics.diagram.ontology;bundle-version="1.0.0", + org.simantics.structural.ontology;bundle-version="1.0.0", + org.simantics.modeling.ontology;bundle-version="1.0.0", + org.simantics.g2d.ontology;bundle-version="1.0.0", + org.simantics.project.ontology;bundle-version="1.0.0", + org.simantics.viewpoint.ontology;bundle-version="1.0.0", + org.simantics.layer0x.ontology;bundle-version="1.0.0", + org.simantics.issues.ontology;bundle-version="1.1.0", + org.simantics.jfreechart.ontology;bundle-version="0.1.0", + org.simantics.action.ontology;bundle-version="1.0.0", + org.simantics.image2.ontology;bundle-version="1.1.0", + org.simantics.color.ontology;bundle-version="1.0.0", + org.simantics.simulation.ontology;bundle-version="1.0.0", + org.simantics.silk.ontology;bundle-version="1.0.0", + org.simantics.spreadsheet.ontology;bundle-version="1.1.0", + org.simantics.workbench.ontology;bundle-version="1.2.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Export-Package: org.simantics.sysdyn +Bundle-Vendor: VTT Technical Reserarch Centre of Finland diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/Sysdyn ontolgy changes.doc b/dev-jkauttio/org.simantics.sysdyn.ontology/Sysdyn ontolgy changes.doc new file mode 100644 index 00000000..2f41a3cc Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ontology/Sysdyn ontolgy changes.doc differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/build.properties b/dev-jkauttio/org.simantics.sysdyn.ontology/build.properties new file mode 100644 index 00000000..098c3fd7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/build.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2010 Association for Decentralized Information Management in +# Industry THTH ry. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# VTT Technical Research Centre of Finland - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + graphs/*.tg,\ + graph.tg +src.includes = graph/ diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/graph.tg b/dev-jkauttio/org.simantics.sysdyn.ontology/graph.tg new file mode 100644 index 00000000..8f3e514e Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ontology/graph.tg differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/graph/Charts.pgraph b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/Charts.pgraph new file mode 100644 index 00000000..533391fb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/Charts.pgraph @@ -0,0 +1,20 @@ +L0 = +VP = +JFREE = +SYSDYN = +G2D = + +CHARTS = SYSDYN.Charts : L0.Library + +CHARTS.SensitivityDataset -- CHARTS.SensitivityDataset.confidenceBounds --> L0.List -- CHARTS.SensitivityDataset.median --> L0.Boolean -- CHARTS.SensitivityDataset.ConfidenceBound.percent --> L0.Double -- CHARTS.SensitivityDataset.ConfidenceBound.color --> G2D.Color +G2D = +DIA = +SYSDYN = +IMAGE = +MOD = + +GENERAL = SYSDYN.SymbolReferences.CommentSymbols : DIA.SymbolReferenceLibrary + L0.HasDescription "General graphical components" + +SYSDYN.AdditionalSymbols : L0.Library + +SYSDYN.AdditionalSymbols.MultilineText """ : L0.String + +SYSDYN.Loop -- SYSDYN.Loop.Comment --> L0.String -- SYSDYN.Loop.Items --> L0.List -- SYSDYN.LoopSymbol.Clockwise --> L0.Boolean +SYSDYN = + +move : L0.Template + @template %subject %base %from %to + %subject : L0.NamespaceMigrationStep.Prefix + L0.NamespaceMigrationStep.Prefix.base %base + L0.NamespaceMigrationStep.Prefix.from %from + L0.NamespaceMigrationStep.Prefix.to %to + +MIGRATION = SYSDYN.Migration : L0.Library + +MIGRATION.fromModel1 : L0.Migration + L0.Migration.format "sysdynModel" + L0.Migration.from 1 + L0.Migration.step FROM16TO17 + L0.Migration.priority 1.0 + +MIGRATION.fromModule1 : L0.Migration + L0.Migration.format "sysdynModule" + L0.Migration.from 1 + L0.Migration.step FROM16TO17 + L0.Migration.priority 1.0 + +MIGRATION.fromFunctionLibrary1 : L0.Migration + L0.Migration.format "sysdynFunctionLibrary" + L0.Migration.from 1 + L0.Migration.step FROM16TO17 + L0.Migration.priority 1.0 + +FROM16TO17 = MIGRATION."from1.6to1.7" : L0.MigrationSequence + @L0.list + FROM16TO17.Ontologies + FROM16TO17.Spreadsheets + FROM16TO17.SysdynChanges + FROM16TO17.OrderedSetsToLists + +FROM16TO17.Ontologies : L0.NamespaceMigrationStep + @L0.list + _ + @move "http://www.simantics.org/Layer0-" "1.0" "1.1" + _ + @move "http://www.simantics.org/Layer0X-" "1.0" "1.1" + _ + @move"http://www.simantics.org/G2D-" "1.0" "1.1" + _ + @move"http://www.simantics.org/Structural-" "1.0" "1.2" + _ + @move"http://www.simantics.org/Structural-" "1.1" "1.2" + _ + @move"http://www.simantics.org/Diagram-" "2.1" "2.2" + _ + @move"http://www.simantics.org/Simulation-" "1.0" "1.1" + _ + @move"http://www.simantics.org/Diagram-" "1.0" "1.1" + _ + @move"http://www.simantics.org/Modeling-" "1.1" "1.2" + _ + @move"http://www.simantics.org/Project-" "1.1" "1.2" + _ + @move"http://www.simantics.org/Spreadsheet-" "1.1" "1.2" + _ + @move"http://www.simantics.org/Viewpoint-" "1.1" "1.2" + _ + @move"http://www.simantics.org/Image2-" "1.1" "1.2" + _ + @move"http://www.simantics.org/Color-" "1.0" "1.1" + _ + @move"http://www.simantics.org/Action-" "1.0" "1.1" + _ + @move"http://www.simantics.org/Silk-" "1.0" "1.1" + _ + @move"http://www.simantics.org/Issue-" "1.1" "1.2" + _ + @move"http://www.simantics.org/User-" "1.0" "1.1" + _ + @move"http://www.simantics.org/Documentation-" "1.0" "1.1" + _ + @move"http://www.simantics.org/Document-" "1.1" "1.2" + _ + @move"http://www.simantics.org/SelectionView-" "1.1" "1.2" + +FROM16TO17.Spreadsheets : L0.NamespaceMigrationStep + @L0.list + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "HasContent" "Cell/content" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "FitRows" "Dimensions/fitRows" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "FitColumns" "Dimensions/fitColumns" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "ColumnCount" "Dimensions/columnCount" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "ColumnLabels" "Headers/columnLabels" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "RowCount" "Dimensions/rowCount" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "ColumnWidths" "Headers/columnWidths" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "ContentOf" "Cell/content/Inverse" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "FitRowsOf" "Dimensions/fitRows/Inverse" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "FitColumnsOf" "Dimensions/fitColumns/Inverse" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "ColumnCountOf" "Dimensions/columnCount/Inverse" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "ColumnLabelsOf" "Headers/columnLabels/Inverse" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "RowCountOf" "Dimensions/rowCount/Inverse" + _ + @move "http://www.simantics.org/Spreadsheet-1.2/" "ColumnWidthsOf" "Headers/columnWidths/Inverse" + +FROM16TO17.SysdynChanges : L0.NamespaceMigrationStep + @L0.list + _ + @move "http://www.simantics.org/Sysdyn-1.1/" "HasTail" "Variable/HasTail" + _ + @move "http://www.simantics.org/Sysdyn-1.1/" "HasHead" "Variable/HasHead" + _ + @move "http://www.simantics.org/Sysdyn-1.1/" "SharedModuleOntolofgy" "SharedModuleOntology" + _ + @move "http://www.simantics.org/Sysdyn-1.1/" "HasUnit" "Variable/unit" + + +FROM16TO17.OrderedSetsToLists : L0.OrderedSetToListMigrationStep + @L0.list + _ : L0.OrderedSetToListMigrationStep.Change + L0.OrderedSetToListMigrationStep.entityType "http://www.simantics.org/Sysdyn-1.1/Variable" + L0.OrderedSetToListMigrationStep.orderedSetRelation "http://www.simantics.org/Sysdyn-1.1/Variable/expressions" + L0.OrderedSetToListMigrationStep.orderedSetType "http://www.simantics.org/Sysdyn-1.1/Expressions" + L0.OrderedSetToListMigrationStep.listRelation "http://www.simantics.org/Sysdyn-1.1/Variable/expressionList" + L0.OrderedSetToListMigrationStep.listType "http://www.simantics.org/Layer0-1.1/List" + _ : L0.OrderedSetToListMigrationStep.Change + L0.OrderedSetToListMigrationStep.entityType "http://www.simantics.org/Sysdyn-1.1/Variable" + L0.OrderedSetToListMigrationStep.orderedSetRelation "http://www.simantics.org/Sysdyn-1.1/Variable/arrayIndexes" + L0.OrderedSetToListMigrationStep.orderedSetType "http://www.simantics.org/Sysdyn-1.1/ArrayIndexes" + L0.OrderedSetToListMigrationStep.listRelation "http://www.simantics.org/Sysdyn-1.1/Variable/arrayIndexesList" + L0.OrderedSetToListMigrationStep.listType "http://www.simantics.org/Layer0-1.1/List" + _ : L0.OrderedSetToListMigrationStep.Change + L0.OrderedSetToListMigrationStep.entityType "http://www.simantics.org/Sysdyn-1.1/Enumeration" + L0.OrderedSetToListMigrationStep.orderedSetRelation "http://www.simantics.org/Sysdyn-1.1/Enumeration/enumerationIndexes" + L0.OrderedSetToListMigrationStep.orderedSetType "http://www.simantics.org/Sysdyn-1.1/EnumerationIndexes" + L0.OrderedSetToListMigrationStep.listRelation "http://www.simantics.org/Sysdyn-1.1/Enumeration/enumerationIndexList" + L0.OrderedSetToListMigrationStep.listType "http://www.simantics.org/Layer0-1.1/List" diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/graph/ModelicaArrayFunctions.pgraph b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/ModelicaArrayFunctions.pgraph new file mode 100644 index 00000000..847db26c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/ModelicaArrayFunctions.pgraph @@ -0,0 +1,536 @@ +L0 = +SYSDYN = + +MAF = : SYSDYN.SysdynModelicaFunctionLibrary + + + +MAF.scalar : SYSDYN.SysdynModelicaFunction + L0.HasDescription """scalar(A) + +Returns a one-element array as scalar. + +Returns the single element of array A. size(A,i) = 1 is required for 1 <= i <= ndims(A).""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.scalar.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.scalar.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.vector : SYSDYN.SysdynModelicaFunction + L0.HasDescription """vector(A) + +Returns an array with one non-singleton dimension as vector. + +Returns a 1-vector, if A is a scalar and otherwise returns a vector containing all the elements of the array, provided there is at most one dimension size > 1. + +Examples: +Real A[1,2,1] = {{{3},{4}}}; +Real v[2] = vector(A); // = {3,4}""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.vector.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.vector.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.matrix : SYSDYN.SysdynModelicaFunction + L0.HasDescription """matrix(A) + +Returns the first two dimensions of an array as matrix. + +Returns promote(A,2), if A is a scalar or vector and otherwise returns the elements of the first two dimensions as a matrix. size(A,i) = 1 is required for 2 < i <= ndims(A). +Function promote(A,n) fills dimensions of size 1 from the right to array A upto dimension n, where "n > ndims(A)" is required. Let C = promote(A,n), with nA = ndims(A), then +ndims(C) = n, +size(C,j) = size(A,j) for 1 <= j <= nA, +size(C,j) = 1 for nA+1 <= j <= n, +C[i_1, ..., i_nA, 1, ..., 1] = A[i_1, ..., i_nA].""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.matrix.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.matrix.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.ndims : SYSDYN.SysdynModelicaFunction + L0.HasDescription """ndims(A) + +Return number of array dimensions. + +Returns the number of dimensions k of array expression A, with k >= 0.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.ndims.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.ndims.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.unit "1" + + + +MAF.size : SYSDYN.SysdynModelicaFunction + L0.HasDescription """size(A,i) +size(A) + +Returns dimensions of an array. + +The first form returns the size of dimension i of array expression A where i shall be > 0 and <= ndims(A). + +The second form returns a vector of length ndims(A) containing the dimension sizes of A. + +Examples: +Real A[8,4,5]; +Integer n3 = size(A,3); // = 5 +Integer n[:] = size(A); // = {8,4,5}""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.size.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + MAF.size.i : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional true + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.size.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + + + +MAF.array : SYSDYN.SysdynModelicaFunction + L0.HasDescription """array(A,B,C,...) + +The constructor function array(A,B,C,...) constructs an array from its arguments. + +The constructor function array(A,B,C,...) constructs an array from its arguments according to the following rules: + * Size matching: All arguments must have the same sizes, i.e., size(A)=size(B)=size(C)=... + * All arguments must be type compatible expressions giving the type of the elements. The data type of the result array is the maximally expanded type of the arguments. Real and Integer subtypes can be mixed resulting in a Real result array where the Integer numbers have been transformed to Real numbers. + * Each application of this constructor function adds a one-sized dimension to the left in the result compared to the dimensions of the argument arrays, i.e., ndims(array(A,B,C)) = ndims(A) + 1 = ndims(B) + 1, ... + * {A, B, C, ...} is a shorthand notation for array(A, B, C, ...). + * There must be at least one argument [i.e., array() or {} are not defined].""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.array.A : SYSDYN.SysdynModelicaFunction.VariableLengthInput + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List + @L0.list + MAF.array.A.A : L0.String + MAF.array.A.B : L0.String + MAF.array.A.C : L0.String + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.array.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.cat : SYSDYN.SysdynModelicaFunction + L0.HasDescription """cat(k,A,B,C,...) + +The function cat(k,A,B,C,...)concatenates arrays A,B,C,... along dimension k. + +The function cat(k,A,B,C,...)concatenates arrays A,B,C,... along dimension k according to the following rules: + * Arrays A, B, C, ... must have the same number of dimensions, i.e., ndims(A) = ndims(B) = ... + * Arrays A, B, C, ... must be type compatible expressions giving the type of the elements of the result. The maximally expanded types should be equivalent. Real and Integer subtypes can be mixed resulting in a Real result array where the Integer numbers have been transformed to Real numbers. + * k has to characterize an existing dimension, i.e., 1 <= k <= ndims(A) = ndims(B) = ndims(C); k shall be an integer number. + * Size matching: Arrays A, B, C, ... must have identical array sizes with the exception of the size of dimension k, i.e., size(A,j) = size(B,j), for 1 <= j <= ndims(A) and j <> k. + +Examples: +Real[2,3] r1 = cat(1, {{1.0, 2.0, 3}}, {{4, 5, 6}}); +Real[2,6] r2 = cat(2, r1, 2*r1);""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.cat.k : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + MAF.cat.A : SYSDYN.SysdynModelicaFunction.VariableLengthInput + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List + @L0.list + MAF.cat.A.A : L0.String + MAF.cat.A.B : L0.String + MAF.cat.A.C : L0.String + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.cat.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.zeros : SYSDYN.SysdynModelicaFunction + L0.HasDescription """zeros(n1, n2, n3, ...) + +Returns a zero array. + +Returns the n1 x n2 x n3 x ... Integer array with all elements equal to zero (ni >= 0).""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.zeros.n : SYSDYN.SysdynModelicaFunction.VariableLengthInput + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List + @L0.list + MAF.zeros.n.n1 : L0.String + MAF.zeros.n.n2 : L0.String + MAF.zeros.n.n3 : L0.String + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.zeros.o : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Integer n annotation(__OpenModelica_varArgs = true); + output Integer o[:];""" + + + +MAF.ones : SYSDYN.SysdynModelicaFunction + L0.HasDescription """ones(n1, n2, n3, ...) + +Returns an array with "1" elements. + +Return the n1 x n2 x n3 x ... Integer array with all elements equal to one (ni >=0 ).""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.ones.n : SYSDYN.SysdynModelicaFunction.VariableLengthInput + SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List + @L0.list + MAF.ones.n.n1 : L0.String + MAF.ones.n.n2 : L0.String + MAF.ones.n.n3 : L0.String + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.ones.o : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Integer n annotation(__OpenModelica_varArgs = true); + output Integer o[:];""" + + + +MAF.fill : SYSDYN.SysdynModelicaFunction + L0.HasDescription """fill(s, n1, n2, n3, ...) + +Return a Real, Integer, Boolean or String array with all elements equal + +Returns the n1 x n2 x n3 x ... array with all elements equal to scalar or array expression s (ni >= 0). The returned array has the same type as s. Recursive definition: +fill(s,n1,n2,n3, ...) = fill(fill(s,n2,n3, ...), n1); +fill(s,n) = {s,s,..., s} + +Examples: +Real mr[2,2] = fill(-1,2,2); // = [-1,-1;-1,-1] +Boolean vb[3] = fill(true,3); // = {true, true, true}""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.fill.s : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MAF.fill.n : SYSDYN.SysdynModelicaFunction.VariableLengthInput + SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels _ : L0.List + @L0.list + MAF.fill.n.n1 : L0.String + MAF.fill.n.n2 : L0.String + MAF.fill.n.n3 : L0.String + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.fill.o : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input OpenModelica.Internal.BuiltinType s; + input Integer n annotation(__OpenModelica_varArgs = true); + output OpenModelica.Internal.BuiltinType o[:];""" + + + +MAF.identity : SYSDYN.SysdynModelicaFunction + L0.HasDescription """identity(n) + +Returns the identity matrix of the desired size. + +Returns the n x n Integer identity matrix, with ones on the diagonal and zeros at the other places.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.identity.n : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Integer " + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.identity.outArray : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Integer " + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Integer n; + output Integer[n,n] outArray;""" + + + +MAF.diagonal : SYSDYN.SysdynModelicaFunction + L0.HasDescription """diagonal(v) + +Returns a diagonal matrix. + +Returns a square matrix with the elements of vector v on the diagonal and all other elements zero.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.diagonal.v : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.diagonal.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.linspace : SYSDYN.SysdynModelicaFunction + L0.HasDescription """linspace(x1, x2, n) + +Return Real vector with equally spaced elements. + +Returns a Real vector with n equally spaced elements, such that +v[i] = x1 + (x2-x1)*(i-1)/(n-1) for 1 <= i <= n. +It is required that n >= 2. The arguments x1 and x2 shall be Real or Integer scalar expressions. + +Example: +Real v[:] = linspace(1,7,4); // = {1, 3, 5, 7}""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.linspace.x1 : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MAF.linspace.x2 : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MAF.linspace.n : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.linspace.v : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x1 "start"; + input Real x2 "end"; + input Integer n "number"; + output Real v[n];""" + + + +MAF.min : SYSDYN.SysdynModelicaFunction + L0.HasDescription """min(A) + +Returns the smallest element. + +Returns the smallest element of array expression A.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.min.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.min.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.max : SYSDYN.SysdynModelicaFunction + L0.HasDescription """max(A) + +Returns the largest element. + +Returns the largest element of array expression A.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.max.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.max.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.sum : SYSDYN.SysdynModelicaFunction + L0.HasDescription """sum(A) +sum(e(i, ..., j) for i in u, ..., j in v) + +Returns the scalar sum. + +The first form returns the scalar sum of all the elements of array expression A: +A[1,...,1]+A[2,...,1]+....+A[end,...,1]+A[end,...,end] + +The second form is a reduction expression and returns the sum of the expression e(i, ..., j) evaluated for all combinations of i in u, ..., j in v: +e(u[1],...,v[1]) + e(u[2],...,v[1]) + ... + +e(u[end],...,v[1]) + ... + e(u[end],...,v[end]) +The type of sum(e(i, ..., j) for i in u, ..., j in v) is the same as the type of e(i,...j). + +Example: +sum(i for i in 1:10) // Gives 1+2+...+10=55 + // Read it as: compute the sum of i for i in the range 1 to 10.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.sum.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.sum.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.product : SYSDYN.SysdynModelicaFunction + L0.HasDescription """product(A) +product(e(i, ..., j) for i in u, ..., j in v) + +Returns the scalar product + +The first form returns the scalar product of all the elements of array expression A: +A[1,...,1]*A[2,...,1]*....*A[end,...,1]*A[end,...,end] + +The second form is a reduction expression and returns the product of the expression e(i, ..., j) evaluated for all combinations of i in u, ..., j in v: +e(u[1],...,v[1]) * e(u[2],...,v[1]) * ... * +e(u[end],...,v[1]) * ... * e(u[end],...,v[end]) +The type of product(e(i, ..., j) for i in u, ..., j in v) is the same as the type of e(i,...j). + +Example: +{product(j for j in 1:i) for i in 0:4} // = {1,1,2,6,24}""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.product.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.product.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "ANY" + + + +MAF.transpose : SYSDYN.SysdynModelicaFunction + L0.HasDescription """transpose(A) + +Transpose of a matrix or permutation of the first two dimensions of an array + +Permutes the first two dimensions of array A. It is an error, if array A does not have at least 2 dimensions.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.transpose.A : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.transpose.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MAF.cross : SYSDYN.SysdynModelicaFunction + L0.HasDescription """cross(x,y) + +Return cross product of two vectors. + +Returns the 3-vector cross product of the 3-vectors x and y. +cross(x,y) = vector( [ x[2]*y[3]-x[3]*y[2]; + x[3]*y[1]-x[1]*y[3]; + x[1]*y[2]-x[2]*y[1] ] );""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.cross.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MAF.cross.y : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.cross.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p*'q" + + + +MAF.skew : SYSDYN.SysdynModelicaFunction + L0.HasDescription """skew(x) + +Returns the skew matrix that is associated with a vector + +Returns the 3 x 3 skew symmetric matrix associated with a 3-vector, i.e., +cross(x,y) = skew(x)*y; +skew(x) = [ 0 , -x[3], x[2]; + x[3], 0 , -x[1]; + -x[2], x[1], 0 ];""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MAF.skew.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MAF.skew.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/graph/ModelicaFunctions.pgraph b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/ModelicaFunctions.pgraph new file mode 100644 index 00000000..c692447a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/ModelicaFunctions.pgraph @@ -0,0 +1,804 @@ +L0 = +SYSDYN = + +MF = : SYSDYN.SysdynModelicaFunctionLibrary + + + +MF.abs : SYSDYN.SysdynModelicaFunction + L0.HasDescription """abs(v) + +Absolute value. + +Returns the absolute value of v. Is expanded into "(if v >= 0 then v else -v)" (into "noEvent(if v >= 0 then v else -v)", to be precise). Argument v needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.abs.v : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.abs.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MF.acos : SYSDYN.SysdynModelicaFunction + L0.HasDescription """acos(u) + +Inverse cosine. + +Returns the inverse of cos of u, with -1 <= u <= +1. Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.acos.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.acos.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; + output Real y;""" + + + +MF.asin : SYSDYN.SysdynModelicaFunction + L0.HasDescription """asin(u) + +Inverse sine. + +Returns the inverse of sin of u, with -1 <= u <= +1. Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.asin.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.asin.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; + output Real y;""" + + + +MF.atan : SYSDYN.SysdynModelicaFunction + L0.HasDescription """atan(u) + +Inverse tangent. + +Returns the inverse of tan of u, with -INF < u < INF. Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.atan.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.atan.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; + output Real y;""" + + + +MF.atan2 : SYSDYN.SysdynModelicaFunction + L0.HasDescription """atan2(u1,u2) + +Four quadrant inverse tangent. + +Returns y = atan2(u1,u2) such that tan(y) = u1/u2 and y is in the range -pi < y <= pi. u2 may be zero, provided u1 is not zero. Usually u1, u2 is provided in such a form that u1 = sin(y) and u2 = cos(y). Arguments u1 and u2 need to be Integer or Real expressions.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.atan2.u1 : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + MF.atan2.u2 : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.atan2.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u1; + input Real u2; + output Real z;""" + + + +MF.ceil : SYSDYN.SysdynModelicaFunction + L0.HasDescription """ceil(x) + +Round a Real number towards plus infinity + +Returns the smallest integer not less than x (i.e. the closest integer above x).""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.ceil.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.ceil.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; + output Real y;""" + + + +MF.cos : SYSDYN.SysdynModelicaFunction + L0.HasDescription """cos(u) + +Cosine. + +Returns the cosine of u, with -INF < u < INF Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.cos.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.cos.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; + output Real y;""" + + + +MF.cosh : SYSDYN.SysdynModelicaFunction + L0.HasDescription """cosh(u) + +Hyperbolic cosine. + +Returns the cosh of u, with -INF < u < INF. Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.cosh.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.cosh.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; + output Real y;""" + + + +MF.delay : SYSDYN.SysdynModelicaFunction + L0.HasDescription """delay(expr, delayTime, delayMax) +delay(expr, delayTime) + +Returns the value of expr at the time time-delayTime. The value of expr is returned when time <= time.start + delayTime. + +Returns "expr(time - delayTime)" for time > time.start + delayTime and "expr(time.start)" for time <= time.start + delayTime. The arguments, i.e., expr, delayTime and delayMax, need to be subtypes of Real. delayMax needs to be additionally a parameter expression. The following relation shall hold: 0 <= delayTime <= delayMax, otherwise an error occurs. If delayMax is not supplied in the argument list, delayTime need to be a parameter expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.delay.expr : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MF.delay.delayTime : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" + MF.delay.delayMax : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional true + SYSDYN.SysdynModelicaFunction.unit "TIME" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.delay.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MF.der : SYSDYN.SysdynModelicaFunction + L0.HasDescription """der(expr) + +Time derivative of expr. expr must be have continuous-time variability. + +The time derivative of expression expr. If the expression expr is a scalar it needs to be a subtype of Real. The expression and all its subexpressions must be differentiable. If expr is an array, the operator is applied to all elements of the array. For Real parameters and constants the result is a zero scalar or array of the same size as the variable. + +Example: + Real x, xdot1, xdot2; +equation + xdot1 = der(x); + xdot2 = der(x*sin(x));""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.der.expr : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.der.dexpr : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p/TIME" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real expr(unit = "'p"); + output Real dexpr(unit = "'p/s");""" + + + +MF.div : SYSDYN.SysdynModelicaFunction + L0.HasDescription """div(x, y) + +Integer part of division of two Real numbers. + +Returns the algebraic quotient x/y with any fractional part discarted (also known as truncation toward zero). E.g. div(10,3) = 3.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.div.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MF.div.y : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.div.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p/'q" + + + +MF.edge : SYSDYN.SysdynModelicaFunction + L0.HasDescription """edge(b) + +Indicate rising edge + +Returns true when the value of the boolean expression b changes. Expanded into (b and not pre(b)).""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.edge.b : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Boolean" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.edge.edgeEvent : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Boolean" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Boolean b; + output Boolean edgeEvent;""" + + + +MF.exp : SYSDYN.SysdynModelicaFunction + L0.HasDescription """exp(u) + +Exponential, base e. + +Returns the base e exponential of u, with -INF < u < INF Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.exp.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.exp.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u(unit = "1"); + output Real y(unit = "1");""" + + + +MF.floor : SYSDYN.SysdynModelicaFunction + L0.HasDescription """floor(x) + +Round Real number towards minus infinity + +Returns the largest integer not greater than x (i.e. the closest integer below x).""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.floor.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.floor.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; + output Real y;""" + + + +MF.initial : SYSDYN.SysdynModelicaFunction + L0.HasDescription """initial() + +True during initialization. + +Returns true during the initialization phase and false otherwise.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.initial.isInitial : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Boolean" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ output Boolean isInitial;""" + + + +MF.log : SYSDYN.SysdynModelicaFunction + L0.HasDescription """log(u) + +Natural (base e) logarithm. + +Returns the base e logarithm of u, with u > 0. Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.log.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.log.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u(unit = "1"); + output Real y(unit = "1");""" + + + +MF.log10 : SYSDYN.SysdynModelicaFunction + L0.HasDescription """log10(u) + +Base 10 logarithm. (u > 0) + +Returns the base 10 logarithm of u, with u > 0. Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.log10.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.log10.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u(unit = "1"); + output Real y(unit = "1");""" + + + +MF.max : SYSDYN.SysdynModelicaFunction + L0.HasDescription """max(x,y) +max(e(i, ..., j) for i in u, ..., j in v) + +Returns the largest element. + +The first form returns the largest element of the scalars x and y. + +The second form is a reduction expression and returns the largest value of the scalar expression e(i, ..., j) evaluated for all combinations of i in u, ..., j in v + +Example: +max(i^2 for i in {3,7,6}) // = 49""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.max.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MF.max.y : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.max.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MF.min : SYSDYN.SysdynModelicaFunction + L0.HasDescription """min(x,y) +min(e(i, ..., j) for i in u, ..., j in v) + +Returns the smallest element. + +The first form returns the smallest element of the scalars x and y. + +The second form is a reduction expression and returns the smallest value of the scalar expression e(i, ..., j) evaluated for all combinations of i in u, ..., j in v + +Example: +min(i^2 for i in {3,7,6}) // = 9""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.min.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MF.min.y : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.min.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MF.mod : SYSDYN.SysdynModelicaFunction + L0.HasDescription """mod(x, y) + +Integer modulus of a division of two Real numbers. + +Returns the integer modulus of x/y: mod(x,y) = x - floor(x/y) * y.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.mod.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MF.mod.y : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.mod.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MF.noEvent : SYSDYN.SysdynModelicaFunction + L0.HasDescription """noEvent(expr) + +Turn off event triggering. + +noEvent around an expression causes the expression to NOT generate event. +Important: +If you want a condition to be checked only on time steps, use noEvent. +(e.g. if noEvent(value >= 1) then ... else ...)""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.noEvent.expr : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.noEvent.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + + + +MF.pre : SYSDYN.SysdynModelicaFunction + L0.HasDescription """pre(y) + +Returns the preceding value of y from time event that has occured before current time. + +Returns the "left limit" y(tpre) of variable y(t) at a time instant t. At an event instant, y(tpre) is the value of y after the last event iteration at time instant t. The pre operator can be applied if the following three conditions are fulfilled simultaneously: + * variable y is a subtype of a simple type + * y is a discrete-time expression + * the operator is not applied in a function class +The first value of pre(y) is determined in the initialization phase. +A new event is triggered if at least for one variable v "pre(v) <> v" after the active model equations are evaluated at an event instant. In this case the model is at once reevaluated. This evaluation sequence is called "event iteration". The integration is restarted, if for all v used in pre-operators the following condition holds: "pre(v) == v".""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.pre.y : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.pre.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MF.rem : SYSDYN.SysdynModelicaFunction + L0.HasDescription """rem(x, y) + +Integer remainder of the division of two Real numbers. + +Returns the integer remainder of x/y: rem(x,y) = x - div(x,y) * y.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.rem.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MF.rem.y : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.rem.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MF.sample : SYSDYN.SysdynModelicaFunction + L0.HasDescription """sample(start, interval) + +Trigger time events. + +Returns true and triggers time events at times start + i * interval (i=0,1,...).""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.sample.start : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" + MF.sample.interval : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.sample.isSample : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Boolean" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ parameter input Real start(fixed = false); + parameter input Real interval(fixed = false); + output Boolean isSample;""" + + + +MF.semiLinear : SYSDYN.SysdynModelicaFunction + L0.HasDescription """semiLinear(x, positiveSlope, negativeSlope) + +Returns "if x >= 0 then positiveSlope*x else negativeSlope*x" and handle x=0 in a meaningful way. + +Returns "if x >= 0 then positiveSlope*x else negativeSlope*x". In some situations, equations with the semiLinear function become underdetermined if the first argument (x) becomes zero, i.e., there are an infinite number of solutions. It is recommended that the following rules are used to transform the equations during the translation phase in order to select one meaningful solution in such cases: + +Rule 1: The equations +y = semiLinear(x, sa, s1); +y = semiLinear(x, s1, s2); +y = semiLinear(x, s2, s3); + ... +y = semiLinear(x, sN, sb); +may be replaced by +s1 = if x >= 0 then sa else sb +s2 = s1; +s3 = s2; + ... +sN = sN-1; +y = semiLinear(x, sa, sb); + +Rule 2: The equations +x = 0; +y = 0; +y = semiLinear(x, sa, sb); +may be replaced by +x = 0 +y = 0; +sa = sb;""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.semiLinear.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + MF.semiLinear.positiveSlope : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" + MF.semiLinear.negativeSlope : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.semiLinear.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p*'q" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; + input Real positiveSlope; + input Real negativeSlope; + output Real result;""" + + + +MF.sign : SYSDYN.SysdynModelicaFunction + L0.HasDescription """sign(v) + +Sign function of a Real or Integer number. + +Returns -1 if v is negative, 1 if v is positive. Expanded into "(if v > 0 then 1 else if v < 0 then -1 else 0)".""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.sign.v : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.sign.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real v; + output Integer result;""" + + + +MF.sin : SYSDYN.SysdynModelicaFunction + L0.HasDescription """sin(u) + +Sine. + +Returns the sine of u, with -INF < u < INF. Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.sin.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.sin.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; + output Real y;""" + + + +MF.sinh : SYSDYN.SysdynModelicaFunction + L0.HasDescription """sinh(u) + +Hyperbolic sine. + +Returns the sinh of u, with -INF < u < INF. Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.sinh.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.sinh.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; + output Real y;""" + + + +MF.smooth : SYSDYN.SysdynModelicaFunction + L0.HasDescription """smooth(p, expr) + +Indicate smoothness of expression. + +If p>=0 smooth(p, expr) returns expr and states that expr is p times continuously differentiable, i.e.: expr is continuous in all real variables appearing in the expression and all partial derivatives with respect to all appearing real variables exist and are continuous up to order p. +The only allowed types for expr in smooth are: real expressions, arrays of allowed expressions, and records containing only components of allowed expressions.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.smooth.p : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + MF.smooth.expr : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.smooth.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + + + +MF.sqrt : SYSDYN.SysdynModelicaFunction + L0.HasDescription """sqrt(v) + +Square root. + +Square root of v. The value of v must be greater or equal to 0 or an assertion error occurs.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.sqrt.v : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.sqrt.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real v(unit = "'p"); + output Real y(unit = "'p(1/2)");""" + + + +MF.tan : SYSDYN.SysdynModelicaFunction + L0.HasDescription """tan(u) + +Tangent. + +Returns the tangent of u, with -INF < u < INF (if u is a multiple of (2n-1)*pi/2, y = tan(u) is +/- infinity). Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.tan.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.tan.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real u; + output Real y;""" + + + +MF.tanh : SYSDYN.SysdynModelicaFunction + L0.HasDescription """tanh(u) + +Hyperbolic tangent. + +Returns the tanh of u, with -INF < u < INF. Argument u needs to be an Integer or Real expression.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + MF.tanh.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.tanh.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ input Real x; + output Real y;""" + + + +MF.terminal : SYSDYN.SysdynModelicaFunction + L0.HasDescription """terminal() + +True after successful analysis + +Returns true at the end of a successful simulation.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + MF.terminal.isTerminal : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Boolean" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface """ output Boolean isTerminal;""" + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/graph/Profiles.pgraph b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/Profiles.pgraph new file mode 100644 index 00000000..2fe4a7b2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/Profiles.pgraph @@ -0,0 +1,45 @@ +L0 = +L0X = +DIA = +SYSDYN = + +PROFILES = SYSDYN.Profiles : L0.Library + + +// TEMPLATE +groupStyleEntry : L0.Template + @template %subject %style %group + %subject : DIA.GroupStyleProfileEntry + DIA.ProfileEntry.HasStyle %style + DIA.ProfileEntry.HasGroup %group + + +// PROFILES +SYSDYN.SimulationPlaybackProfile +VP = +SYSDYN = + +///////////////////////////////// +/// History datasets +///////////////////////////////// +HDBC = SYSDYN.HistoryDataset.HistoryDatasetVariablesBrowseContext : VP.BrowseContext + +HDBC.StringNodeType +L0X = +G2D = +STR = +DIA = +SIMU = +MOD = +PROJ = +JFREE = +SHEET = +WORKBENCH = + +//##################################################################### +// Defines ontology and attaches it to SimanticsDomain +//##################################################################### + +SYSDYN = : L0.Ontology + @L0.new + L0.HasResourceClass "org.simantics.sysdyn.SysdynResource" + +SYSDYN.ImportedOntologies : PROJ.NamespaceRequirement + L0.HasDescription "Specifies the ontologies required by a Sysdyn project." + PROJ.RequiresNamespace + "http://www.simantics.org/Sysdyn-1.1" : L0.URI + "http://www.simantics.org/Layer0-1.1" : L0.URI + "http://www.simantics.org/SelectionView-1.2" : L0.URI +// "http://www.semantum.fi/Simupedia-1.0" : L0.URI // Experimental Simupedia +// "http://www.semantum.fi/SimupediaWorkbench-1.0" : L0.URI // Experimental Simupedia +// "http://www.simantics.org/Documentation-1.2" : L0.URI // Experimental Simupedia + +SYSDYN.SharedFunctionOntology -- SYSDYN.SysdynModel.startTime --> L0.Double -- SYSDYN.SysdynModel.stopTime --> L0.Double -- SYSDYN.SysdynModel.simulationStepLength --> L0.Double -- SYSDYN.SysdynModel.outputInterval --> L0.Double -- SYSDYN.SysdynModel.tolerance --> L0.Double -- SYSDYN.SysdynModel.solver --> L0.String -- SYSDYN.SysdynModel.variableFilter --> L0.String -- SYSDYN.SysdynModel.fmuFile --> L0.ByteArray -- SYSDYN.SysdynModel.timeUnit --> L0.String -- SYSDYN.SysdynModel.lastExportFileName --> L0.String -- SYSDYN.SysdynModel.lastExportFilePath --> L0.String -- SYSDYN.SysdynModel.exeFile --> L0.ByteArray -- SYSDYN.ConfigurationDiagram.selection --> DIA.Element -- SYSDYN.Variable.type --> L0.String -- SYSDYN.Variable.expressions --> SYSDYN.Expressions -- SYSDYN.Variable.expressionList --> L0.List -- SYSDYN.Variable.arrayIndexes --> SYSDYN.ArrayIndexes -- SYSDYN.Variable.arrayIndexesList --> L0.List -- SYSDYN.Variable.unit --> L0.String -- SYSDYN.Variable.variability --> L0.String -- SYSDYN.Variable.isTailOf --> STR.Connection -- SYSDYN.Variable.isHeadOf --> STR.Connection -- SYSDYN.Variable.value -- SYSDYN.Variable.values -- SYSDYN.Variable.times -- SYSDYN.Variable.names -- SYSDYN.Variable.activeDatasets -- SYSDYN.Variable.time -- SYSDYN.IndependentVariable.unit --> L0.String -- SYSDYN.IndependentVariable.rangeStart --> L0.Double -- SYSDYN.IndependentVariable.rangeEnd --> L0.Double -- SYSDYN.IndependentVariable.rangeStep --> L0.Double -- SYSDYN.IndependentVariable.activeExpression --> SYSDYN.Expression -- SYSDYN.IndependentVariable.isUninitialized --> SYSDYN.IndependentVariable -- SYSDYN.Input.defaultInputValue --> L0.Double -- SYSDYN.Enumeration.enumerationIndexes --> SYSDYN.EnumerationIndexes -- SYSDYN.Enumeration.enumerationIndexList --> L0.List -- SYSDYN.Enumeration.isReplaceable --> L0.Boolean -- SYSDYN.Shadow.original --> SYSDYN.IndependentVariable -- SYSDYN.Module.redeclaration --> SYSDYN.Redeclaration -- SYSDYN.Module.parameterOverride --> SYSDYN.Module.ParameterOverride -- SYSDYN.Module.ParameterOverride.overriddenParameter --> SYSDYN.IndependentVariable -- SYSDYN.Module.ParameterOverride.overrideExpression --> L0.String -- SYSDYN.Dependency.angle --> L0.Double -- SYSDYN.Dependency.refersTo --> SYSDYN.Variable -- SYSDYN.Expression.equation --> L0.String -- SYSDYN.Expression.arrayRange --> L0.String -- SYSDYN.DelayExpression.expression --> L0.String -- SYSDYN.DelayExpression.order --> L0.Integer -- SYSDYN.DelayExpression.delayTime --> L0.String -- SYSDYN.DelayExpression.initialValue --> L0.String -- SYSDYN.StockExpression.useCustomIntegral --> SYSDYN.StockExpression -- SYSDYN.StockExpression.integralEquation --> L0.String -- SYSDYN.StockExpression.initialEquation --> L0.String -- SYSDYN.LookupExpression.lookup --> L0.String -- SYSDYN.WithLookupExpression.expression --> L0.String -- SYSDYN.WithLookupExpression.lookup --> L0.String -- SYSDYN.WithLookupExpression.minX --> L0.Double -- SYSDYN.WithLookupExpression.maxX --> L0.Double -- SYSDYN.WithLookupExpression.minY --> L0.Double -- SYSDYN.WithLookupExpression.maxY --> L0.Double -- SYSDYN.EnumerationIndex.showEnumerationIndexInCharts --> L0.Boolean -- SYSDYN.Redeclaration.replacedEnumeration --> SYSDYN.Enumeration -- SYSDYN.Redeclaration.replacingEnumeration --> SYSDYN.Enumeration -- SYSDYN.SysdynModelicaFunction.modelicaFunctionCode --> L0.String -- SYSDYN.SysdynModelicaFunction.modelicaFunctionInterface --> L0.String -- SYSDYN.SysdynModelicaFunction.inputs --> L0.List -- SYSDYN.SysdynModelicaFunction.outputs --> L0.List -- SYSDYN.ExternalFunctionFile.externalFile --> L0.ByteArray -- SYSDYN.SysdynModelicaFunction.definition --> L0.String -- SYSDYN.SysdynModelicaFunction.unit --> L0.String -- SYSDYN.SysdynModelicaFunction.optional --> L0.Boolean -- SYSDYN.SysdynModelicaFunction.VariableLengthInput.shownLabels --> L0.List -- SYSDYN.Experiment.result --> SYSDYN.Result -- SYSDYN.Experiment.resultSet --> SYSDYN.ResultSet -- SYSDYN.GameExperiment.stepDuration --> L0.Double -- SYSDYN.GameExperiment.stepLength --> L0.Double -- SYSDYN.Experiment.Run.time -- SYSDYN.SensitivityAnalysisExperiment.parameterList --> L0.List -- SYSDYN.SensitivityAnalysisExperiment.randomSeed --> L0.Integer -- SYSDYN.SensitivityAnalysisExperiment.method --> SYSDYN.ValueGeneratorMethod -- SYSDYN.SensitivityAnalysisExperiment.resultRefreshRate --> L0.Integer -- SYSDYN.SensitivityAnalysisExperiment.numberOfValues --> L0.Integer -- SYSDYN.SensitivityAnalysisExperiment.Parameter.propabilityDistribution --> SYSDYN.ProbabilityDistribution -- SYSDYN.SensitivityAnalysisExperiment.Parameter.variable --> L0.String -- SYSDYN.SensitivityAnalysisExperiment.Parameter.indexes --> L0.StringArray -- SYSDYN.UniformDistribution.minValue --> L0.Double -- SYSDYN.UniformDistribution.maxValue --> L0.Double -- SYSDYN.NormalDistribution.minValue --> L0.Double -- SYSDYN.NormalDistribution.maxValue --> L0.Double -- SYSDYN.NormalDistribution.mean --> L0.Double -- SYSDYN.NormalDistribution.stdDeviation --> L0.Double -- SYSDYN.Interval.minValue --> L0.Double -- SYSDYN.Interval.maxValue --> L0.Double -- SYSDYN.Result.parameterFile --> L0.String -- SYSDYN.Result.resultFile --> L0.String -- SYSDYN.Result.showResult --> SYSDYN.Result -- SYSDYN.Result.time --> L0.Long -- SYSDYN.HistoryDataset.start --> L0.String -- SYSDYN.HistoryDataset.end --> L0.String -- SYSDYN.HistoryDataset.timeName --> L0.String -- SYSDYN.HistoryDataset.columns --> L0.Boolean -- SYSDYN.HistoryDataset.sheet --> SHEET.Spreadsheet -- SYSDYN.Experiment.result --> SYSDYN.Result -- SYSDYN.ValveSymbol.orientation --> SYSDYN.Orientation -- SYSDYN.ValveSymbol.textLocation --> SYSDYN.Location -- SYSDYN.FlowConnection.width --> L0.Float -- SYSDYN.DependencyConnection.polarity --> L0.String -- SYSDYN.DependencyConnection.polarityLocation --> L0.String -- SYSDYN.DependencyConnection.hideArrow --> SYSDYN.DependencyConnection -- SYSDYN.DependencyConnection.delayMark --> SYSDYN.DependencyConnection -- SYSDYN.DependencyConnection.strokeWidth --> L0.Float +SYSDYN = + +FL = : SYSDYN.SysdynModelicaFunctionLibrary + + + +FL.minmax : SYSDYN.SysdynModelicaFunction + L0.HasDescription """minmax(expression, minimum, maximum) + +Limits the result of an equation to between the given minimum and maximum values.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + FL.minmax.expression : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + FL.minmax.minimum : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + FL.minmax.maximum : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + FL.minmax.result : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real expression; + input Real minimum; + input Real maximum; + output Real result; +algorithm + result := min(maximum, max(minimum, expression));""" + + + +FL.xidz : SYSDYN.SysdynModelicaFunction + L0.HasDescription """xidz(divident, divisor, x) + +x if divided by zero, divident/divisor otherwise""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + FL.xidz.divident : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + FL.xidz.divisor : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" + FL.xidz.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p/'q" + SYSDYN.SysdynModelicaFunction.definition "Result if divisor = 0" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + FL.xidz.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p/'q" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real divident; + input Real divisor; + input Real x; + output Real z; +algorithm + if divisor > 0.0 or divisor < 0.0 then + z := divident / divisor; + else + z := x; + end if;""" + + + +FL.zidz : SYSDYN.SysdynModelicaFunction + L0.HasDescription "zidz(divident, divisor) + +Zero if divided by zero, divident/divisor otherwise" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + FL.zidz.divident : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + FL.zidz.divisor : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + FL.zidz.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p/'q" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real divident; + input Real divisor; + output Real z; +algorithm + z := xidz(divident,divisor,0.0);""" + + + +FL.interpolate : SYSDYN.SysdynModelicaFunction + L0.HasDescription """interpolate(u, table) + +Interpolate function for two-dimensional table""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + FL.interpolate.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.definition "input value (first column of table)" + FL.interpolate.table : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.definition "table to be interpolated" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + FL.interpolate.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real u "input value (first column of table)"; + input Real table[:, :] "table to be interpolated"; + output Real y "interpolated input value (icol column of table)"; +algorithm + y := interpolateFull(u, table, 2);""" + + + +FL.interpolateFull : SYSDYN.SysdynModelicaFunction + L0.HasDescription """interpolateFull(u, table, icol) + +The full interpolate function""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + FL.interpolateFull.u : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.definition "input value (first column of table)" + FL.interpolateFull.table : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.definition "table to be interpolated" + FL.interpolateFull.icol : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Integer" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.definition "column of table to be interpolated" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + FL.interpolateFull.y : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real u "input value (first column of table)"; + input Real table[:, :] "table to be interpolated"; + input Integer icol "column of table to be interpolated"; + output Real y "interpolated input value (icol column of table)"; +protected + Integer i; + Integer n "number of rows of table"; + Real u1; + Real u2; + Real y1; + Real y2; +algorithm + n := size(table, 1); + if n <= 1 then + y := table[1, icol]; + else + /* Search interval */ + if u <= table[1, 1] then + i := 1; + else + i := 2; + while i < n and u > table[i, 1] loop + i := i + 1; + end while; + i := i - 1; + end if; + + /* Get interpolation data */ + u1 := table[i, 1]; + u2 := table[i + 1, 1]; + y1 := table[i, icol]; + y2 := table[i + 1, icol]; + /* Interpolate */ + if u1 >= u2 then + y := y1; + /* since not possible to throw error */ + else + y := y1 + (y2 - y1)*(u - u1)/(u2 - u1); + end if; + end if;""" \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/graph/SysdynModelingViewpoint.pgraph b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/SysdynModelingViewpoint.pgraph new file mode 100644 index 00000000..8267cfa4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/SysdynModelingViewpoint.pgraph @@ -0,0 +1,248 @@ +L0 = +VP = +SIMU = +PROJECT = +IMAGE = +ACT = +MOD = +STR = +SYSDYN = +SILK = +SHEET = +JFREE = + + +SBC = SYSDYN.ModelingBrowseContext : VP.BrowseContext +SAC = SYSDYN.ModelingActionContext : VP.BrowseContext + VP.BrowseContext.IsIncludedIn PROJECT.ProjectActionContext + +SBC.VariableNodeType +SBC.BuiltinFunctions : VP.ResourceNodeType +SBC.ModuleTypeChildRule : VP.ChildRule +SBC.ModuleContentChildRule : VP.ChildRule +SBC.VariableChildRule : VP.ChildRule +SBC.ExperimentsFolder : VP.ResourceNodeType +SBC.FunctionsFolder : VP.ResourceNodeType +SBC.SharedFunctionsFolder : VP.ResourceNodeType +SBC.Variable : SBC.VariableNodeType + +SBC + @VP.relationChildRuleWithFolder SYSDYN.SysdynModel L0.ConsistsOf SYSDYN.Experiment + SBC.ExperimentsFolder + @VP.relationChildRule SYSDYN.Experiment SYSDYN.Experiment.result SYSDYN.Result + + @VP.customChildRule MBC.Configuration SBC.VariableChildRule + SBC.Variable + @VP.customChildRule SBC.Variable SBC.VariableChildRule + SBC.Variable + + @VP.relationChildRule MBC.Configuration L0.ConsistsOf SHEET.Book + @VP.relationChildRule SHEET.Book L0.ConsistsOf SHEET.Spreadsheet + + + // Function libraries + // Functions folder + @VP.relationChildRuleWithFolder SYSDYN.SysdynModel L0.ConsistsOf SYSDYN.SysdynModelicaFunction + SBC.FunctionsFolder + @VP.relationChildRule SBC.FunctionsFolder L0.ConsistsOf SYSDYN.SysdynModelicaFunctionLibrary + + // Function libraries + @VP.relationChildRule SYSDYN.SysdynModelicaFunctionLibrary L0.ConsistsOf SYSDYN.SysdynModelicaFunctionLibrary + @VP.relationChildRule SYSDYN.SysdynModelicaFunctionLibrary L0.ConsistsOf SYSDYN.SysdynModelicaFunction + @VP.relationChildRule SYSDYN.SharedFunctionOntology L0.ConsistsOf SYSDYN.SysdynModelicaFunctionLibrary + @VP.relationChildRule SYSDYN.SharedFunctionOntology L0.ConsistsOf SYSDYN.SysdynModelicaFunction + + // Built-in functions + VP.BrowseContext.HasChildContribution _ : VP.ChildContribution + VP.ChildContribution.HasParentNodeType SBC.FunctionsFolder + VP.ChildContribution.HasChildNodeType SBC.BuiltinFunctions + VP.ChildContribution.HasRule _ : VP.ConstantChildRule + VP.ConstantChildRule.HasChild BuiltinFunctions + @VP.relationChildRule SBC.BuiltinFunctions L0.ConsistsOf SYSDYN.SysdynModelicaFunctionLibrary + @VP.relationChildRule SBC.BuiltinFunctions L0.ConsistsOf SYSDYN.SysdynModelicaFunction + + // Shared functions linked to a model + @VP.relationChildRuleWithFolder SBC.FunctionsFolder L0.IsLinkedTo SYSDYN.SharedFunctionOntology + SBC.SharedFunctionsFolder + + + // Modules + @VP.equalContentChildRule MOD.StructuralModel + SBC.ModulesFolder : VP.ResourceNodeType + @VP.customChildRule SBC.ModulesFolder SBC.ModuleTypeChildRule + SBC.ModuleSymbol + @VP.customChildRule SBC.ModuleSymbol SBC.ModuleContentChildRule STR.Component + + // Charts + @VP.relationChildRuleWithFolder MOD.StructuralModel L0.ConsistsOf JFREE.Chart + SBC.ChartsFolder : VP.ResourceNodeType + +// Labels +SBC.VariableNameLabelRule : VP.LabelRule +SBC.ModuleTypeLabelRule : VP.LabelRule + +SBC + @VP.constantLabelRule SBC.ExperimentsFolder "Experiments" + @VP.constantLabelRule SBC.FunctionsFolder "Functions" + @VP.constantLabelRule SBC.ChartsFolder "Charts" + @VP.constantLabelRule SBC.ModulesFolder "Modules" + @VP.constantLabelRule SBC.SharedFunctionsFolder "Shared Functions" + @VP.constantLabelRule SHEET.Book "Spreadsheets" + + @VP.customLabelRule SIMU.Run PROJECT.ProjectBrowseContext.RunLabelRule + @VP.customLabelRule SBC.BuiltinFunctions VP.ResourceNameLabelRule + @VP.customLabelRule SBC.ModuleSymbol SBC.ModuleTypeLabelRule + @VP.customLabelRule SBC.Variable SBC.VariableNameLabelRule + @VP.customLabelRule SHEET.Spreadsheet VP.ResourceNameLabelRule + @VP.customLabelRule SYSDYN.HistoryDataset VP.ResourceLabelLabelRule + @VP.customLabelRule JFREE.Chart VP.ResourceLabelLabelRule + +// Modifiers +SBC + @VP.customLabelRule SYSDYN.SysdynModelicaFunction VP.ResourceNameModifierRule + @VP.customLabelRule SYSDYN.HistoryDataset VP.ResourceLabelModifierRule + @VP.customLabelRule JFREE.Chart VP.ResourceLabelModifierRule + @VP.customLabelRule SBC.FunctionsFolder VP.NoModifierRule + + +// Decorations +SBC.ActiveLabelDecorationRule : VP.ConstantLabelDecorationRule + VP.ConstantLabelDecorationRule.HasFormat "%s [ACTIVE]" + VP.ConstantLabelDecorationRule.HasStyle "B" + + +// Images +SBC.VariableImageRule : VP.ImageRule +SBC.ChartImageRule : VP.ImageRule +SBC.ResultImageRule : VP.ImageRule + +SBC + @VP.customImageRule SBC.Variable SBC.VariableImageRule + @VP.customImageRule JFREE.Chart SBC.ChartImageRule + @VP.customImageRule SYSDYN.Result SBC.ResultImageRule + + + @VP.constantImageRule SBC.ExperimentsFolder SILK.folder + @VP.constantImageRule SBC.FunctionsFolder SILK.folder + @VP.constantImageRule SBC.SharedFunctionsFolder SILK.folder_link + @VP.constantImageRule SYSDYN.SysdynModelicaFunctionLibrary SILK.folder + @VP.constantImageRule SYSDYN.SysdynModelicaFunction SILK.brick + @VP.constantImageRule SBC.ModulesFolder SILK.folder + @VP.constantImageRule SBC.ModuleSymbol SILK.bricks + @VP.constantImageRule SBC.BuiltinFunctions SILK.folder_link + @VP.constantImageRule SYSDYN.SharedFunctionOntology SILK.folder_link + @VP.constantImageRule SHEET.Book SILK.table_multiple + @VP.constantImageRule SHEET.Spreadsheet SILK.table + @VP.constantImageRule SYSDYN.BasicExperiment SILK.time + @VP.constantImageRule SYSDYN.PlaybackExperiment SILK.timeline_marker + @VP.constantImageRule SBC.ChartsFolder SILK.folder + @VP.constantImageRule SYSDYN.HistoryDataset SILK.table + +SBC + // Active experiment + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType SYSDYN.Experiment + VP.VisualsContribution.HasCondition _ : VP.HasStatementTest + VP.HasStatementTest.HasRelation SIMU.IsActive + VP.VisualsContribution.HasRule SBC.ActiveLabelDecorationRule + + // Show result in charts + VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution + VP.VisualsContribution.HasNodeType SYSDYN.Result + VP.VisualsContribution.HasCondition _ : VP.HasStatementTest + VP.HasStatementTest.HasRelation SYSDYN.Result.showResult + VP.VisualsContribution.HasRule SBC.ActiveLabelDecorationRule + + +// Actions +ACTIONS = SAC.Actions : L0.Library + +// NEW -Actions +ACTIONS.NewModuleType : ACT.Action +ACTIONS.NewEnumeration : ACT.Action +ACTIONS.NewFunction : ACT.Action +ACTIONS.NewFunctionLibrary : ACT.Action +ACTIONS.NewSharedFunctionLibrary : ACT.Action +ACTIONS.NewExperiment : ACT.Action +ACTIONS.NewSimulationPlaybackExperiment : ACT.Action +ACTIONS.NewLineChart : ACT.Action +ACTIONS.NewBarChart : ACT.Action +ACTIONS.NewPieChart : ACT.Action +ACTIONS.NewSheet : ACT.Action +ACTIONS.NewHistoryData : ACT.Action + +SAC + @VP.actionContribution "Module" SBC.ModulesFolder SILK.bricks VP.NewActionCategory ACTIONS.NewModuleType + @VP.actionContribution "Enumeration" MBC.Configuration SILK.brick VP.NewActionCategory ACTIONS.NewEnumeration + @VP.actionContribution "Enumeration" SBC.ModuleSymbol SILK.brick VP.NewActionCategory ACTIONS.NewEnumeration + @VP.actionContribution "Function" SBC.FunctionsFolder SILK.brick VP.NewActionCategory ACTIONS.NewFunction + @VP.actionContribution "Function" SYSDYN.SysdynModelicaFunctionLibrary SILK.brick VP.NewActionCategory ACTIONS.NewFunction + @VP.actionContribution "Function" SYSDYN.SharedFunctionOntology SILK.brick VP.NewActionCategory ACTIONS.NewFunction + @VP.actionContribution "Function Library" SBC.FunctionsFolder SILK.folder VP.NewActionCategory ACTIONS.NewFunctionLibrary + @VP.actionContribution "Function Library" SYSDYN.SysdynModelicaFunctionLibrary SILK.folder VP.NewActionCategory ACTIONS.NewFunctionLibrary + @VP.actionContribution "Function Library" SYSDYN.SharedFunctionOntology SILK.folder VP.NewActionCategory ACTIONS.NewFunctionLibrary + @VP.actionContribution "Shared Function Library" SBC.SharedFunctionsFolder SILK.folder VP.NewActionCategory ACTIONS.NewSharedFunctionLibrary + @VP.actionContribution "Experiment" SBC.ExperimentsFolder SILK.time VP.NewActionCategory ACTIONS.NewExperiment + @VP.actionContribution "Simulation Playback Experiment" SBC.ExperimentsFolder SILK.timeline_marker VP.NewActionCategory ACTIONS.NewSimulationPlaybackExperiment + @VP.actionContribution "Line Chart" SBC.ChartsFolder SILK.chart_line VP.NewActionCategory ACTIONS.NewLineChart + @VP.actionContribution "Pie Chart" SBC.ChartsFolder SILK.chart_pie VP.NewActionCategory ACTIONS.NewPieChart + @VP.actionContribution "Bar Chart" SBC.ChartsFolder SILK.chart_bar VP.NewActionCategory ACTIONS.NewBarChart + @VP.actionContribution "Sheet" SHEET.Book SILK.table VP.NewActionCategory ACTIONS.NewSheet + @VP.actionContribution "History Data" SYSDYN.Experiment SILK.table VP.NewActionCategory ACTIONS.NewHistoryData + + +// Drop actions +ACTIONS.FunctionDropAction : ACT.DropAction +ACTIONS.ChartDropAction : ACT.DropAction + +SBC + @VP.dropActionContribution SBC.FunctionsFolder ACTIONS.FunctionDropAction 1.0 + @VP.dropActionContribution SYSDYN.SysdynModelicaFunction ACTIONS.FunctionDropAction 1.0 + @VP.dropActionContribution SYSDYN.SysdynModelicaFunctionLibrary ACTIONS.FunctionDropAction 1.0 + @VP.dropActionContribution SYSDYN.SharedFunctionOntology ACTIONS.FunctionDropAction 1.0 + @VP.dropActionContribution JFREE.Chart ACTIONS.ChartDropAction 1.0 + diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/graph/Validation.pgraph b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/Validation.pgraph new file mode 100644 index 00000000..cfa53e0b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/Validation.pgraph @@ -0,0 +1,206 @@ +L0 = +L0X = +ISSUE = +SYSDYN = +STR = + +VALIDATIONS = SYSDYN.Validations : L0.Library + +VALIDATIONS.Issue -- VALIDATIONS.Issue.stringContexts --> L0.List -- VALIDATIONS.Units.UnitIssueSource.allowEquivalents >-- L0.Boolean +SYSDYN = + +VF = : SYSDYN.SysdynModelicaFunctionLibrary + +/* +VF.DELAYFIXED : SYSDYN.SysdynModelicaFunction + L0.HasDescription """DELAY FIXED( inputVar , dtime , init ) + -> delay(inputVar, dtime) + init -value is ignored.""" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real inputVar; + input Real dtime; + input Real init; + input Real t = time; + output Real z; +protected + parameter Real parameterDTime = dtime; +algorithm + z := if time < parameterDTime then init else delay(inputVar, parameterDTime);""" +*/ + + + +VF.IFTHENELSE : SYSDYN.SysdynModelicaFunction + L0.HasDescription """IFTHENELSE( cond , ontrue , onfalse ) + +Returns ontrue if cond, otherwise onfalse""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.IFTHENELSE.cond : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "1" + VF.IFTHENELSE.ontrue : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + VF.IFTHENELSE.onfalse : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.IFTHENELSE.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Boolean cond; + input Real ontrue; + input Real onfalse; + output Real z; +algorithm + z := if cond then ontrue else onfalse;""" + + + +VF.MAX : SYSDYN.SysdynModelicaFunction + L0.HasDescription """MAX(a, b) + +Returns the larger of a and b.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.MAX.a : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + VF.MAX.b : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.MAX.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real a; + input Real b; + output Real z; +algorithm + z := if a > b then a else b;""" + + + +VF.MIN : SYSDYN.SysdynModelicaFunction + L0.HasDescription """MIN(a, b) + +Returns the smaller of a and b.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.MIN.a : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + VF.MIN.b : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.MIN.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real a; + input Real b; + output Real z; +algorithm + z := if a < b then a else b;""" + + + +VF.XIDZ : SYSDYN.SysdynModelicaFunction + L0.HasDescription """XIDZ(a, b, x) + +x if divided by zero, a/b otherwise.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.XIDZ.a : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + VF.XIDZ.b : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" + VF.XIDZ.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p/'q" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.XIDZ.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p/'q" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real a; + input Real b; + input Real x; + output Real z; +algorithm + z := xidz(a, b, x);""" + + + +VF.ZIDZ : SYSDYN.SysdynModelicaFunction + L0.HasDescription """ZIDZ(a, b) + +Zero if divided by zero, a/b otherwise.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.ZIDZ.a : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + VF.ZIDZ.b : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'q" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.ZIDZ.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p/'q" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real a; + input Real b; + output Real z; +algorithm + z := zidz(a, b);""" + + + +VF.ABS : SYSDYN.SysdynModelicaFunction + L0.HasDescription """ABS(x) + +Returns the absolute value of x.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.ABS.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.ABS.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := abs(x);""" + + + +VF.SQRT : SYSDYN.SysdynModelicaFunction + L0.HasDescription """SQRT(x) + +Returns the square root of x.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.SQRT.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.SQRT.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := sqrt(x);""" + + + +VF.MODULO : SYSDYN.SysdynModelicaFunction + L0.HasDescription """MODULO(a, b) + +Returns the remainder when a is divided by b. """ + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.MODULO.a : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + VF.MODULO.b : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.MODULO.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real a; + input Real b; + output Real z; +algorithm + z := mod(a, b);""" + + + +VF.PULSE : SYSDYN.SysdynModelicaFunction + L0.HasDescription """PULSE(start, width) + +Returns 1.0 starting at time start and lasting for interval width. 0.0 is returned at other times.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.PULSE.start : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" + VF.PULSE.width : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.PULSE.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real start; + input Real width; + input Real t = time; + output Real z; +algorithm + z := if t >= start and (t - start) <= width then 1.0 else 0.0;""" + + + +VF.RAMP : SYSDYN.SysdynModelicaFunction + L0.HasDescription """RAMP(slope, startTime, endTime) + +Returns 0 until the start time and then slopes upward until end time and then holds constant.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.RAMP.slope : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + VF.RAMP.startTime : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" + VF.RAMP.endTime : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.RAMP.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real slope; + input Real startTime; + input Real endTime; + input Real t = time; + output Real z; +algorithm + z := + if t > startTime then + if t < endTime then + slope * (t - startTime) + else + slope * (endTime - startTime) + else + 0;""" + + + +VF.STEP : SYSDYN.SysdynModelicaFunction + L0.HasDescription """STEP(height, stepTime) + +Returns 0.0 until the step time and then returns height.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.STEP.height : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "'p" + VF.STEP.stepTime : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "TIME" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.STEP.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "'p" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real height; + input Real stepTime; + input Real t = time; + output Real z; +algorithm + z := if t >= stepTime then height else 0.0;""" + + + +/* Continuous built-in common mathematical functions */ + +VF.EXP : SYSDYN.SysdynModelicaFunction + L0.HasDescription """EXP(x) + +Exponential, base e.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.EXP.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.EXP.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := exp(x);""" + + + +VF.SIN : SYSDYN.SysdynModelicaFunction + L0.HasDescription """SIN(x) + +Returns the sine of x.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.SIN.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.SIN.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := sin(x);""" + + + +VF.SINH : SYSDYN.SysdynModelicaFunction + L0.HasDescription """SINH(x) + +Returns the hyperbolic sine of x.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.SINH.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.SINH.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := sinh(x);""" + + + +VF.COS : SYSDYN.SysdynModelicaFunction + L0.HasDescription """COS(x) + +Returns the cosine of x.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.COS.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.COS.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := cos(x);""" + + + +VF.COSH : SYSDYN.SysdynModelicaFunction + L0.HasDescription """COSH(x) + +Returns the hyperbolic cosine of x.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.COSH.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.COSH.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := cosh(x);""" + + + +VF.TAN : SYSDYN.SysdynModelicaFunction + L0.HasDescription """TAN(x) + +Returns the tangent of x.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.TAN.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.TAN.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := tan(x);""" + + + +VF.TANH : SYSDYN.SysdynModelicaFunction + L0.HasDescription """TANH(x) + +Returns the hyperbolic tangent of x.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.TANH.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.TANH.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := tanh(x);""" + + + +VF.LN : SYSDYN.SysdynModelicaFunction + L0.HasDescription """LN(x) + +Returns the natural logarithm of x. + +In modelica log(x) is the natural logarighm and log10(x) is base 10 logarighm.""" + SYSDYN.SysdynModelicaFunction.inputs _ : L0.List + @L0.list + VF.LN.x : SYSDYN.SysdynModelicaFunction.Input + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.optional false + SYSDYN.SysdynModelicaFunction.unit "ANY" + SYSDYN.SysdynModelicaFunction.outputs _ : L0.List + @L0.list + VF.LN.z : SYSDYN.SysdynModelicaFunction.Output + SYSDYN.Variable.type "Real" + SYSDYN.SysdynModelicaFunction.unit "1" + SYSDYN.SysdynModelicaFunction.modelicaFunctionCode """ input Real x; + output Real z; +algorithm + z := log(x);""" + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/graph/WorkModel.pgraph b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/WorkModel.pgraph new file mode 100644 index 00000000..de9d0ea7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/graph/WorkModel.pgraph @@ -0,0 +1,751 @@ +L0 = +L0X = +G2D = +STR = +DIA = +SIMU = +MOD = +SYSDYN = +PROJ = + +//###################################################################### +//# Example work model with two modules +//###################################################################### + +/* +WM = : PROJ.Project + @L0.new +*/ + +/* +WM = : PROJ.Project + @L0.new + + +TAGS = WM.Tags : L0.Library + + +WM.dependency : L0.Template + @template %type %head %tail %angle + %type + @L0.tag TAGS.AdminIsVisible + @L0.tag TAGS.AdminIsFocusable + STR.HasConnectionType SYSDYN.SysdynConnectionType + SYSDYN.Dependency.angle %angle + DIA.HasArrowConnector _ : DIA.Connector + SYSDYN.HasHeadTerminal %head + DIA.AreConnected _ : DIA.Connector + SYSDYN.HasTailTerminal %tail + DIA.IsPlainConnectorOf %type + +WM.flow : L0.Template + @template %type %head %tail + %type + @L0.tag TAGS.AdminIsVisible + @L0.tag TAGS.AdminIsFocusable + STR.HasConnectionType SYSDYN.SysdynConnectionType + DIA.HasArrowConnector _ : DIA.Connector + SYSDYN.HasHeadTerminal %head + DIA.AreConnected _ : DIA.Connector + SYSDYN.HasTailTerminal %tail + DIA.IsPlainConnectorOf %type + +WM.conf_dependency : L0.Template + @template %type %head %tail + %type + @L0.tag MOD.Mapped + SYSDYN.HasHead %head + SYSDYN.HasTail %tail + +WM.conf_dependency_ref : L0.Template + @template %type %head %tail %ref + %type + @L0.tag MOD.Mapped + SYSDYN.HasHead %head + SYSDYN.HasTail %tail + SYSDYN.Dependency.refersTo %ref + + + +WM.WorkSymbol + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/mdl2pgraph.pl b/dev-jkauttio/org.simantics.sysdyn.ontology/mdl2pgraph.pl new file mode 100755 index 00000000..b8e1a1cf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/mdl2pgraph.pl @@ -0,0 +1,660 @@ +#!/usr/bin/perl +# +# Script for converting Vensim .mdl files into Simantics .pgraph files +# + +use strict; +use warnings; +use Data::Dumper; + +die("Usage:\n\tparser.pl [filetoparse] [targetfile]") if($#ARGV < 1); + +sub trim($) { + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} + +# Equation parser +# See http://www.perlmonks.org/?node_id=678119 + +my @token_def = ( + [Whitespace => qr{\s+}, 1], + [Comment => qr{#.*\n?$}m, 1], + [AddOp => qr{[+-]} ], + [MulOp => qr{[*/]} ], + [Number => qr{(\d\.)+} ], + [Equals => qr{=} ], + [Lt => qr{<} ], + [Gt => qr{>} ], + [OpenParen => qr{\(} ], + [CloseParen => qr{\)} ], + [Comma => qr{,} ], + [If => qr{IFTHENELSE} ], + [Xls => qr{GETXLSCONSTANTS} ], + [XlsData => qr{GETXLSDATA} ], + [TimeShift => qr{TIMESHIFT} ], + [VectorMap => qr{VECTORELMMAP} ], + [Sum => qr{SUM} ], + [Integ => qr{INTEG} ], + [Str => qr{'[^']+'} ], + [Array => qr{[0-9\w]+\[[^\]]+\]} ], + [Variable => qr{[0-9\w]+} ], +); + +sub parseEquation($) { + my $input = shift; + my @tokens; + pos($input) = 0; + + while(pos($input) < length $input){ + my $matched = 0; + for my $t (@token_def){ + my ($name, $re, $ignore_flag) = @$t; + if ($input =~ m/\G($re)/gc){ + $matched = 1; + next if $ignore_flag; + push @tokens, [$name, $1]; + next; + } + } + unless($matched) { + print "Syntax error at position " . pos($input).": $input\n"; + return; + } + } + return token2str(\@tokens); +} + +sub match { + my $tokens = shift; + my $expected_token = shift; + if ($tokens->[0][0] eq $expected_token){ + my $current = shift @$tokens; + return $current->[1]; + } else { + print "Syntax error: expected $expected_token, got $tokens->[0][0]\n"; + } +} + +sub lookahead { + my $tokens = shift; + my @expected = @_; + no warnings 'uninitialized'; + for (0 .. $#expected){ + return 0 if $tokens->[$_][0] ne $expected[$_]; + } + return 1; +} + +# +# Parse vensim equations and convert to modelica equations +# NOTE: This is not a bullet proof solution, but does parse correctly formed Vensim equations +# FIXME: Find corresponding modelica version for the functions that are currently not transformed +# +sub token2str { + my $tokens = shift; + my $rval = ""; + + if (lookahead($tokens, 'Integ')){ + # Stock. + match($tokens, 'Integ'); + match($tokens, 'OpenParen'); + my $a = token2str($tokens); + match($tokens, 'Comma'); + my $b = token2str($tokens); + match($tokens, 'CloseParen'); +# $rval = "INTEG($a, $b)"; # Integ function will be replaced with stock component, and it has only initial value ? + $rval = $b; # FIXME! + } elsif (lookahead($tokens, 'If')){ + match($tokens, 'If'); + match($tokens, 'OpenParen'); + my $check = token2str($tokens); + match($tokens, 'Comma'); + my $then = token2str($tokens); + match($tokens, 'Comma'); + my $else = ""; + if (lookahead($tokens, 'If')){ + match($tokens, 'If'); + match($tokens, 'OpenParen'); + my $subcheck = token2str($tokens); + match($tokens, 'Comma'); + my $subthen = token2str($tokens); + match($tokens, 'Comma'); + my $subelse = token2str($tokens); # TODO doesn't support elseif yet.. + match($tokens, 'CloseParen'); + $else = "elseif $subcheck then $subthen else $subelse"; + } else { + $else = "else ".token2str($tokens).""; + } + match($tokens, 'CloseParen'); + $rval = "if $check then $then ".$else.""; # Apparently, end if is not used inside equations.. + } elsif (lookahead($tokens, 'Xls')){ + match($tokens, 'Xls'); + match($tokens, 'OpenParen'); + my $a = match($tokens, 'Str'); + match($tokens, 'Comma'); + my $b = match($tokens, 'Str'); + match($tokens, 'Comma'); + my $c = match($tokens, 'Str'); + match($tokens, 'CloseParen'); + $rval = "XLS_CONSTANT($a, $b, $c)"; + } elsif (lookahead($tokens, 'XlsData')){ + match($tokens, 'XlsData'); + match($tokens, 'OpenParen'); + my $a = match($tokens, 'Str'); + match($tokens, 'Comma'); + my $b = match($tokens, 'Str'); + match($tokens, 'Comma'); + my $c = match($tokens, 'Str'); + match($tokens, 'Comma'); + my $d = match($tokens, 'Str'); + match($tokens, 'CloseParen'); + $rval = "XLS_DATA($a, $b, $c, $d)"; + } elsif (lookahead($tokens, 'VectorMap')){ + match($tokens, 'VectorMap'); + match($tokens, 'OpenParen'); + my $a = token2str($tokens); # Should be a variable, but we can use token2str to parse it anyway + match($tokens, 'Comma'); + my $b = token2str($tokens); # Should be a number, but we can use token2str to parse it anyway + match($tokens, 'CloseParen'); + $rval = "VECTOR_MAP($a, $b)"; # + } elsif (lookahead($tokens, 'TimeShift')){ + match($tokens, 'TimeShift'); + match($tokens, 'OpenParen'); + my $var = token2str($tokens); # Should be a variable, but we can use token2str to parse it anyway + match($tokens, 'Comma'); + my $num = token2str($tokens); # Should be a number, but we can use token2str to parse it anyway + match($tokens, 'CloseParen'); + $rval = "delay($var, $num)"; # FIXME: Not sure if this is correct.. + } elsif (lookahead($tokens, 'Sum')){ + match($tokens, 'Sum'); + match($tokens, 'OpenParen'); + my $var = token2str($tokens); # Should be a variable, but we can use token2str to parse it anyway + match($tokens, 'CloseParen'); + $rval = "sum($var)"; + } elsif (lookahead($tokens, 'Array')){ + my $var = match($tokens, 'Array'); + $rval = $var; + } elsif (lookahead($tokens, 'Variable')){ + my $var = match($tokens, 'Variable'); + $rval = $var; + } elsif (lookahead($tokens, 'AddOp')){ + my $op = match($tokens, 'AddOp'); + $rval = $op; + } elsif (lookahead($tokens, 'MulOp')){ + my $op = match($tokens, 'MulOp'); + $rval = $op; + } elsif (lookahead($tokens, 'Number')){ + my $n = match($tokens, 'Number'); + $rval = $n; + } elsif (lookahead($tokens, 'Equals')){ + my $n = match($tokens, 'Equals'); + $rval = $n.$n; # In modelica we must use two times = (This should be used only in if statements..) + } elsif (lookahead($tokens, 'Lt')){ + my $n = match($tokens, 'Lt'); + $rval = $n; + } elsif (lookahead($tokens, 'Gt')){ + my $n = match($tokens, 'Gt'); + $rval = $n; + } elsif (lookahead($tokens, 'OpenParen')){ + match($tokens, 'OpenParen'); + my $inner = token2str($tokens); + match($tokens, 'CloseParen'); + $rval = "($inner)"; + } else { + return ""; + } + my $next = token2str($tokens); + return $rval.$next; +} + +# And finally the actual program + +my $sourcefile = $ARGV[0]; +my $targetfile = $ARGV[1]; + +open(DAT, $sourcefile) || die("Could not open source file for reading!"); +my @raw_data=; +close(DAT); + +my $elements = {}; + +# 1. Parse equations + +my $text = join("\n", @raw_data); +while($text =~ m/(.*)(:=|=|:)([^~]*)~([^~]*)~([^\|]*)/mg) { + my $var = trim($1); + my $op = $2; + my $equation = trim($3); + my $unit = trim($4); + my $comment = trim($5); # May include also "~ :SUPPLEMENTARY" + + $var =~ s/\[.*//g; # Remove the array part from the end ( foo[bar] => foo ) + + $equation =~ s/[\n\s\\]//g; # Remove white spaces, line breaks and backslashes (backslash seems to be used to break equation into two lines). + my $type = ""; + # FIXME: No idea what is the exact difference of these: +# if($op =~ m/^:=$/) { +# $type = "VARIABLE"; +# } elsif($op =~ m/^:$/) { +# $type = "CONSTANT"; +# } else { +# $type = "EQUATION"; +# } + $type = "auxiliary"; + if($equation =~ m/^\s*INTEG\(/) { # If equation is integral, the element type is stock. + $type = "stock"; + } + # TODO: is there any way to detect valve? + + # Convert equation to modelica format + my $modelica_equation = parseEquation($equation); + if($modelica_equation =~ m/^\+if/) { # FIXME: Not sure why "+ IF THEN ELSE" is used in Vensim.. + $modelica_equation =~ s/^\+//g; + } + $modelica_equation =~ s/\+-/-/g; # For some reason there is +- ... which means same as - + if($elements->{$var}) { + push(@{$elements->{$var}->{'equations'}}, $modelica_equation); + } else { + my @eq = ($modelica_equation); + $elements->{$var} = {name => $var, + type => $type, + equations => \@eq, + unit => $unit, + comment => $comment}; + } +} + +my $diagrams = {}; +my $connections = {}; +my $ghost_symbols = {}; +my $types = {}; + +# 2. Parse diagram layout +# i.e., the part after this: +# \\\---/// Sketch information - do not modify anything except names +# V300 Do not put anything below this section - it will be ignored +# + +my $diagram; +foreach my $row (@raw_data) { + # Lines starting with * indicates new diagram configuration.. + if($row =~ m/^\*\w/) { + $diagram = trim($row); + $diagram =~ s/^(\*)//; + } + if($diagram) { + if($row =~ m/^1\d*,/) { + my @data = split(/,/, $row); + my $type = $data[0]; + my $id = $data[1]; + if($type == 1) { + # Connection + # 1,6,1,5,1,0,0,0,0,64,0,-1--1--1,,1|(729,352)| + # 1,546,138,3,0,0,0,0,0,64,1,-1--1--1,,1|(-1642,-250)| <- this connection is not visible in vensim? + # Flow + # 1,33,35,8,4,0,0,22,0,0,0,-1--1--1,,1|(456,528)| + + my $target = $data[2]; + my $source = $data[3]; + my $foo = $data[4]; # If this is 100, the flow direction must be changed (Yeah, wtf?) + my $t = $data[9] == 64 ? "dependency" : "flow"; + my $hidden = $data[10] == 1 ? 1 : 0; # TODO: Not sure if this is correct + if($t eq "flow" && $foo == 100) { + my $tmp = $target; + $target = $source; + $source = $tmp; + } + + $connections->{$diagram} = {} unless($connections->{$diagram}); + $connections->{$diagram}->{$id} = {source => $source, target => $target, type => $t, hidden => $hidden}; + } elsif($type == 10) { + # Element + # 10,1,TotalPopulation,417,269,47,65,3,131,0,0,0,0,0,0 <- not sure, might be stock (but actually is auxiliary9 + # 10,11,TotalPopulationT1,417,610,47,65,3,131,0,0,0,0,0,0 <- what is this? + # 10,274,LungCsIVNoD,-1050,1269,40,20,3,3,0,0,0,0,0,0 <- level aka stock? + # 10,2,LungCs01,-1109,-650,79,18,3,131,0,0,0,0,0,0 <- stock + # 10,786,LungCSmokersPercentageOfPopulation,-700,-835,147,21,8,131,0,0,0,0,0,0 <- input? + # 10,63,LungCProgress0102Rate,-1248,-541,91,9,8,3,0,0,0,0,0,0 <- aux ? + # 10,125,LungCModelPopCorrectionRate,1582,65,105,9,8,3,0,0,0,0,0,0 <- constant (FIXME: seems to be identical with aux) + # 10,152,LungCTreated1PopCorr,287,269,102,9,40,3,1,0,-1,0,0,0 <- valve + + my $name = $data[2]; + my $x = $data[3]; + my $y = $data[4]; + my $width = $data[5]; + my $height = $data[6]; + my $foo = $data[7]; + my $bar = $data[8]; # 131 for stock, 3 for aux + my $t = "unknown"; #$data[11] == -1 ? "valve" : "stock"; # -1 for valve, 0 for stock ? + my $ghost = 0; + if($#data > 15) { # Ghost symbols contains more parameters.. + # 10,505,LungCs01Diagnosis, -808,-633, 64,9,40,3,0,0,-1,0,0,0 + # 10,590,LungCs01Diagnosis, 2614,1033, 73,9,8, 2,0,3,-1,0,0,0,128-128-128,0-0-0,|12||128-128-128 + $ghost = 1; + } + + if($foo == 3 && $bar == 3) { + $t = "stock"; + } elsif($foo == 3 && $bar == 131) { + $t = "auxiliary"; # FIXME: + } elsif($foo == 8 && $bar == 131) { + $t = "auxiliary"; + } elsif($foo == 40 && $bar == 3) { + $t = "valve"; + } elsif($bar == 3) { + $t = "auxiliary"; + } else { + $t = "valve"; + } + if(!$ghost) { + $types->{$name} = $t; + } + + $diagrams->{$diagram} = {} unless($diagrams->{$diagram}); + $diagrams->{$diagram}->{$id} = { + id => $id, + name => $name, + x => $x, + y => $y, + width => $width, + height => $height, + type => $t, + ghost => $ghost + }; + if($t eq "valve" && $ghost_symbols->{$id}) { + $diagrams->{$diagram}->{($ghost_symbols->{$id})} = $diagrams->{$diagram}->{$id}; + } + } elsif($type == 11) { + # Valve + # 11,48,48,-1348,-887,6,8,34,3,0,0,1,0,0,0 + my $x = $data[3]; + my $y = $data[4]; + + # This data is very much related to the valve symbol on the next line .. + $ghost_symbols->{$id+1} = $id; + } elsif($type == 12) { + # Textbox (can be ignored, the string is on the next line) + # 12,2,0,430,56,114,34,8,132,0,0,-1,0,0,0 + # Cloud + # 12,45,48,-1553,-888,10,8,0,3,0,0,-1,0,0,0 + + my $x = $data[3]; + my $y = $data[4]; + my $foo = $data[7]; + my $bar = $data[8]; # 132 for textbox, 3 for cloud + if($bar == 3) { + $diagrams->{$diagram} = {} unless($diagrams->{$diagram}); + $diagrams->{$diagram}->{$id} = { + id => $id, + name => "Cloud".$id, # Cloud does not have name, but we can generate one + x => $x, + y => $y, + type => 'cloud', + ghost => 0}; + $types->{"Cloud".$id} = 'cloud'; + } + } + } else { + # Comment or something... + } + } +} + +# 3. Generate .pgraph file +my $generated_elements = {}; +my $generated_symbols = {}; + +# Create combined configuration +my $output = ""; +foreach my $key (keys (%$diagrams)) { + my $d = $key; + $d =~ s/\s+//g; + my $WC = "CMC"; + + my $tmp = $diagrams->{$key}; + foreach my $id (keys (%$tmp)) { + my $n = $tmp->{$id}->{'name'}; + if($tmp->{$id}->{'ghost'} == 1) { # Ghost does not contain correct element type + next; + } + my $type = $tmp->{$id}->{'type'}; + no warnings 'uninitialized'; + $type = "stock" if($elements->{$n}->{'type'} eq "stock"); + + if($type eq "cloud") { + # Cloud is not a real element, thus it is not present in elements array.. + $output .= $WC.".".$tmp->{$id}->{'name'}." : SYSDYN.Cloud\n"; + $output .= "\n"; + } elsif($elements->{$n} && $elements->{$n}->{'name'} && !$generated_elements->{$elements->{$n}->{'name'}}) { + if($type eq "valve") { + $output .= $WC.".".$elements->{$n}->{'name'}." : SYSDYN.Valve\n"; + $output .= " \@L0.tag MOD.Mapped\n"; + $output .= " SYSDYN.HasExpressions _ : SYSDYN.Expressions\n"; + $output .= " \@L0.orderedSet\n"; + my $equations = $elements->{$n}->{'equations'}; + foreach my $equation (@$equations) { + $output .= " _ : SYSDYN.NormalExpression\n"; + $output .= " SYSDYN.HasEquation \"".$equation."\" \n"; + } + } elsif($type eq "stock") { + $output .= $WC.".".$elements->{$n}->{'name'}." : SYSDYN.Stock\n"; + $output .= " \@L0.tag MOD.Mapped\n"; + $output .= " SYSDYN.HasExpressions _ : SYSDYN.Expressions\n"; + $output .= " \@L0.orderedSet\n"; + my $equations = $elements->{$n}->{'equations'}; + foreach my $equation (@$equations) { + $output .= " _ : SYSDYN.StockExpression\n"; + $output .= " SYSDYN.HasInitialEquation \"".$equation."\" \n"; + } + $output .= "\n"; + } elsif($type eq "auxiliary") { + $output .= $WC.".".$elements->{$n}->{'name'}." : SYSDYN.Auxiliary\n"; + $output .= " \@L0.tag MOD.Mapped\n"; + $output .= " SYSDYN.HasExpressions _ : SYSDYN.Expressions\n"; + $output .= " \@L0.orderedSet\n"; + my $equations = $elements->{$n}->{'equations'}; + foreach my $equation (@$equations) { + $output .= " _ : SYSDYN.NormalExpression\n"; + $output .= " SYSDYN.HasEquation \"".$equation."\" \n"; + } + $output .= "\n"; + } else { + print("Unknown element type: $type\n"); + } + } + $generated_elements->{$elements->{$n}->{'name'}} = 1; + } + + my $c = $connections->{$key}; + foreach my $id (keys (%$c)) { + my $source = $tmp->{$c->{$id}->{'source'}}->{'name'}; + my $target = $tmp->{$c->{$id}->{'target'}}->{'name'}; + if($source && $target) { + if($c->{$id}->{'type'} eq "flow") { + $output .= $WC.".f".$id." : SYSDYN.Flow\n"; + $output .= " \@WM.conf_dependency ".$WC.".".$source." ".$WC.".".$target."\n"; + } elsif($c->{$id}->{'type'} eq "dependency") { + $output .= $WC.".d".$id." : SYSDYN.Dependency\n"; + $output .= " \@WM.conf_dependency ".$WC.".".$source." ".$WC.".".$target."\n"; + } else { + print("Unknown connection type ".$c->{$id}->{'type'}."\n"); + } + } else { + print("WARNING: "); + print("No source element for connection #".$c->{$id}->{'source'}." -> $target\n") if($target); + print("No target element for connection $source -> #".$c->{$id}->{'target'}."\n") if($source); + } + } + $output .= "\n"; +} + +# Create combined diagram +my $max_x = 0; # FIXME: Assumes that there are positive locations.. +foreach my $key (keys (%$diagrams)) { + my $d = $key; + $d =~ s/\s+//g; + + my $WC = "CMC"; + my $tmp = $diagrams->{$key}; + unless($key eq "Population") { + $output .= $d."ConfigurationDiagram : SYSDYN.ConfigurationDiagram {$id}->{'name'}; + my $suffix = "Element".$tmp->{$id}->{'id'}; # id field in hash might be different than $id (see parsing of type 11 and type 10 elements) + + if(!$generated_symbols->{$n.$suffix}) { + my $x = sprintf("%.1f", $tmp->{$id}->{'x'} / 5 + $offset_x); # Scale + my $y = sprintf("%.1f", $tmp->{$id}->{'y'} / 5); # Scale + $max_x = $x if(($tmp->{$id}->{'x'} / 5 + $offset_x) > $max_x) ; + my $type = $types->{$n}; # Type lookup contains correct type (ghosts does not..) + $type = "stock" if($elements->{$n}->{'type'} eq "stock"); + + if($type eq "stock") { + $output .= " ".$n.$suffix." : SYSDYN.StockSymbol\n"; + $output .= " MOD.ElementToComponent ".$WC.".$n\n"; + $output .= " DIA.HasTransform [1.0, 0.0, 0.0, 1.0, ".$x.", ".$y."] : G2D.Transform\n"; + } elsif($type eq "auxiliary") { + $output .= " ".$n.$suffix." : SYSDYN.AuxiliarySymbol\n"; + $output .= " MOD.ElementToComponent ".$WC.".$n\n"; + $output .= " DIA.HasTransform [1.0, 0.0, 0.0, 1.0, ".$x.", ".$y."] : G2D.Transform\n"; + } elsif($type eq "valve") { + $output .= " ".$n.$suffix." : SYSDYN.ValveSymbol\n"; + $output .= " MOD.ElementToComponent ".$WC.".$n\n"; + $output .= " DIA.HasTransform [1.0, 0.0, 0.0, 1.0, ".$x.", ".$y."] : G2D.Transform\n"; + } elsif($type eq "input") { + $output .= " ".$n.$suffix." : SYSDYN.InputSymbol\n"; + $output .= " MOD.ElementToComponent ".$WC.".$n\n"; + $output .= " DIA.HasTransform [1.0, 0.0, 0.0, 1.0, ".$x.", ".$y."] : G2D.Transform\n"; + } elsif($type eq "cloud") { + $output .= " ".$n.$suffix." : SYSDYN.CloudSymbol\n"; + $output .= " MOD.ElementToComponent ".$WC.".$n\n"; + $output .= " DIA.HasTransform [1.0, 0.0, 0.0, 1.0, ".$x.", ".$y."] : G2D.Transform\n"; + } else { + print("Unknown element type $type\n"); + } + } + $generated_symbols->{$n.$suffix} = 1; + } + + my $c = $connections->{$key}; + foreach my $id (keys (%$c)) { + my $source = $tmp->{$c->{$id}->{'source'}}->{'name'}; + my $target = $tmp->{$c->{$id}->{'target'}}->{'name'}; + if($source && $target) { + my $source_suffix = "Element".$tmp->{$c->{$id}->{'source'}}->{'id'}; + my $target_suffix = "Element".$tmp->{$c->{$id}->{'target'}}->{'id'}; + + if($c->{$id}->{'hidden'} == 0) { + if($c->{$id}->{'type'} eq "flow") { + $output .= " _ : SYSDYN.FlowConnection\n"; + $output .= " MOD.DiagramConnectionToConnection ".$WC.".f".$id."\n"; + $output .= " \@WM.flow ".$source.$source_suffix." ".$target.$target_suffix."\n"; + } elsif($c->{$id}->{'type'} eq "dependency") { + $output .= " _ : SYSDYN.DependencyConnection\n"; + $output .= " MOD.DiagramConnectionToConnection ".$WC.".d".$id."\n"; + $output .= " \@WM.dependency ".$source.$source_suffix." ".$target.$target_suffix." -0.1\n"; + } else { + print("Unknown element type ".$c->{$id}->{'type'}."\n"); + } + } + } + } + $output .= "\n"; +} + +my $header = < +G2D = +STR = +DIA = +SIMU = +MOD = +SYSDYN = +PROJ = + +//###################################################################### +//# Example work model with two modules +//###################################################################### + +WM = : PROJ.Project + PROJ.HasFeature _ : PROJ.FeatureSpec + PROJ.HasGroupId "org.simantics.sysdyn.feature.group" + L0.PartOf + +TAGS = WM.Tags : L0.Library + +WM.dependency : L0.Template + \@template %type %head %tail %angle + %type + \@L0.tag TAGS.AdminIsVisible + \@L0.tag TAGS.AdminIsFocusable + STR.HasConnectionType SYSDYN.SysdynConnectionType + SYSDYN.angle %angle + DIA.HasArrowConnector _ : DIA.Connector + SYSDYN.HasHeadTerminal %head + DIA.AreConnected _ : DIA.Connector + SYSDYN.HasTailTerminal %tail + DIA.IsPlainConnectorOf %type + +WM.flow : L0.Template + \@template %type %head %tail + %type + \@L0.tag TAGS.AdminIsVisible + \@L0.tag TAGS.AdminIsFocusable + STR.HasConnectionType SYSDYN.SysdynConnectionType + DIA.HasArrowConnector _ : DIA.Connector + SYSDYN.HasHeadTerminal %head + DIA.AreConnected _ : DIA.Connector + SYSDYN.HasTailTerminal %tail + DIA.IsPlainConnectorOf %type + +WM.conf_dependency : L0.Template + \@template %type %head %tail + %type + \@L0.tag MOD.Mapped + SYSDYN.HasHead %head + SYSDYN.HasTail %tail + +WM.conf_dependency_ref : L0.Template + \@template %type %head %tail %ref + %type + \@L0.tag MOD.Mapped + SYSDYN.HasHead %head + SYSDYN.HasTail %tail + SYSDYN.RefersTo %ref + +WM.CancerModel : SYSDYN.SysdynModel + L0.HasLabel "Cancer Model" + SIMU.HasConfiguration CMC + SYSDYN.HasStartTime 0.0 + SYSDYN.HasStopTime 24.0 + +WM.CancerModel.Experiment : SYSDYN.Experiment + L0.HasLabel "Experiment" + +CMC = WM.CancerModel.CancerModelConfiguration : SYSDYN.Configuration + L0.HasLabel "CancerModelConfiguration" + +END + +open(OUTPUT, ">$targetfile") || die("Could not open target file for writing!"); +print OUTPUT $header; +print OUTPUT $output; +close(OUTPUT); + +print("Simantics graph configuration saved successfully to file $targetfile\n"); diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java b/dev-jkauttio/org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java new file mode 100644 index 00000000..ef34edf7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java @@ -0,0 +1,2353 @@ +package org.simantics.sysdyn; + +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.ReadGraph; +import org.simantics.db.request.Read; +import org.simantics.db.Session; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.QueryControl; + +public class SysdynResource { + + public final Resource AdditionalSymbols; + public final Resource AdditionalSymbols_MultilineText; + public final Resource AllElementsGroup; + public final Resource ArrayIndexes; + public final Resource ArrayIndexes_Inverse; + public final Resource Auxiliary; + public final Resource AuxiliarySymbol; + public final Resource AvailableSharedFunctionLibraries; + public final Resource AvailableVariableIndexes; + public final Resource BasicExperiment; + public final Resource Bottom; + public final Resource Browser; + public final Resource Built$in_Functions; + public final Resource Built$in_Functions_Modelica_Array_Functions; + public final Resource Built$in_Functions_Modelica_Array_Functions_array; + public final Resource Built$in_Functions_Modelica_Array_Functions_array_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_array_A_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_array_A_B; + public final Resource Built$in_Functions_Modelica_Array_Functions_array_A_C; + public final Resource Built$in_Functions_Modelica_Array_Functions_array_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_cat; + public final Resource Built$in_Functions_Modelica_Array_Functions_cat_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_cat_A_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_cat_A_B; + public final Resource Built$in_Functions_Modelica_Array_Functions_cat_A_C; + public final Resource Built$in_Functions_Modelica_Array_Functions_cat_k; + public final Resource Built$in_Functions_Modelica_Array_Functions_cat_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_cross; + public final Resource Built$in_Functions_Modelica_Array_Functions_cross_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_cross_x; + public final Resource Built$in_Functions_Modelica_Array_Functions_cross_y; + public final Resource Built$in_Functions_Modelica_Array_Functions_diagonal; + public final Resource Built$in_Functions_Modelica_Array_Functions_diagonal_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_diagonal_v; + public final Resource Built$in_Functions_Modelica_Array_Functions_fill; + public final Resource Built$in_Functions_Modelica_Array_Functions_fill_n; + public final Resource Built$in_Functions_Modelica_Array_Functions_fill_n_n1; + public final Resource Built$in_Functions_Modelica_Array_Functions_fill_n_n2; + public final Resource Built$in_Functions_Modelica_Array_Functions_fill_n_n3; + public final Resource Built$in_Functions_Modelica_Array_Functions_fill_o; + public final Resource Built$in_Functions_Modelica_Array_Functions_fill_s; + public final Resource Built$in_Functions_Modelica_Array_Functions_identity; + public final Resource Built$in_Functions_Modelica_Array_Functions_identity_n; + public final Resource Built$in_Functions_Modelica_Array_Functions_identity_outArray; + public final Resource Built$in_Functions_Modelica_Array_Functions_linspace; + public final Resource Built$in_Functions_Modelica_Array_Functions_linspace_n; + public final Resource Built$in_Functions_Modelica_Array_Functions_linspace_v; + public final Resource Built$in_Functions_Modelica_Array_Functions_linspace_x1; + public final Resource Built$in_Functions_Modelica_Array_Functions_linspace_x2; + public final Resource Built$in_Functions_Modelica_Array_Functions_matrix; + public final Resource Built$in_Functions_Modelica_Array_Functions_matrix_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_matrix_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_max; + public final Resource Built$in_Functions_Modelica_Array_Functions_max_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_max_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_min; + public final Resource Built$in_Functions_Modelica_Array_Functions_min_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_min_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_ndims; + public final Resource Built$in_Functions_Modelica_Array_Functions_ndims_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_ndims_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_ones; + public final Resource Built$in_Functions_Modelica_Array_Functions_ones_n; + public final Resource Built$in_Functions_Modelica_Array_Functions_ones_n_n1; + public final Resource Built$in_Functions_Modelica_Array_Functions_ones_n_n2; + public final Resource Built$in_Functions_Modelica_Array_Functions_ones_n_n3; + public final Resource Built$in_Functions_Modelica_Array_Functions_ones_o; + public final Resource Built$in_Functions_Modelica_Array_Functions_product; + public final Resource Built$in_Functions_Modelica_Array_Functions_product_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_product_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_scalar; + public final Resource Built$in_Functions_Modelica_Array_Functions_scalar_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_scalar_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_size; + public final Resource Built$in_Functions_Modelica_Array_Functions_size_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_size_i; + public final Resource Built$in_Functions_Modelica_Array_Functions_size_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_skew; + public final Resource Built$in_Functions_Modelica_Array_Functions_skew_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_skew_x; + public final Resource Built$in_Functions_Modelica_Array_Functions_sum; + public final Resource Built$in_Functions_Modelica_Array_Functions_sum_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_sum_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_transpose; + public final Resource Built$in_Functions_Modelica_Array_Functions_transpose_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_transpose_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_vector; + public final Resource Built$in_Functions_Modelica_Array_Functions_vector_A; + public final Resource Built$in_Functions_Modelica_Array_Functions_vector_result; + public final Resource Built$in_Functions_Modelica_Array_Functions_zeros; + public final Resource Built$in_Functions_Modelica_Array_Functions_zeros_n; + public final Resource Built$in_Functions_Modelica_Array_Functions_zeros_n_n1; + public final Resource Built$in_Functions_Modelica_Array_Functions_zeros_n_n2; + public final Resource Built$in_Functions_Modelica_Array_Functions_zeros_n_n3; + public final Resource Built$in_Functions_Modelica_Array_Functions_zeros_o; + public final Resource Built$in_Functions_Modelica_Functions; + public final Resource Built$in_Functions_Modelica_Functions_abs; + public final Resource Built$in_Functions_Modelica_Functions_abs_result; + public final Resource Built$in_Functions_Modelica_Functions_abs_v; + public final Resource Built$in_Functions_Modelica_Functions_acos; + public final Resource Built$in_Functions_Modelica_Functions_acos_u; + public final Resource Built$in_Functions_Modelica_Functions_acos_y; + public final Resource Built$in_Functions_Modelica_Functions_asin; + public final Resource Built$in_Functions_Modelica_Functions_asin_u; + public final Resource Built$in_Functions_Modelica_Functions_asin_y; + public final Resource Built$in_Functions_Modelica_Functions_atan; + public final Resource Built$in_Functions_Modelica_Functions_atan2; + public final Resource Built$in_Functions_Modelica_Functions_atan2_u1; + public final Resource Built$in_Functions_Modelica_Functions_atan2_u2; + public final Resource Built$in_Functions_Modelica_Functions_atan2_y; + public final Resource Built$in_Functions_Modelica_Functions_atan_u; + public final Resource Built$in_Functions_Modelica_Functions_atan_y; + public final Resource Built$in_Functions_Modelica_Functions_ceil; + public final Resource Built$in_Functions_Modelica_Functions_ceil_x; + public final Resource Built$in_Functions_Modelica_Functions_ceil_y; + public final Resource Built$in_Functions_Modelica_Functions_cos; + public final Resource Built$in_Functions_Modelica_Functions_cos_u; + public final Resource Built$in_Functions_Modelica_Functions_cos_y; + public final Resource Built$in_Functions_Modelica_Functions_cosh; + public final Resource Built$in_Functions_Modelica_Functions_cosh_u; + public final Resource Built$in_Functions_Modelica_Functions_cosh_y; + public final Resource Built$in_Functions_Modelica_Functions_delay; + public final Resource Built$in_Functions_Modelica_Functions_delay_delayMax; + public final Resource Built$in_Functions_Modelica_Functions_delay_delayTime; + public final Resource Built$in_Functions_Modelica_Functions_delay_expr; + public final Resource Built$in_Functions_Modelica_Functions_delay_result; + public final Resource Built$in_Functions_Modelica_Functions_der; + public final Resource Built$in_Functions_Modelica_Functions_der_dexpr; + public final Resource Built$in_Functions_Modelica_Functions_der_expr; + public final Resource Built$in_Functions_Modelica_Functions_div; + public final Resource Built$in_Functions_Modelica_Functions_div_result; + public final Resource Built$in_Functions_Modelica_Functions_div_x; + public final Resource Built$in_Functions_Modelica_Functions_div_y; + public final Resource Built$in_Functions_Modelica_Functions_edge; + public final Resource Built$in_Functions_Modelica_Functions_edge_b; + public final Resource Built$in_Functions_Modelica_Functions_edge_edgeEvent; + public final Resource Built$in_Functions_Modelica_Functions_exp; + public final Resource Built$in_Functions_Modelica_Functions_exp_u; + public final Resource Built$in_Functions_Modelica_Functions_exp_y; + public final Resource Built$in_Functions_Modelica_Functions_floor; + public final Resource Built$in_Functions_Modelica_Functions_floor_x; + public final Resource Built$in_Functions_Modelica_Functions_floor_y; + public final Resource Built$in_Functions_Modelica_Functions_initial; + public final Resource Built$in_Functions_Modelica_Functions_initial_isInitial; + public final Resource Built$in_Functions_Modelica_Functions_log; + public final Resource Built$in_Functions_Modelica_Functions_log10; + public final Resource Built$in_Functions_Modelica_Functions_log10_u; + public final Resource Built$in_Functions_Modelica_Functions_log10_y; + public final Resource Built$in_Functions_Modelica_Functions_log_u; + public final Resource Built$in_Functions_Modelica_Functions_log_y; + public final Resource Built$in_Functions_Modelica_Functions_max; + public final Resource Built$in_Functions_Modelica_Functions_max_result; + public final Resource Built$in_Functions_Modelica_Functions_max_x; + public final Resource Built$in_Functions_Modelica_Functions_max_y; + public final Resource Built$in_Functions_Modelica_Functions_min; + public final Resource Built$in_Functions_Modelica_Functions_min_result; + public final Resource Built$in_Functions_Modelica_Functions_min_x; + public final Resource Built$in_Functions_Modelica_Functions_min_y; + public final Resource Built$in_Functions_Modelica_Functions_mod; + public final Resource Built$in_Functions_Modelica_Functions_mod_result; + public final Resource Built$in_Functions_Modelica_Functions_mod_x; + public final Resource Built$in_Functions_Modelica_Functions_mod_y; + public final Resource Built$in_Functions_Modelica_Functions_noEvent; + public final Resource Built$in_Functions_Modelica_Functions_noEvent_expr; + public final Resource Built$in_Functions_Modelica_Functions_noEvent_result; + public final Resource Built$in_Functions_Modelica_Functions_pre; + public final Resource Built$in_Functions_Modelica_Functions_pre_result; + public final Resource Built$in_Functions_Modelica_Functions_pre_y; + public final Resource Built$in_Functions_Modelica_Functions_rem; + public final Resource Built$in_Functions_Modelica_Functions_rem_result; + public final Resource Built$in_Functions_Modelica_Functions_rem_x; + public final Resource Built$in_Functions_Modelica_Functions_rem_y; + public final Resource Built$in_Functions_Modelica_Functions_sample; + public final Resource Built$in_Functions_Modelica_Functions_sample_interval; + public final Resource Built$in_Functions_Modelica_Functions_sample_isSample; + public final Resource Built$in_Functions_Modelica_Functions_sample_start; + public final Resource Built$in_Functions_Modelica_Functions_semiLinear; + public final Resource Built$in_Functions_Modelica_Functions_semiLinear_negativeSlope; + public final Resource Built$in_Functions_Modelica_Functions_semiLinear_positiveSlope; + public final Resource Built$in_Functions_Modelica_Functions_semiLinear_result; + public final Resource Built$in_Functions_Modelica_Functions_semiLinear_x; + public final Resource Built$in_Functions_Modelica_Functions_sign; + public final Resource Built$in_Functions_Modelica_Functions_sign_result; + public final Resource Built$in_Functions_Modelica_Functions_sign_v; + public final Resource Built$in_Functions_Modelica_Functions_sin; + public final Resource Built$in_Functions_Modelica_Functions_sin_u; + public final Resource Built$in_Functions_Modelica_Functions_sin_y; + public final Resource Built$in_Functions_Modelica_Functions_sinh; + public final Resource Built$in_Functions_Modelica_Functions_sinh_u; + public final Resource Built$in_Functions_Modelica_Functions_sinh_y; + public final Resource Built$in_Functions_Modelica_Functions_smooth; + public final Resource Built$in_Functions_Modelica_Functions_smooth_expr; + public final Resource Built$in_Functions_Modelica_Functions_smooth_p; + public final Resource Built$in_Functions_Modelica_Functions_smooth_result; + public final Resource Built$in_Functions_Modelica_Functions_sqrt; + public final Resource Built$in_Functions_Modelica_Functions_sqrt_v; + public final Resource Built$in_Functions_Modelica_Functions_sqrt_y; + public final Resource Built$in_Functions_Modelica_Functions_tan; + public final Resource Built$in_Functions_Modelica_Functions_tan_u; + public final Resource Built$in_Functions_Modelica_Functions_tan_y; + public final Resource Built$in_Functions_Modelica_Functions_tanh; + public final Resource Built$in_Functions_Modelica_Functions_tanh_u; + public final Resource Built$in_Functions_Modelica_Functions_tanh_y; + public final Resource Built$in_Functions_Modelica_Functions_terminal; + public final Resource Built$in_Functions_Modelica_Functions_terminal_isTerminal; + public final Resource Built$in_Functions_Vensim_Functions; + public final Resource Built$in_Functions_Vensim_Functions_ABS; + public final Resource Built$in_Functions_Vensim_Functions_ABS_x; + public final Resource Built$in_Functions_Vensim_Functions_ABS_z; + public final Resource Built$in_Functions_Vensim_Functions_COS; + public final Resource Built$in_Functions_Vensim_Functions_COSH; + public final Resource Built$in_Functions_Vensim_Functions_COSH_x; + public final Resource Built$in_Functions_Vensim_Functions_COSH_z; + public final Resource Built$in_Functions_Vensim_Functions_COS_x; + public final Resource Built$in_Functions_Vensim_Functions_COS_z; + public final Resource Built$in_Functions_Vensim_Functions_EXP; + public final Resource Built$in_Functions_Vensim_Functions_EXP_x; + public final Resource Built$in_Functions_Vensim_Functions_EXP_z; + public final Resource Built$in_Functions_Vensim_Functions_IFTHENELSE; + public final Resource Built$in_Functions_Vensim_Functions_IFTHENELSE_cond; + public final Resource Built$in_Functions_Vensim_Functions_IFTHENELSE_onfalse; + public final Resource Built$in_Functions_Vensim_Functions_IFTHENELSE_ontrue; + public final Resource Built$in_Functions_Vensim_Functions_IFTHENELSE_z; + public final Resource Built$in_Functions_Vensim_Functions_LN; + public final Resource Built$in_Functions_Vensim_Functions_LN_x; + public final Resource Built$in_Functions_Vensim_Functions_LN_z; + public final Resource Built$in_Functions_Vensim_Functions_MAX; + public final Resource Built$in_Functions_Vensim_Functions_MAX_a; + public final Resource Built$in_Functions_Vensim_Functions_MAX_b; + public final Resource Built$in_Functions_Vensim_Functions_MAX_z; + public final Resource Built$in_Functions_Vensim_Functions_MIN; + public final Resource Built$in_Functions_Vensim_Functions_MIN_a; + public final Resource Built$in_Functions_Vensim_Functions_MIN_b; + public final Resource Built$in_Functions_Vensim_Functions_MIN_z; + public final Resource Built$in_Functions_Vensim_Functions_MODULO; + public final Resource Built$in_Functions_Vensim_Functions_MODULO_a; + public final Resource Built$in_Functions_Vensim_Functions_MODULO_b; + public final Resource Built$in_Functions_Vensim_Functions_MODULO_z; + public final Resource Built$in_Functions_Vensim_Functions_PULSE; + public final Resource Built$in_Functions_Vensim_Functions_PULSE_start; + public final Resource Built$in_Functions_Vensim_Functions_PULSE_width; + public final Resource Built$in_Functions_Vensim_Functions_PULSE_z; + public final Resource Built$in_Functions_Vensim_Functions_RAMP; + public final Resource Built$in_Functions_Vensim_Functions_RAMP_endTime; + public final Resource Built$in_Functions_Vensim_Functions_RAMP_slope; + public final Resource Built$in_Functions_Vensim_Functions_RAMP_startTime; + public final Resource Built$in_Functions_Vensim_Functions_RAMP_z; + public final Resource Built$in_Functions_Vensim_Functions_SIN; + public final Resource Built$in_Functions_Vensim_Functions_SINH; + public final Resource Built$in_Functions_Vensim_Functions_SINH_x; + public final Resource Built$in_Functions_Vensim_Functions_SINH_z; + public final Resource Built$in_Functions_Vensim_Functions_SIN_x; + public final Resource Built$in_Functions_Vensim_Functions_SIN_z; + public final Resource Built$in_Functions_Vensim_Functions_SQRT; + public final Resource Built$in_Functions_Vensim_Functions_SQRT_x; + public final Resource Built$in_Functions_Vensim_Functions_SQRT_z; + public final Resource Built$in_Functions_Vensim_Functions_STEP; + public final Resource Built$in_Functions_Vensim_Functions_STEP_height; + public final Resource Built$in_Functions_Vensim_Functions_STEP_stepTime; + public final Resource Built$in_Functions_Vensim_Functions_STEP_z; + public final Resource Built$in_Functions_Vensim_Functions_TAN; + public final Resource Built$in_Functions_Vensim_Functions_TANH; + public final Resource Built$in_Functions_Vensim_Functions_TANH_x; + public final Resource Built$in_Functions_Vensim_Functions_TANH_z; + public final Resource Built$in_Functions_Vensim_Functions_TAN_x; + public final Resource Built$in_Functions_Vensim_Functions_TAN_z; + public final Resource Built$in_Functions_Vensim_Functions_XIDZ; + public final Resource Built$in_Functions_Vensim_Functions_XIDZ_a; + public final Resource Built$in_Functions_Vensim_Functions_XIDZ_b; + public final Resource Built$in_Functions_Vensim_Functions_XIDZ_x; + public final Resource Built$in_Functions_Vensim_Functions_XIDZ_z; + public final Resource Built$in_Functions_Vensim_Functions_ZIDZ; + public final Resource Built$in_Functions_Vensim_Functions_ZIDZ_a; + public final Resource Built$in_Functions_Vensim_Functions_ZIDZ_b; + public final Resource Built$in_Functions_Vensim_Functions_ZIDZ_z; + public final Resource Built$in_Functions_interpolate; + public final Resource Built$in_Functions_interpolateFull; + public final Resource Built$in_Functions_interpolateFull_icol; + public final Resource Built$in_Functions_interpolateFull_table; + public final Resource Built$in_Functions_interpolateFull_u; + public final Resource Built$in_Functions_interpolateFull_y; + public final Resource Built$in_Functions_interpolate_table; + public final Resource Built$in_Functions_interpolate_u; + public final Resource Built$in_Functions_interpolate_y; + public final Resource Built$in_Functions_minmax; + public final Resource Built$in_Functions_minmax_expression; + public final Resource Built$in_Functions_minmax_maximum; + public final Resource Built$in_Functions_minmax_minimum; + public final Resource Built$in_Functions_minmax_result; + public final Resource Built$in_Functions_xidz; + public final Resource Built$in_Functions_xidz_divident; + public final Resource Built$in_Functions_xidz_divisor; + public final Resource Built$in_Functions_xidz_x; + public final Resource Built$in_Functions_xidz_z; + public final Resource Built$in_Functions_zidz; + public final Resource Built$in_Functions_zidz_divident; + public final Resource Built$in_Functions_zidz_divisor; + public final Resource Built$in_Functions_zidz_z; + public final Resource Center; + public final Resource Charts; + public final Resource Charts_SensitivityDataset; + public final Resource Charts_SensitivityDataset_ConfidenceBound; + public final Resource Charts_SensitivityDataset_ConfidenceBound_color; + public final Resource Charts_SensitivityDataset_ConfidenceBound_color_Inverse; + public final Resource Charts_SensitivityDataset_ConfidenceBound_percent; + public final Resource Charts_SensitivityDataset_ConfidenceBound_percent_Inverse; + public final Resource Charts_SensitivityDataset_confidenceBounds; + public final Resource Charts_SensitivityDataset_confidenceBounds_Inverse; + public final Resource Charts_SensitivityDataset_median; + public final Resource Charts_SensitivityDataset_median_Inverse; + public final Resource Charts_SensitivityPlot; + public final Resource Cloud; + public final Resource CloudSymbol; + public final Resource Component; + public final Resource Configuration; + public final Resource ConfigurationDiagram; + public final Resource ConfigurationDiagramTemplate; + public final Resource ConfigurationDiagram_selection; + public final Resource ConfigurationDiagram_selection_Inverse; + public final Resource ConstantExpression; + public final Resource DefaultFont; + public final Resource DefaultProfile; + public final Resource DefaultRealization; + public final Resource DelayExpression; + public final Resource DelayExpression_delayTime; + public final Resource DelayExpression_delayTime_Inverse; + public final Resource DelayExpression_expression; + public final Resource DelayExpression_expression_Inverse; + public final Resource DelayExpression_initialValue; + public final Resource DelayExpression_initialValue_Inverse; + public final Resource DelayExpression_order; + public final Resource DelayExpression_order_Inverse; + public final Resource Dependency; + public final Resource DependencyConnection; + public final Resource DependencyConnection_delayMark; + public final Resource DependencyConnection_hideArrow; + public final Resource DependencyConnection_polarity; + public final Resource DependencyConnection_polarityLocation; + public final Resource DependencyConnection_polarityLocation_Inverse; + public final Resource DependencyConnection_polarity_Inverse; + public final Resource DependencyConnection_strokeWidth; + public final Resource DependencyConnection_strokeWidth_Inverse; + public final Resource Dependency_angle; + public final Resource Dependency_angle_Inverse; + public final Resource Dependency_refersTo; + public final Resource DiagramToCompositeMapping; + public final Resource Enumeration; + public final Resource EnumerationIndex; + public final Resource EnumerationIndex_showEnumerationIndexInCharts; + public final Resource EnumerationIndex_showEnumerationIndexInCharts_Inverse; + public final Resource EnumerationIndexes; + public final Resource EnumerationIndexes_Inverse; + public final Resource EnumerationReplacement; + public final Resource Enumeration_enumerationIndexList; + public final Resource Enumeration_enumerationIndexList_Inverse; + public final Resource Enumeration_enumerationIndexes; + public final Resource Enumeration_enumerationIndexes_Inverse; + public final Resource Enumeration_isReplaceable; + public final Resource Enumeration_isReplaceable_Inverse; + public final Resource Experiment; + public final Resource Experiment_Run; + public final Resource Experiment_Run_time; + public final Resource Experiment_Run_time_Inverse; + public final Resource Experiment_result; + public final Resource Experiment_resultSet; + public final Resource Experiment_resultSet_Inverse; + public final Resource Experiment_result_Inverse; + public final Resource ExportModuleTree; + public final Resource Expression; + public final Resource Expression_arrayRange; + public final Resource Expression_arrayRange_Inverse; + public final Resource Expression_equation; + public final Resource Expression_equation_Inverse; + public final Resource Expressions; + public final Resource Expressions_Inverse; + public final Resource ExternalFiles; + public final Resource ExternalFunctionFile; + public final Resource ExternalFunctionFile_externalFile; + public final Resource ExternalFunctionFile_externalFile_Inverse; + public final Resource Flow; + public final Resource FlowConnection; + public final Resource FlowConnection_width; + public final Resource FlowConnection_width_Inverse; + public final Resource FunctionTree; + public final Resource Functions; + public final Resource Functions_runChildren; + public final Resource Functions_runProperties; + public final Resource Functions_valuePropertyProperties; + public final Resource Functions_valuePropertyValue; + public final Resource GameExperiment; + public final Resource GameExperiment_stepDuration; + public final Resource GameExperiment_stepDuration_Inverse; + public final Resource GameExperiment_stepLength; + public final Resource GameExperiment_stepLength_Inverse; + public final Resource HaltonSequenceGenerator; + public final Resource HasEquationOrEmpty; + public final Resource HasEquationOrEmpty_Inverse; + public final Resource HasHeadTerminal; + public final Resource HasRangeEnd; + public final Resource HasRangeEnd_Inverse; + public final Resource HasRangeStart; + public final Resource HasRangeStart_Inverse; + public final Resource HasRangeStep; + public final Resource HasRangeStep_Inverse; + public final Resource HasTailTerminal; + public final Resource HistoryDataset; + public final Resource HistoryDataset_FoundVariableNameNode; + public final Resource HistoryDataset_HistoryDatasetVariablesBrowseContext; + public final Resource HistoryDataset_HistoryDatasetVariablesBrowseContext_StringNodeType; + public final Resource HistoryDataset_HistoryDatasetVariablesBrowseContext_VariableChildRule; + public final Resource HistoryDataset_HistoryDatasetVariablesBrowseContext_VariableLabelRule; + public final Resource HistoryDataset_columns; + public final Resource HistoryDataset_columns_Inverse; + public final Resource HistoryDataset_end; + public final Resource HistoryDataset_end_Inverse; + public final Resource HistoryDataset_sheet; + public final Resource HistoryDataset_start; + public final Resource HistoryDataset_start_Inverse; + public final Resource HistoryDataset_timeName; + public final Resource HistoryDataset_timeName_Inverse; + public final Resource HistoryRealization; + public final Resource Horizontal; + public final Resource ImportModuleTree; + public final Resource ImportedOntologies; + public final Resource IndependentVariable; + public final Resource IndependentVariable_activeExpression; + public final Resource IndependentVariable_isUninitialized; + public final Resource IndependentVariable_isUninitialized_Inverse; + public final Resource IndependentVariable_rangeEnd; + public final Resource IndependentVariable_rangeEnd_Inverse; + public final Resource IndependentVariable_rangeStart; + public final Resource IndependentVariable_rangeStart_Inverse; + public final Resource IndependentVariable_rangeStep; + public final Resource IndependentVariable_rangeStep_Inverse; + public final Resource IndependentVariable_unit; + public final Resource IndependentVariable_unit_Inverse; + public final Resource Input; + public final Resource InputSymbol; + public final Resource Input_defaultInputValue; + public final Resource Input_defaultInputValue_Inverse; + public final Resource Interval; + public final Resource Interval_maxValue; + public final Resource Interval_maxValue_Inverse; + public final Resource Interval_minValue; + public final Resource Interval_minValue_Inverse; + public final Resource IsHeadOfTerminal; + public final Resource IsOutput; + public final Resource IsTailOfTerminal; + public final Resource IssueStyle; + public final Resource Left; + public final Resource Location; + public final Resource LookupExpression; + public final Resource LookupExpression_lookup; + public final Resource LookupExpression_lookup_Inverse; + public final Resource Loop; + public final Resource LoopSymbol; + public final Resource LoopSymbol_Clockwise; + public final Resource LoopSymbol_Clockwise_Inverse; + public final Resource Loop_Comment; + public final Resource Loop_Comment_Inverse; + public final Resource Loop_Items; + public final Resource Loop_Items_Inverse; + public final Resource Migration; + public final Resource Migration_from1$6to1$7; + public final Resource Migration_from1$6to1$7_Ontologies; + public final Resource Migration_from1$6to1$7_OrderedSetsToLists; + public final Resource Migration_from1$6to1$7_Spreadsheets; + public final Resource Migration_from1$6to1$7_SysdynChanges; + public final Resource Migration_fromFunctionLibrary1; + public final Resource Migration_fromModel1; + public final Resource Migration_fromModule1; + public final Resource ModelBrowser; + public final Resource ModelingActionContext; + public final Resource ModelingActionContext_Actions; + public final Resource ModelingActionContext_Actions_ChartDropAction; + public final Resource ModelingActionContext_Actions_FunctionDropAction; + public final Resource ModelingActionContext_Actions_NewBarChart; + public final Resource ModelingActionContext_Actions_NewEnumeration; + public final Resource ModelingActionContext_Actions_NewExperiment; + public final Resource ModelingActionContext_Actions_NewFunction; + public final Resource ModelingActionContext_Actions_NewFunctionLibrary; + public final Resource ModelingActionContext_Actions_NewHistoryData; + public final Resource ModelingActionContext_Actions_NewLineChart; + public final Resource ModelingActionContext_Actions_NewModuleType; + public final Resource ModelingActionContext_Actions_NewPieChart; + public final Resource ModelingActionContext_Actions_NewSharedFunctionLibrary; + public final Resource ModelingActionContext_Actions_NewSheet; + public final Resource ModelingActionContext_Actions_NewSimulationPlaybackExperiment; + public final Resource ModelingBrowseContext; + public final Resource ModelingBrowseContext_ActiveLabelDecorationRule; + public final Resource ModelingBrowseContext_BuiltinFunctions; + public final Resource ModelingBrowseContext_ChartImageRule; + public final Resource ModelingBrowseContext_ChartsFolder; + public final Resource ModelingBrowseContext_ExperimentsFolder; + public final Resource ModelingBrowseContext_FunctionsFolder; + public final Resource ModelingBrowseContext_ModuleContentChildRule; + public final Resource ModelingBrowseContext_ModuleSymbol; + public final Resource ModelingBrowseContext_ModuleSymbolNodeType; + public final Resource ModelingBrowseContext_ModuleTypeChildRule; + public final Resource ModelingBrowseContext_ModuleTypeLabelRule; + public final Resource ModelingBrowseContext_ModulesFolder; + public final Resource ModelingBrowseContext_ResultImageRule; + public final Resource ModelingBrowseContext_SharedFunctionsFolder; + public final Resource ModelingBrowseContext_Variable; + public final Resource ModelingBrowseContext_VariableChildRule; + public final Resource ModelingBrowseContext_VariableImageRule; + public final Resource ModelingBrowseContext_VariableNameLabelRule; + public final Resource ModelingBrowseContext_VariableNodeType; + public final Resource Module; + public final Resource ModuleSymbol; + public final Resource Module_ParameterOverride; + public final Resource Module_ParameterOverrideBrowseContext; + public final Resource Module_ParameterOverrideBrowseContext_Node; + public final Resource Module_ParameterOverrideBrowseContext_NodeType; + public final Resource Module_ParameterOverrideBrowseContext_ParameterChildRule; + public final Resource Module_ParameterOverrideBrowseContext_ParameterLabelDecorationRule; + public final Resource Module_ParameterOverrideBrowseContext_ParameterLabelRule; + public final Resource Module_ParameterOverrideBrowseContext_ParameterModifierRule; + public final Resource Module_ParameterOverrideBrowseContext_ParameterSorterRule; + public final Resource Module_ParameterOverride_overriddenParameter; + public final Resource Module_ParameterOverride_overrideExpression; + public final Resource Module_ParameterOverride_overrideExpression_Inverse; + public final Resource Module_parameterOverride; + public final Resource Module_parameterOverride_Inverse; + public final Resource Module_redeclaration; + public final Resource Module_redeclaration_Inverse; + public final Resource ModulesSearchFunction; + public final Resource NormalDistribution; + public final Resource NormalDistribution_maxValue; + public final Resource NormalDistribution_maxValue_Inverse; + public final Resource NormalDistribution_mean; + public final Resource NormalDistribution_mean_Inverse; + public final Resource NormalDistribution_minValue; + public final Resource NormalDistribution_minValue_Inverse; + public final Resource NormalDistribution_stdDeviation; + public final Resource NormalDistribution_stdDeviation_Inverse; + public final Resource NormalExpression; + public final Resource Orientation; + public final Resource ParameterExpression; + public final Resource PlaybackExperiment; + public final Resource ProbabilityDistribution; + public final Resource Profiles; + public final Resource Profiles_IssueWarnings; + public final Resource Profiles_ShadowVisualizations; + public final Resource Profiles_SimulationPlaybackColours; + public final Resource RandomGenerator; + public final Resource Redeclaration; + public final Resource Redeclaration_replacedEnumeration; + public final Resource Redeclaration_replacedEnumeration_Inverse; + public final Resource Redeclaration_replacingEnumeration; + public final Resource Redeclaration_replacingEnumeration_Inverse; + public final Resource Result; + public final Resource ResultSet; + public final Resource Result_parameterFile; + public final Resource Result_parameterFile_Inverse; + public final Resource Result_resultFile; + public final Resource Result_resultFile_Inverse; + public final Resource Result_showResult; + public final Resource Result_time; + public final Resource Result_time_Inverse; + public final Resource Right; + public final Resource SearchContribution; + public final Resource SelectedSharedFunctionLibraries; + public final Resource SensitivityAnalysisExperiment; + public final Resource SensitivityAnalysisExperiment_Parameter; + public final Resource SensitivityAnalysisExperiment_ParameterActionContext; + public final Resource SensitivityAnalysisExperiment_ParameterActionContext_Actions; + public final Resource SensitivityAnalysisExperiment_ParameterBrowseContext; + public final Resource SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterChildRule; + public final Resource SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterLabelRule; + public final Resource SensitivityAnalysisExperiment_Parameter_indexes; + public final Resource SensitivityAnalysisExperiment_Parameter_indexes_Inverse; + public final Resource SensitivityAnalysisExperiment_Parameter_propabilityDistribution; + public final Resource SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse; + public final Resource SensitivityAnalysisExperiment_Parameter_variable; + public final Resource SensitivityAnalysisExperiment_Parameter_variable_Inverse; + public final Resource SensitivityAnalysisExperiment_method; + public final Resource SensitivityAnalysisExperiment_method_Inverse; + public final Resource SensitivityAnalysisExperiment_numberOfValues; + public final Resource SensitivityAnalysisExperiment_numberOfValues_Inverse; + public final Resource SensitivityAnalysisExperiment_parameterList; + public final Resource SensitivityAnalysisExperiment_parameterList_Inverse; + public final Resource SensitivityAnalysisExperiment_randomSeed; + public final Resource SensitivityAnalysisExperiment_randomSeed_Inverse; + public final Resource SensitivityAnalysisExperiment_resultRefreshRate; + public final Resource SensitivityAnalysisExperiment_resultRefreshRate_Inverse; + public final Resource Shadow; + public final Resource ShadowStyle; + public final Resource ShadowSymbol; + public final Resource Shadow_original; + public final Resource Shadow_original_Inverse; + public final Resource SharedFunctionOntology; + public final Resource SharedModuleOntology; + public final Resource SimulateOnChangeExperiment; + public final Resource SimulationPlaybackProfile; + public final Resource SimulationPlaybackStyle; + public final Resource Stock; + public final Resource StockExpression; + public final Resource StockExpression_initialEquation; + public final Resource StockExpression_initialEquation_Inverse; + public final Resource StockExpression_integralEquation; + public final Resource StockExpression_integralEquation_Inverse; + public final Resource StockExpression_useCustomIntegral; + public final Resource StockSymbol; + public final Resource SymbolReferences; + public final Resource SymbolReferences_BasicSymbols; + public final Resource SymbolReferences_CommentSymbols; + public final Resource Symbols; + public final Resource SysdynConnectionType; + public final Resource SysdynDiagramModelingRules; + public final Resource SysdynModel; + public final Resource SysdynModel_fmuFile; + public final Resource SysdynModel_fmuFile_Inverse; + public final Resource SysdynModel_lastExportFileName; + public final Resource SysdynModel_lastExportFileName_Inverse; + public final Resource SysdynModel_lastExportFilePath; + public final Resource SysdynModel_lastExportFilePath_Inverse; + public final Resource SysdynModel_outputInterval; + public final Resource SysdynModel_outputInterval_Inverse; + public final Resource SysdynModel_simulationStepLength; + public final Resource SysdynModel_simulationStepLength_Inverse; + public final Resource SysdynModel_solver; + public final Resource SysdynModel_solver_Inverse; + public final Resource SysdynModel_startTime; + public final Resource SysdynModel_startTime_Inverse; + public final Resource SysdynModel_stopTime; + public final Resource SysdynModel_stopTime_Inverse; + public final Resource SysdynModel_timeUnit; + public final Resource SysdynModel_timeUnit_Inverse; + public final Resource SysdynModel_tolerance; + public final Resource SysdynModel_tolerance_Inverse; + public final Resource SysdynModel_variableFilter; + public final Resource SysdynModel_variableFilter_Inverse; + public final Resource SysdynModelicaFunction; + public final Resource SysdynModelicaFunctionLibrary; + public final Resource SysdynModelicaFunction_Input; + public final Resource SysdynModelicaFunction_InterfaceVariable; + public final Resource SysdynModelicaFunction_Output; + public final Resource SysdynModelicaFunction_VariableLengthInput; + public final Resource SysdynModelicaFunction_VariableLengthInput_shownLabels; + public final Resource SysdynModelicaFunction_VariableLengthInput_shownLabels_Inverse; + public final Resource SysdynModelicaFunction_definition; + public final Resource SysdynModelicaFunction_definition_Inverse; + public final Resource SysdynModelicaFunction_inputs; + public final Resource SysdynModelicaFunction_inputs_Inverse; + public final Resource SysdynModelicaFunction_modelicaFunctionCode; + public final Resource SysdynModelicaFunction_modelicaFunctionCode_Inverse; + public final Resource SysdynModelicaFunction_modelicaFunctionInterface; + public final Resource SysdynModelicaFunction_modelicaFunctionInterface_Inverse; + public final Resource SysdynModelicaFunction_optional; + public final Resource SysdynModelicaFunction_optional_Inverse; + public final Resource SysdynModelicaFunction_outputs; + public final Resource SysdynModelicaFunction_outputs_Inverse; + public final Resource SysdynModelicaFunction_unit; + public final Resource SysdynModelicaFunction_unit_Inverse; + public final Resource SysdynModuleLibrary; + public final Resource SysdynOperationBrowser; + public final Resource SysdynSymbol; + public final Resource SysdynTerminal; + public final Resource Top; + public final Resource UniformDistribution; + public final Resource UniformDistribution_maxValue; + public final Resource UniformDistribution_maxValue_Inverse; + public final Resource UniformDistribution_minValue; + public final Resource UniformDistribution_minValue_Inverse; + public final Resource UsedVariableIndexes; + public final Resource Validations; + public final Resource Validations_Dependencies; + public final Resource Validations_Dependencies_DependencyConnectionsIssueSource; + public final Resource Validations_Dependencies_MissingDependencyConnectionsIssueSource; + public final Resource Validations_Dependencies_dependencyValidator; + public final Resource Validations_Dependencies_invalidSheetReferenceIssueDescription; + public final Resource Validations_Dependencies_missingDependencyValidator; + public final Resource Validations_Dependencies_missingLinkIssueDescription; + public final Resource Validations_Dependencies_noSuchVariableIssueDescription; + public final Resource Validations_Dependencies_rangeIssueDescription; + public final Resource Validations_Dependencies_rangeWarningDescription; + public final Resource Validations_Dependencies_unusedDependencyIssueDescription; + public final Resource Validations_DependencyConstraint; + public final Resource Validations_EmptyEnumerationIssue; + public final Resource Validations_EnumerationConstraint; + public final Resource Validations_Enumerations; + public final Resource Validations_Enumerations_EnumerationIssueSource; + public final Resource Validations_Enumerations_emptyEnumerationIssueDescription; + public final Resource Validations_Enumerations_enumerationIndexValidator; + public final Resource Validations_ExpressionConstraint; + public final Resource Validations_ExpressionIssue; + public final Resource Validations_Expressions; + public final Resource Validations_Expressions_ExpressionIssueSource; + public final Resource Validations_Expressions_expressionIssueDescription; + public final Resource Validations_Expressions_expressionValidator; + public final Resource Validations_Functions; + public final Resource Validations_Functions_baseRealizationFunction; + public final Resource Validations_Functions_path; + public final Resource Validations_InvalidSheetReferenceIssue; + public final Resource Validations_Issue; + public final Resource Validations_Issue_stringContexts; + public final Resource Validations_Issue_stringContexts_Inverse; + public final Resource Validations_MissingDependencyConstraint; + public final Resource Validations_MissingLinkIssue; + public final Resource Validations_ModuleInputUnitWarning; + public final Resource Validations_ModuleOutputUnitWarning; + public final Resource Validations_NoSuchVariableIssue; + public final Resource Validations_RangeIssue; + public final Resource Validations_RangeWarning; + public final Resource Validations_UnitConstraint; + public final Resource Validations_UnitWarning; + public final Resource Validations_Units; + public final Resource Validations_Units_UnitIssueSource; + public final Resource Validations_Units_UnitIssueSource_allowEquivalents; + public final Resource Validations_Units_UnitIssueSource_allowEquivalents_Inverse; + public final Resource Validations_Units_moduleInputUnitWarningDescription; + public final Resource Validations_Units_moduleInterfaceExtension; + public final Resource Validations_Units_moduleOutputUnitWarningDescription; + public final Resource Validations_Units_unitValidator; + public final Resource Validations_Units_unitWarningDescription; + public final Resource Validations_UnusedDependencyIssue; + public final Resource Validations_constraint; + public final Resource Validations_issue; + public final Resource Validations_listeningConstraint; + public final Resource ValueGeneratorMethod; + public final Resource Valve; + public final Resource ValveSymbol; + public final Resource ValveSymbol_orientation; + public final Resource ValveSymbol_textLocation; + public final Resource Variable; + public final Resource Variable_HasHead; + public final Resource Variable_HasTail; + public final Resource Variable_activeDatasets; + public final Resource Variable_activeDatasets_Inverse; + public final Resource Variable_arrayIndexes; + public final Resource Variable_arrayIndexesList; + public final Resource Variable_arrayIndexesList_Inverse; + public final Resource Variable_arrayIndexes_Inverse; + public final Resource Variable_expressionList; + public final Resource Variable_expressionList_Inverse; + public final Resource Variable_expressions; + public final Resource Variable_expressions_Inverse; + public final Resource Variable_isHeadOf; + public final Resource Variable_isTailOf; + public final Resource Variable_names; + public final Resource Variable_names_Inverse; + public final Resource Variable_time; + public final Resource Variable_time_Inverse; + public final Resource Variable_times; + public final Resource Variable_times_Inverse; + public final Resource Variable_type; + public final Resource Variable_type_Inverse; + public final Resource Variable_unit; + public final Resource Variable_unit_Inverse; + public final Resource Variable_value; + public final Resource Variable_value_Inverse; + public final Resource Variable_values; + public final Resource Variable_values_Inverse; + public final Resource Variable_variability; + public final Resource Variable_variability_Inverse; + public final Resource Vertical; + public final Resource WithLookupExpression; + public final Resource WithLookupExpression_expression; + public final Resource WithLookupExpression_expression_Inverse; + public final Resource WithLookupExpression_lookup; + public final Resource WithLookupExpression_lookup_Inverse; + public final Resource WithLookupExpression_maxX; + public final Resource WithLookupExpression_maxY; + public final Resource WithLookupExpression_minX; + public final Resource WithLookupExpression_minY; + + public static class URIs { + public static final String AdditionalSymbols = "http://www.simantics.org/Sysdyn-1.1/AdditionalSymbols"; + public static final String AdditionalSymbols_MultilineText = "http://www.simantics.org/Sysdyn-1.1/AdditionalSymbols/MultilineText"; + public static final String AllElementsGroup = "http://www.simantics.org/Sysdyn-1.1/AllElementsGroup"; + public static final String ArrayIndexes = "http://www.simantics.org/Sysdyn-1.1/ArrayIndexes"; + public static final String ArrayIndexes_Inverse = "http://www.simantics.org/Sysdyn-1.1/ArrayIndexes/Inverse"; + public static final String Auxiliary = "http://www.simantics.org/Sysdyn-1.1/Auxiliary"; + public static final String AuxiliarySymbol = "http://www.simantics.org/Sysdyn-1.1/AuxiliarySymbol"; + public static final String AvailableSharedFunctionLibraries = "http://www.simantics.org/Sysdyn-1.1/AvailableSharedFunctionLibraries"; + public static final String AvailableVariableIndexes = "http://www.simantics.org/Sysdyn-1.1/AvailableVariableIndexes"; + public static final String BasicExperiment = "http://www.simantics.org/Sysdyn-1.1/BasicExperiment"; + public static final String Bottom = "http://www.simantics.org/Sysdyn-1.1/Bottom"; + public static final String Browser = "http://www.simantics.org/Sysdyn-1.1/Browser"; + public static final String Built$in_Functions = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions"; + public static final String Built$in_Functions_Modelica_Array_Functions = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions"; + public static final String Built$in_Functions_Modelica_Array_Functions_array = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/array"; + public static final String Built$in_Functions_Modelica_Array_Functions_array_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/array/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_array_A_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/array/A/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_array_A_B = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/array/A/B"; + public static final String Built$in_Functions_Modelica_Array_Functions_array_A_C = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/array/A/C"; + public static final String Built$in_Functions_Modelica_Array_Functions_array_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/array/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_cat = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cat"; + public static final String Built$in_Functions_Modelica_Array_Functions_cat_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cat/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_cat_A_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cat/A/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_cat_A_B = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cat/A/B"; + public static final String Built$in_Functions_Modelica_Array_Functions_cat_A_C = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cat/A/C"; + public static final String Built$in_Functions_Modelica_Array_Functions_cat_k = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cat/k"; + public static final String Built$in_Functions_Modelica_Array_Functions_cat_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cat/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_cross = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cross"; + public static final String Built$in_Functions_Modelica_Array_Functions_cross_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cross/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_cross_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cross/x"; + public static final String Built$in_Functions_Modelica_Array_Functions_cross_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/cross/y"; + public static final String Built$in_Functions_Modelica_Array_Functions_diagonal = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/diagonal"; + public static final String Built$in_Functions_Modelica_Array_Functions_diagonal_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/diagonal/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_diagonal_v = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/diagonal/v"; + public static final String Built$in_Functions_Modelica_Array_Functions_fill = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/fill"; + public static final String Built$in_Functions_Modelica_Array_Functions_fill_n = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/fill/n"; + public static final String Built$in_Functions_Modelica_Array_Functions_fill_n_n1 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/fill/n/n1"; + public static final String Built$in_Functions_Modelica_Array_Functions_fill_n_n2 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/fill/n/n2"; + public static final String Built$in_Functions_Modelica_Array_Functions_fill_n_n3 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/fill/n/n3"; + public static final String Built$in_Functions_Modelica_Array_Functions_fill_o = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/fill/o"; + public static final String Built$in_Functions_Modelica_Array_Functions_fill_s = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/fill/s"; + public static final String Built$in_Functions_Modelica_Array_Functions_identity = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/identity"; + public static final String Built$in_Functions_Modelica_Array_Functions_identity_n = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/identity/n"; + public static final String Built$in_Functions_Modelica_Array_Functions_identity_outArray = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/identity/outArray"; + public static final String Built$in_Functions_Modelica_Array_Functions_linspace = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/linspace"; + public static final String Built$in_Functions_Modelica_Array_Functions_linspace_n = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/linspace/n"; + public static final String Built$in_Functions_Modelica_Array_Functions_linspace_v = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/linspace/v"; + public static final String Built$in_Functions_Modelica_Array_Functions_linspace_x1 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/linspace/x1"; + public static final String Built$in_Functions_Modelica_Array_Functions_linspace_x2 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/linspace/x2"; + public static final String Built$in_Functions_Modelica_Array_Functions_matrix = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/matrix"; + public static final String Built$in_Functions_Modelica_Array_Functions_matrix_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/matrix/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_matrix_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/matrix/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_max = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/max"; + public static final String Built$in_Functions_Modelica_Array_Functions_max_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/max/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_max_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/max/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_min = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/min"; + public static final String Built$in_Functions_Modelica_Array_Functions_min_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/min/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_min_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/min/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_ndims = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/ndims"; + public static final String Built$in_Functions_Modelica_Array_Functions_ndims_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/ndims/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_ndims_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/ndims/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_ones = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/ones"; + public static final String Built$in_Functions_Modelica_Array_Functions_ones_n = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/ones/n"; + public static final String Built$in_Functions_Modelica_Array_Functions_ones_n_n1 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/ones/n/n1"; + public static final String Built$in_Functions_Modelica_Array_Functions_ones_n_n2 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/ones/n/n2"; + public static final String Built$in_Functions_Modelica_Array_Functions_ones_n_n3 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/ones/n/n3"; + public static final String Built$in_Functions_Modelica_Array_Functions_ones_o = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/ones/o"; + public static final String Built$in_Functions_Modelica_Array_Functions_product = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/product"; + public static final String Built$in_Functions_Modelica_Array_Functions_product_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/product/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_product_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/product/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_scalar = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/scalar"; + public static final String Built$in_Functions_Modelica_Array_Functions_scalar_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/scalar/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_scalar_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/scalar/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_size = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/size"; + public static final String Built$in_Functions_Modelica_Array_Functions_size_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/size/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_size_i = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/size/i"; + public static final String Built$in_Functions_Modelica_Array_Functions_size_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/size/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_skew = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/skew"; + public static final String Built$in_Functions_Modelica_Array_Functions_skew_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/skew/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_skew_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/skew/x"; + public static final String Built$in_Functions_Modelica_Array_Functions_sum = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/sum"; + public static final String Built$in_Functions_Modelica_Array_Functions_sum_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/sum/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_sum_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/sum/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_transpose = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/transpose"; + public static final String Built$in_Functions_Modelica_Array_Functions_transpose_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/transpose/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_transpose_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/transpose/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_vector = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/vector"; + public static final String Built$in_Functions_Modelica_Array_Functions_vector_A = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/vector/A"; + public static final String Built$in_Functions_Modelica_Array_Functions_vector_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/vector/result"; + public static final String Built$in_Functions_Modelica_Array_Functions_zeros = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/zeros"; + public static final String Built$in_Functions_Modelica_Array_Functions_zeros_n = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/zeros/n"; + public static final String Built$in_Functions_Modelica_Array_Functions_zeros_n_n1 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/zeros/n/n1"; + public static final String Built$in_Functions_Modelica_Array_Functions_zeros_n_n2 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/zeros/n/n2"; + public static final String Built$in_Functions_Modelica_Array_Functions_zeros_n_n3 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/zeros/n/n3"; + public static final String Built$in_Functions_Modelica_Array_Functions_zeros_o = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Array%20Functions/zeros/o"; + public static final String Built$in_Functions_Modelica_Functions = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions"; + public static final String Built$in_Functions_Modelica_Functions_abs = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/abs"; + public static final String Built$in_Functions_Modelica_Functions_abs_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/abs/result"; + public static final String Built$in_Functions_Modelica_Functions_abs_v = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/abs/v"; + public static final String Built$in_Functions_Modelica_Functions_acos = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/acos"; + public static final String Built$in_Functions_Modelica_Functions_acos_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/acos/u"; + public static final String Built$in_Functions_Modelica_Functions_acos_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/acos/y"; + public static final String Built$in_Functions_Modelica_Functions_asin = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/asin"; + public static final String Built$in_Functions_Modelica_Functions_asin_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/asin/u"; + public static final String Built$in_Functions_Modelica_Functions_asin_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/asin/y"; + public static final String Built$in_Functions_Modelica_Functions_atan = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/atan"; + public static final String Built$in_Functions_Modelica_Functions_atan2 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/atan2"; + public static final String Built$in_Functions_Modelica_Functions_atan2_u1 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/atan2/u1"; + public static final String Built$in_Functions_Modelica_Functions_atan2_u2 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/atan2/u2"; + public static final String Built$in_Functions_Modelica_Functions_atan2_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/atan2/y"; + public static final String Built$in_Functions_Modelica_Functions_atan_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/atan/u"; + public static final String Built$in_Functions_Modelica_Functions_atan_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/atan/y"; + public static final String Built$in_Functions_Modelica_Functions_ceil = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/ceil"; + public static final String Built$in_Functions_Modelica_Functions_ceil_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/ceil/x"; + public static final String Built$in_Functions_Modelica_Functions_ceil_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/ceil/y"; + public static final String Built$in_Functions_Modelica_Functions_cos = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/cos"; + public static final String Built$in_Functions_Modelica_Functions_cos_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/cos/u"; + public static final String Built$in_Functions_Modelica_Functions_cos_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/cos/y"; + public static final String Built$in_Functions_Modelica_Functions_cosh = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/cosh"; + public static final String Built$in_Functions_Modelica_Functions_cosh_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/cosh/u"; + public static final String Built$in_Functions_Modelica_Functions_cosh_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/cosh/y"; + public static final String Built$in_Functions_Modelica_Functions_delay = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/delay"; + public static final String Built$in_Functions_Modelica_Functions_delay_delayMax = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/delay/delayMax"; + public static final String Built$in_Functions_Modelica_Functions_delay_delayTime = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/delay/delayTime"; + public static final String Built$in_Functions_Modelica_Functions_delay_expr = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/delay/expr"; + public static final String Built$in_Functions_Modelica_Functions_delay_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/delay/result"; + public static final String Built$in_Functions_Modelica_Functions_der = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/der"; + public static final String Built$in_Functions_Modelica_Functions_der_dexpr = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/der/dexpr"; + public static final String Built$in_Functions_Modelica_Functions_der_expr = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/der/expr"; + public static final String Built$in_Functions_Modelica_Functions_div = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/div"; + public static final String Built$in_Functions_Modelica_Functions_div_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/div/result"; + public static final String Built$in_Functions_Modelica_Functions_div_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/div/x"; + public static final String Built$in_Functions_Modelica_Functions_div_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/div/y"; + public static final String Built$in_Functions_Modelica_Functions_edge = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/edge"; + public static final String Built$in_Functions_Modelica_Functions_edge_b = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/edge/b"; + public static final String Built$in_Functions_Modelica_Functions_edge_edgeEvent = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/edge/edgeEvent"; + public static final String Built$in_Functions_Modelica_Functions_exp = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/exp"; + public static final String Built$in_Functions_Modelica_Functions_exp_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/exp/u"; + public static final String Built$in_Functions_Modelica_Functions_exp_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/exp/y"; + public static final String Built$in_Functions_Modelica_Functions_floor = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/floor"; + public static final String Built$in_Functions_Modelica_Functions_floor_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/floor/x"; + public static final String Built$in_Functions_Modelica_Functions_floor_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/floor/y"; + public static final String Built$in_Functions_Modelica_Functions_initial = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/initial"; + public static final String Built$in_Functions_Modelica_Functions_initial_isInitial = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/initial/isInitial"; + public static final String Built$in_Functions_Modelica_Functions_log = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/log"; + public static final String Built$in_Functions_Modelica_Functions_log10 = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/log10"; + public static final String Built$in_Functions_Modelica_Functions_log10_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/log10/u"; + public static final String Built$in_Functions_Modelica_Functions_log10_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/log10/y"; + public static final String Built$in_Functions_Modelica_Functions_log_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/log/u"; + public static final String Built$in_Functions_Modelica_Functions_log_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/log/y"; + public static final String Built$in_Functions_Modelica_Functions_max = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/max"; + public static final String Built$in_Functions_Modelica_Functions_max_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/max/result"; + public static final String Built$in_Functions_Modelica_Functions_max_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/max/x"; + public static final String Built$in_Functions_Modelica_Functions_max_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/max/y"; + public static final String Built$in_Functions_Modelica_Functions_min = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/min"; + public static final String Built$in_Functions_Modelica_Functions_min_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/min/result"; + public static final String Built$in_Functions_Modelica_Functions_min_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/min/x"; + public static final String Built$in_Functions_Modelica_Functions_min_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/min/y"; + public static final String Built$in_Functions_Modelica_Functions_mod = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/mod"; + public static final String Built$in_Functions_Modelica_Functions_mod_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/mod/result"; + public static final String Built$in_Functions_Modelica_Functions_mod_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/mod/x"; + public static final String Built$in_Functions_Modelica_Functions_mod_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/mod/y"; + public static final String Built$in_Functions_Modelica_Functions_noEvent = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/noEvent"; + public static final String Built$in_Functions_Modelica_Functions_noEvent_expr = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/noEvent/expr"; + public static final String Built$in_Functions_Modelica_Functions_noEvent_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/noEvent/result"; + public static final String Built$in_Functions_Modelica_Functions_pre = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/pre"; + public static final String Built$in_Functions_Modelica_Functions_pre_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/pre/result"; + public static final String Built$in_Functions_Modelica_Functions_pre_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/pre/y"; + public static final String Built$in_Functions_Modelica_Functions_rem = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/rem"; + public static final String Built$in_Functions_Modelica_Functions_rem_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/rem/result"; + public static final String Built$in_Functions_Modelica_Functions_rem_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/rem/x"; + public static final String Built$in_Functions_Modelica_Functions_rem_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/rem/y"; + public static final String Built$in_Functions_Modelica_Functions_sample = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sample"; + public static final String Built$in_Functions_Modelica_Functions_sample_interval = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sample/interval"; + public static final String Built$in_Functions_Modelica_Functions_sample_isSample = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sample/isSample"; + public static final String Built$in_Functions_Modelica_Functions_sample_start = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sample/start"; + public static final String Built$in_Functions_Modelica_Functions_semiLinear = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/semiLinear"; + public static final String Built$in_Functions_Modelica_Functions_semiLinear_negativeSlope = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/semiLinear/negativeSlope"; + public static final String Built$in_Functions_Modelica_Functions_semiLinear_positiveSlope = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/semiLinear/positiveSlope"; + public static final String Built$in_Functions_Modelica_Functions_semiLinear_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/semiLinear/result"; + public static final String Built$in_Functions_Modelica_Functions_semiLinear_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/semiLinear/x"; + public static final String Built$in_Functions_Modelica_Functions_sign = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sign"; + public static final String Built$in_Functions_Modelica_Functions_sign_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sign/result"; + public static final String Built$in_Functions_Modelica_Functions_sign_v = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sign/v"; + public static final String Built$in_Functions_Modelica_Functions_sin = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sin"; + public static final String Built$in_Functions_Modelica_Functions_sin_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sin/u"; + public static final String Built$in_Functions_Modelica_Functions_sin_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sin/y"; + public static final String Built$in_Functions_Modelica_Functions_sinh = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sinh"; + public static final String Built$in_Functions_Modelica_Functions_sinh_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sinh/u"; + public static final String Built$in_Functions_Modelica_Functions_sinh_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sinh/y"; + public static final String Built$in_Functions_Modelica_Functions_smooth = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/smooth"; + public static final String Built$in_Functions_Modelica_Functions_smooth_expr = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/smooth/expr"; + public static final String Built$in_Functions_Modelica_Functions_smooth_p = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/smooth/p"; + public static final String Built$in_Functions_Modelica_Functions_smooth_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/smooth/result"; + public static final String Built$in_Functions_Modelica_Functions_sqrt = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sqrt"; + public static final String Built$in_Functions_Modelica_Functions_sqrt_v = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sqrt/v"; + public static final String Built$in_Functions_Modelica_Functions_sqrt_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/sqrt/y"; + public static final String Built$in_Functions_Modelica_Functions_tan = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/tan"; + public static final String Built$in_Functions_Modelica_Functions_tan_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/tan/u"; + public static final String Built$in_Functions_Modelica_Functions_tan_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/tan/y"; + public static final String Built$in_Functions_Modelica_Functions_tanh = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/tanh"; + public static final String Built$in_Functions_Modelica_Functions_tanh_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/tanh/u"; + public static final String Built$in_Functions_Modelica_Functions_tanh_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/tanh/y"; + public static final String Built$in_Functions_Modelica_Functions_terminal = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/terminal"; + public static final String Built$in_Functions_Modelica_Functions_terminal_isTerminal = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Modelica%20Functions/terminal/isTerminal"; + public static final String Built$in_Functions_Vensim_Functions = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions"; + public static final String Built$in_Functions_Vensim_Functions_ABS = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/ABS"; + public static final String Built$in_Functions_Vensim_Functions_ABS_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/ABS/x"; + public static final String Built$in_Functions_Vensim_Functions_ABS_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/ABS/z"; + public static final String Built$in_Functions_Vensim_Functions_COS = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/COS"; + public static final String Built$in_Functions_Vensim_Functions_COSH = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/COSH"; + public static final String Built$in_Functions_Vensim_Functions_COSH_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/COSH/x"; + public static final String Built$in_Functions_Vensim_Functions_COSH_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/COSH/z"; + public static final String Built$in_Functions_Vensim_Functions_COS_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/COS/x"; + public static final String Built$in_Functions_Vensim_Functions_COS_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/COS/z"; + public static final String Built$in_Functions_Vensim_Functions_EXP = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/EXP"; + public static final String Built$in_Functions_Vensim_Functions_EXP_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/EXP/x"; + public static final String Built$in_Functions_Vensim_Functions_EXP_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/EXP/z"; + public static final String Built$in_Functions_Vensim_Functions_IFTHENELSE = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/IFTHENELSE"; + public static final String Built$in_Functions_Vensim_Functions_IFTHENELSE_cond = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/IFTHENELSE/cond"; + public static final String Built$in_Functions_Vensim_Functions_IFTHENELSE_onfalse = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/IFTHENELSE/onfalse"; + public static final String Built$in_Functions_Vensim_Functions_IFTHENELSE_ontrue = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/IFTHENELSE/ontrue"; + public static final String Built$in_Functions_Vensim_Functions_IFTHENELSE_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/IFTHENELSE/z"; + public static final String Built$in_Functions_Vensim_Functions_LN = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/LN"; + public static final String Built$in_Functions_Vensim_Functions_LN_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/LN/x"; + public static final String Built$in_Functions_Vensim_Functions_LN_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/LN/z"; + public static final String Built$in_Functions_Vensim_Functions_MAX = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MAX"; + public static final String Built$in_Functions_Vensim_Functions_MAX_a = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MAX/a"; + public static final String Built$in_Functions_Vensim_Functions_MAX_b = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MAX/b"; + public static final String Built$in_Functions_Vensim_Functions_MAX_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MAX/z"; + public static final String Built$in_Functions_Vensim_Functions_MIN = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MIN"; + public static final String Built$in_Functions_Vensim_Functions_MIN_a = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MIN/a"; + public static final String Built$in_Functions_Vensim_Functions_MIN_b = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MIN/b"; + public static final String Built$in_Functions_Vensim_Functions_MIN_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MIN/z"; + public static final String Built$in_Functions_Vensim_Functions_MODULO = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MODULO"; + public static final String Built$in_Functions_Vensim_Functions_MODULO_a = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MODULO/a"; + public static final String Built$in_Functions_Vensim_Functions_MODULO_b = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MODULO/b"; + public static final String Built$in_Functions_Vensim_Functions_MODULO_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/MODULO/z"; + public static final String Built$in_Functions_Vensim_Functions_PULSE = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/PULSE"; + public static final String Built$in_Functions_Vensim_Functions_PULSE_start = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/PULSE/start"; + public static final String Built$in_Functions_Vensim_Functions_PULSE_width = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/PULSE/width"; + public static final String Built$in_Functions_Vensim_Functions_PULSE_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/PULSE/z"; + public static final String Built$in_Functions_Vensim_Functions_RAMP = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/RAMP"; + public static final String Built$in_Functions_Vensim_Functions_RAMP_endTime = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/RAMP/endTime"; + public static final String Built$in_Functions_Vensim_Functions_RAMP_slope = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/RAMP/slope"; + public static final String Built$in_Functions_Vensim_Functions_RAMP_startTime = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/RAMP/startTime"; + public static final String Built$in_Functions_Vensim_Functions_RAMP_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/RAMP/z"; + public static final String Built$in_Functions_Vensim_Functions_SIN = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/SIN"; + public static final String Built$in_Functions_Vensim_Functions_SINH = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/SINH"; + public static final String Built$in_Functions_Vensim_Functions_SINH_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/SINH/x"; + public static final String Built$in_Functions_Vensim_Functions_SINH_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/SINH/z"; + public static final String Built$in_Functions_Vensim_Functions_SIN_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/SIN/x"; + public static final String Built$in_Functions_Vensim_Functions_SIN_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/SIN/z"; + public static final String Built$in_Functions_Vensim_Functions_SQRT = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/SQRT"; + public static final String Built$in_Functions_Vensim_Functions_SQRT_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/SQRT/x"; + public static final String Built$in_Functions_Vensim_Functions_SQRT_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/SQRT/z"; + public static final String Built$in_Functions_Vensim_Functions_STEP = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/STEP"; + public static final String Built$in_Functions_Vensim_Functions_STEP_height = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/STEP/height"; + public static final String Built$in_Functions_Vensim_Functions_STEP_stepTime = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/STEP/stepTime"; + public static final String Built$in_Functions_Vensim_Functions_STEP_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/STEP/z"; + public static final String Built$in_Functions_Vensim_Functions_TAN = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/TAN"; + public static final String Built$in_Functions_Vensim_Functions_TANH = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/TANH"; + public static final String Built$in_Functions_Vensim_Functions_TANH_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/TANH/x"; + public static final String Built$in_Functions_Vensim_Functions_TANH_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/TANH/z"; + public static final String Built$in_Functions_Vensim_Functions_TAN_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/TAN/x"; + public static final String Built$in_Functions_Vensim_Functions_TAN_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/TAN/z"; + public static final String Built$in_Functions_Vensim_Functions_XIDZ = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/XIDZ"; + public static final String Built$in_Functions_Vensim_Functions_XIDZ_a = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/XIDZ/a"; + public static final String Built$in_Functions_Vensim_Functions_XIDZ_b = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/XIDZ/b"; + public static final String Built$in_Functions_Vensim_Functions_XIDZ_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/XIDZ/x"; + public static final String Built$in_Functions_Vensim_Functions_XIDZ_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/XIDZ/z"; + public static final String Built$in_Functions_Vensim_Functions_ZIDZ = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/ZIDZ"; + public static final String Built$in_Functions_Vensim_Functions_ZIDZ_a = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/ZIDZ/a"; + public static final String Built$in_Functions_Vensim_Functions_ZIDZ_b = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/ZIDZ/b"; + public static final String Built$in_Functions_Vensim_Functions_ZIDZ_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/Vensim%20Functions/ZIDZ/z"; + public static final String Built$in_Functions_interpolate = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/interpolate"; + public static final String Built$in_Functions_interpolateFull = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/interpolateFull"; + public static final String Built$in_Functions_interpolateFull_icol = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/interpolateFull/icol"; + public static final String Built$in_Functions_interpolateFull_table = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/interpolateFull/table"; + public static final String Built$in_Functions_interpolateFull_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/interpolateFull/u"; + public static final String Built$in_Functions_interpolateFull_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/interpolateFull/y"; + public static final String Built$in_Functions_interpolate_table = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/interpolate/table"; + public static final String Built$in_Functions_interpolate_u = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/interpolate/u"; + public static final String Built$in_Functions_interpolate_y = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/interpolate/y"; + public static final String Built$in_Functions_minmax = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/minmax"; + public static final String Built$in_Functions_minmax_expression = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/minmax/expression"; + public static final String Built$in_Functions_minmax_maximum = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/minmax/maximum"; + public static final String Built$in_Functions_minmax_minimum = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/minmax/minimum"; + public static final String Built$in_Functions_minmax_result = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/minmax/result"; + public static final String Built$in_Functions_xidz = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/xidz"; + public static final String Built$in_Functions_xidz_divident = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/xidz/divident"; + public static final String Built$in_Functions_xidz_divisor = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/xidz/divisor"; + public static final String Built$in_Functions_xidz_x = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/xidz/x"; + public static final String Built$in_Functions_xidz_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/xidz/z"; + public static final String Built$in_Functions_zidz = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/zidz"; + public static final String Built$in_Functions_zidz_divident = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/zidz/divident"; + public static final String Built$in_Functions_zidz_divisor = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/zidz/divisor"; + public static final String Built$in_Functions_zidz_z = "http://www.simantics.org/Sysdyn-1.1/Built-in%20Functions/zidz/z"; + public static final String Center = "http://www.simantics.org/Sysdyn-1.1/Center"; + public static final String Charts = "http://www.simantics.org/Sysdyn-1.1/Charts"; + public static final String Charts_SensitivityDataset = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset"; + public static final String Charts_SensitivityDataset_ConfidenceBound = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset/ConfidenceBound"; + public static final String Charts_SensitivityDataset_ConfidenceBound_color = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset/ConfidenceBound/color"; + public static final String Charts_SensitivityDataset_ConfidenceBound_color_Inverse = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset/ConfidenceBound/color/Inverse"; + public static final String Charts_SensitivityDataset_ConfidenceBound_percent = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset/ConfidenceBound/percent"; + public static final String Charts_SensitivityDataset_ConfidenceBound_percent_Inverse = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset/ConfidenceBound/percent/Inverse"; + public static final String Charts_SensitivityDataset_confidenceBounds = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset/confidenceBounds"; + public static final String Charts_SensitivityDataset_confidenceBounds_Inverse = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset/confidenceBounds/Inverse"; + public static final String Charts_SensitivityDataset_median = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset/median"; + public static final String Charts_SensitivityDataset_median_Inverse = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityDataset/median/Inverse"; + public static final String Charts_SensitivityPlot = "http://www.simantics.org/Sysdyn-1.1/Charts/SensitivityPlot"; + public static final String Cloud = "http://www.simantics.org/Sysdyn-1.1/Cloud"; + public static final String CloudSymbol = "http://www.simantics.org/Sysdyn-1.1/CloudSymbol"; + public static final String Component = "http://www.simantics.org/Sysdyn-1.1/Component"; + public static final String Configuration = "http://www.simantics.org/Sysdyn-1.1/Configuration"; + public static final String ConfigurationDiagram = "http://www.simantics.org/Sysdyn-1.1/ConfigurationDiagram"; + public static final String ConfigurationDiagramTemplate = "http://www.simantics.org/Sysdyn-1.1/ConfigurationDiagramTemplate"; + public static final String ConfigurationDiagram_selection = "http://www.simantics.org/Sysdyn-1.1/ConfigurationDiagram/selection"; + public static final String ConfigurationDiagram_selection_Inverse = "http://www.simantics.org/Sysdyn-1.1/ConfigurationDiagram/selection/Inverse"; + public static final String ConstantExpression = "http://www.simantics.org/Sysdyn-1.1/ConstantExpression"; + public static final String DefaultFont = "http://www.simantics.org/Sysdyn-1.1/DefaultFont"; + public static final String DefaultProfile = "http://www.simantics.org/Sysdyn-1.1/DefaultProfile"; + public static final String DefaultRealization = "http://www.simantics.org/Sysdyn-1.1/DefaultRealization"; + public static final String DelayExpression = "http://www.simantics.org/Sysdyn-1.1/DelayExpression"; + public static final String DelayExpression_delayTime = "http://www.simantics.org/Sysdyn-1.1/DelayExpression/delayTime"; + public static final String DelayExpression_delayTime_Inverse = "http://www.simantics.org/Sysdyn-1.1/DelayExpression/delayTime/Inverse"; + public static final String DelayExpression_expression = "http://www.simantics.org/Sysdyn-1.1/DelayExpression/expression"; + public static final String DelayExpression_expression_Inverse = "http://www.simantics.org/Sysdyn-1.1/DelayExpression/expression/Inverse"; + public static final String DelayExpression_initialValue = "http://www.simantics.org/Sysdyn-1.1/DelayExpression/initialValue"; + public static final String DelayExpression_initialValue_Inverse = "http://www.simantics.org/Sysdyn-1.1/DelayExpression/initialValue/Inverse"; + public static final String DelayExpression_order = "http://www.simantics.org/Sysdyn-1.1/DelayExpression/order"; + public static final String DelayExpression_order_Inverse = "http://www.simantics.org/Sysdyn-1.1/DelayExpression/order/Inverse"; + public static final String Dependency = "http://www.simantics.org/Sysdyn-1.1/Dependency"; + public static final String DependencyConnection = "http://www.simantics.org/Sysdyn-1.1/DependencyConnection"; + public static final String DependencyConnection_delayMark = "http://www.simantics.org/Sysdyn-1.1/DependencyConnection/delayMark"; + public static final String DependencyConnection_hideArrow = "http://www.simantics.org/Sysdyn-1.1/DependencyConnection/hideArrow"; + public static final String DependencyConnection_polarity = "http://www.simantics.org/Sysdyn-1.1/DependencyConnection/polarity"; + public static final String DependencyConnection_polarityLocation = "http://www.simantics.org/Sysdyn-1.1/DependencyConnection/polarityLocation"; + public static final String DependencyConnection_polarityLocation_Inverse = "http://www.simantics.org/Sysdyn-1.1/DependencyConnection/polarityLocation/Inverse"; + public static final String DependencyConnection_polarity_Inverse = "http://www.simantics.org/Sysdyn-1.1/DependencyConnection/polarity/Inverse"; + public static final String DependencyConnection_strokeWidth = "http://www.simantics.org/Sysdyn-1.1/DependencyConnection/strokeWidth"; + public static final String DependencyConnection_strokeWidth_Inverse = "http://www.simantics.org/Sysdyn-1.1/DependencyConnection/strokeWidth/Inverse"; + public static final String Dependency_angle = "http://www.simantics.org/Sysdyn-1.1/Dependency/angle"; + public static final String Dependency_angle_Inverse = "http://www.simantics.org/Sysdyn-1.1/Dependency/angle/Inverse"; + public static final String Dependency_refersTo = "http://www.simantics.org/Sysdyn-1.1/Dependency/refersTo"; + public static final String DiagramToCompositeMapping = "http://www.simantics.org/Sysdyn-1.1/DiagramToCompositeMapping"; + public static final String Enumeration = "http://www.simantics.org/Sysdyn-1.1/Enumeration"; + public static final String EnumerationIndex = "http://www.simantics.org/Sysdyn-1.1/EnumerationIndex"; + public static final String EnumerationIndex_showEnumerationIndexInCharts = "http://www.simantics.org/Sysdyn-1.1/EnumerationIndex/showEnumerationIndexInCharts"; + public static final String EnumerationIndex_showEnumerationIndexInCharts_Inverse = "http://www.simantics.org/Sysdyn-1.1/EnumerationIndex/showEnumerationIndexInCharts/Inverse"; + public static final String EnumerationIndexes = "http://www.simantics.org/Sysdyn-1.1/EnumerationIndexes"; + public static final String EnumerationIndexes_Inverse = "http://www.simantics.org/Sysdyn-1.1/EnumerationIndexes/Inverse"; + public static final String EnumerationReplacement = "http://www.simantics.org/Sysdyn-1.1/EnumerationReplacement"; + public static final String Enumeration_enumerationIndexList = "http://www.simantics.org/Sysdyn-1.1/Enumeration/enumerationIndexList"; + public static final String Enumeration_enumerationIndexList_Inverse = "http://www.simantics.org/Sysdyn-1.1/Enumeration/enumerationIndexList/Inverse"; + public static final String Enumeration_enumerationIndexes = "http://www.simantics.org/Sysdyn-1.1/Enumeration/enumerationIndexes"; + public static final String Enumeration_enumerationIndexes_Inverse = "http://www.simantics.org/Sysdyn-1.1/Enumeration/enumerationIndexes/Inverse"; + public static final String Enumeration_isReplaceable = "http://www.simantics.org/Sysdyn-1.1/Enumeration/isReplaceable"; + public static final String Enumeration_isReplaceable_Inverse = "http://www.simantics.org/Sysdyn-1.1/Enumeration/isReplaceable/Inverse"; + public static final String Experiment = "http://www.simantics.org/Sysdyn-1.1/Experiment"; + public static final String Experiment_Run = "http://www.simantics.org/Sysdyn-1.1/Experiment/Run"; + public static final String Experiment_Run_time = "http://www.simantics.org/Sysdyn-1.1/Experiment/Run/time"; + public static final String Experiment_Run_time_Inverse = "http://www.simantics.org/Sysdyn-1.1/Experiment/Run/time/Inverse"; + public static final String Experiment_result = "http://www.simantics.org/Sysdyn-1.1/Experiment/result"; + public static final String Experiment_resultSet = "http://www.simantics.org/Sysdyn-1.1/Experiment/resultSet"; + public static final String Experiment_resultSet_Inverse = "http://www.simantics.org/Sysdyn-1.1/Experiment/resultSet/Inverse"; + public static final String Experiment_result_Inverse = "http://www.simantics.org/Sysdyn-1.1/Experiment/result/Inverse"; + public static final String ExportModuleTree = "http://www.simantics.org/Sysdyn-1.1/ExportModuleTree"; + public static final String Expression = "http://www.simantics.org/Sysdyn-1.1/Expression"; + public static final String Expression_arrayRange = "http://www.simantics.org/Sysdyn-1.1/Expression/arrayRange"; + public static final String Expression_arrayRange_Inverse = "http://www.simantics.org/Sysdyn-1.1/Expression/arrayRange/Inverse"; + public static final String Expression_equation = "http://www.simantics.org/Sysdyn-1.1/Expression/equation"; + public static final String Expression_equation_Inverse = "http://www.simantics.org/Sysdyn-1.1/Expression/equation/Inverse"; + public static final String Expressions = "http://www.simantics.org/Sysdyn-1.1/Expressions"; + public static final String Expressions_Inverse = "http://www.simantics.org/Sysdyn-1.1/Expressions/Inverse"; + public static final String ExternalFiles = "http://www.simantics.org/Sysdyn-1.1/ExternalFiles"; + public static final String ExternalFunctionFile = "http://www.simantics.org/Sysdyn-1.1/ExternalFunctionFile"; + public static final String ExternalFunctionFile_externalFile = "http://www.simantics.org/Sysdyn-1.1/ExternalFunctionFile/externalFile"; + public static final String ExternalFunctionFile_externalFile_Inverse = "http://www.simantics.org/Sysdyn-1.1/ExternalFunctionFile/externalFile/Inverse"; + public static final String Flow = "http://www.simantics.org/Sysdyn-1.1/Flow"; + public static final String FlowConnection = "http://www.simantics.org/Sysdyn-1.1/FlowConnection"; + public static final String FlowConnection_width = "http://www.simantics.org/Sysdyn-1.1/FlowConnection/width"; + public static final String FlowConnection_width_Inverse = "http://www.simantics.org/Sysdyn-1.1/FlowConnection/width/Inverse"; + public static final String FunctionTree = "http://www.simantics.org/Sysdyn-1.1/FunctionTree"; + public static final String Functions = "http://www.simantics.org/Sysdyn-1.1/Functions"; + public static final String Functions_runChildren = "http://www.simantics.org/Sysdyn-1.1/Functions/runChildren"; + public static final String Functions_runProperties = "http://www.simantics.org/Sysdyn-1.1/Functions/runProperties"; + public static final String Functions_valuePropertyProperties = "http://www.simantics.org/Sysdyn-1.1/Functions/valuePropertyProperties"; + public static final String Functions_valuePropertyValue = "http://www.simantics.org/Sysdyn-1.1/Functions/valuePropertyValue"; + public static final String GameExperiment = "http://www.simantics.org/Sysdyn-1.1/GameExperiment"; + public static final String GameExperiment_stepDuration = "http://www.simantics.org/Sysdyn-1.1/GameExperiment/stepDuration"; + public static final String GameExperiment_stepDuration_Inverse = "http://www.simantics.org/Sysdyn-1.1/GameExperiment/stepDuration/Inverse"; + public static final String GameExperiment_stepLength = "http://www.simantics.org/Sysdyn-1.1/GameExperiment/stepLength"; + public static final String GameExperiment_stepLength_Inverse = "http://www.simantics.org/Sysdyn-1.1/GameExperiment/stepLength/Inverse"; + public static final String HaltonSequenceGenerator = "http://www.simantics.org/Sysdyn-1.1/HaltonSequenceGenerator"; + public static final String HasEquationOrEmpty = "http://www.simantics.org/Sysdyn-1.1/HasEquationOrEmpty"; + public static final String HasEquationOrEmpty_Inverse = "http://www.simantics.org/Sysdyn-1.1/HasEquationOrEmpty/Inverse"; + public static final String HasHeadTerminal = "http://www.simantics.org/Sysdyn-1.1/HasHeadTerminal"; + public static final String HasRangeEnd = "http://www.simantics.org/Sysdyn-1.1/HasRangeEnd"; + public static final String HasRangeEnd_Inverse = "http://www.simantics.org/Sysdyn-1.1/HasRangeEnd/Inverse"; + public static final String HasRangeStart = "http://www.simantics.org/Sysdyn-1.1/HasRangeStart"; + public static final String HasRangeStart_Inverse = "http://www.simantics.org/Sysdyn-1.1/HasRangeStart/Inverse"; + public static final String HasRangeStep = "http://www.simantics.org/Sysdyn-1.1/HasRangeStep"; + public static final String HasRangeStep_Inverse = "http://www.simantics.org/Sysdyn-1.1/HasRangeStep/Inverse"; + public static final String HasTailTerminal = "http://www.simantics.org/Sysdyn-1.1/HasTailTerminal"; + public static final String HistoryDataset = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset"; + public static final String HistoryDataset_FoundVariableNameNode = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/FoundVariableNameNode"; + public static final String HistoryDataset_HistoryDatasetVariablesBrowseContext = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/HistoryDatasetVariablesBrowseContext"; + public static final String HistoryDataset_HistoryDatasetVariablesBrowseContext_StringNodeType = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/HistoryDatasetVariablesBrowseContext/StringNodeType"; + public static final String HistoryDataset_HistoryDatasetVariablesBrowseContext_VariableChildRule = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/HistoryDatasetVariablesBrowseContext/VariableChildRule"; + public static final String HistoryDataset_HistoryDatasetVariablesBrowseContext_VariableLabelRule = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/HistoryDatasetVariablesBrowseContext/VariableLabelRule"; + public static final String HistoryDataset_columns = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/columns"; + public static final String HistoryDataset_columns_Inverse = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/columns/Inverse"; + public static final String HistoryDataset_end = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/end"; + public static final String HistoryDataset_end_Inverse = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/end/Inverse"; + public static final String HistoryDataset_sheet = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/sheet"; + public static final String HistoryDataset_start = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/start"; + public static final String HistoryDataset_start_Inverse = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/start/Inverse"; + public static final String HistoryDataset_timeName = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/timeName"; + public static final String HistoryDataset_timeName_Inverse = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/timeName/Inverse"; + public static final String HistoryRealization = "http://www.simantics.org/Sysdyn-1.1/HistoryRealization"; + public static final String Horizontal = "http://www.simantics.org/Sysdyn-1.1/Horizontal"; + public static final String ImportModuleTree = "http://www.simantics.org/Sysdyn-1.1/ImportModuleTree"; + public static final String ImportedOntologies = "http://www.simantics.org/Sysdyn-1.1/ImportedOntologies"; + public static final String IndependentVariable = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable"; + public static final String IndependentVariable_activeExpression = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/activeExpression"; + public static final String IndependentVariable_isUninitialized = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/isUninitialized"; + public static final String IndependentVariable_isUninitialized_Inverse = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/isUninitialized/Inverse"; + public static final String IndependentVariable_rangeEnd = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/rangeEnd"; + public static final String IndependentVariable_rangeEnd_Inverse = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/rangeEnd/Inverse"; + public static final String IndependentVariable_rangeStart = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/rangeStart"; + public static final String IndependentVariable_rangeStart_Inverse = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/rangeStart/Inverse"; + public static final String IndependentVariable_rangeStep = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/rangeStep"; + public static final String IndependentVariable_rangeStep_Inverse = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/rangeStep/Inverse"; + public static final String IndependentVariable_unit = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/unit"; + public static final String IndependentVariable_unit_Inverse = "http://www.simantics.org/Sysdyn-1.1/IndependentVariable/unit/Inverse"; + public static final String Input = "http://www.simantics.org/Sysdyn-1.1/Input"; + public static final String InputSymbol = "http://www.simantics.org/Sysdyn-1.1/InputSymbol"; + public static final String Input_defaultInputValue = "http://www.simantics.org/Sysdyn-1.1/Input/defaultInputValue"; + public static final String Input_defaultInputValue_Inverse = "http://www.simantics.org/Sysdyn-1.1/Input/defaultInputValue/Inverse"; + public static final String Interval = "http://www.simantics.org/Sysdyn-1.1/Interval"; + public static final String Interval_maxValue = "http://www.simantics.org/Sysdyn-1.1/Interval/maxValue"; + public static final String Interval_maxValue_Inverse = "http://www.simantics.org/Sysdyn-1.1/Interval/maxValue/Inverse"; + public static final String Interval_minValue = "http://www.simantics.org/Sysdyn-1.1/Interval/minValue"; + public static final String Interval_minValue_Inverse = "http://www.simantics.org/Sysdyn-1.1/Interval/minValue/Inverse"; + public static final String IsHeadOfTerminal = "http://www.simantics.org/Sysdyn-1.1/IsHeadOfTerminal"; + public static final String IsOutput = "http://www.simantics.org/Sysdyn-1.1/IsOutput"; + public static final String IsTailOfTerminal = "http://www.simantics.org/Sysdyn-1.1/IsTailOfTerminal"; + public static final String IssueStyle = "http://www.simantics.org/Sysdyn-1.1/IssueStyle"; + public static final String Left = "http://www.simantics.org/Sysdyn-1.1/Left"; + public static final String Location = "http://www.simantics.org/Sysdyn-1.1/Location"; + public static final String LookupExpression = "http://www.simantics.org/Sysdyn-1.1/LookupExpression"; + public static final String LookupExpression_lookup = "http://www.simantics.org/Sysdyn-1.1/LookupExpression/lookup"; + public static final String LookupExpression_lookup_Inverse = "http://www.simantics.org/Sysdyn-1.1/LookupExpression/lookup/Inverse"; + public static final String Loop = "http://www.simantics.org/Sysdyn-1.1/Loop"; + public static final String LoopSymbol = "http://www.simantics.org/Sysdyn-1.1/LoopSymbol"; + public static final String LoopSymbol_Clockwise = "http://www.simantics.org/Sysdyn-1.1/LoopSymbol/Clockwise"; + public static final String LoopSymbol_Clockwise_Inverse = "http://www.simantics.org/Sysdyn-1.1/LoopSymbol/Clockwise/Inverse"; + public static final String Loop_Comment = "http://www.simantics.org/Sysdyn-1.1/Loop/Comment"; + public static final String Loop_Comment_Inverse = "http://www.simantics.org/Sysdyn-1.1/Loop/Comment/Inverse"; + public static final String Loop_Items = "http://www.simantics.org/Sysdyn-1.1/Loop/Items"; + public static final String Loop_Items_Inverse = "http://www.simantics.org/Sysdyn-1.1/Loop/Items/Inverse"; + public static final String Migration = "http://www.simantics.org/Sysdyn-1.1/Migration"; + public static final String Migration_from1$6to1$7 = "http://www.simantics.org/Sysdyn-1.1/Migration/from1.6to1.7"; + public static final String Migration_from1$6to1$7_Ontologies = "http://www.simantics.org/Sysdyn-1.1/Migration/from1.6to1.7/Ontologies"; + public static final String Migration_from1$6to1$7_OrderedSetsToLists = "http://www.simantics.org/Sysdyn-1.1/Migration/from1.6to1.7/OrderedSetsToLists"; + public static final String Migration_from1$6to1$7_Spreadsheets = "http://www.simantics.org/Sysdyn-1.1/Migration/from1.6to1.7/Spreadsheets"; + public static final String Migration_from1$6to1$7_SysdynChanges = "http://www.simantics.org/Sysdyn-1.1/Migration/from1.6to1.7/SysdynChanges"; + public static final String Migration_fromFunctionLibrary1 = "http://www.simantics.org/Sysdyn-1.1/Migration/fromFunctionLibrary1"; + public static final String Migration_fromModel1 = "http://www.simantics.org/Sysdyn-1.1/Migration/fromModel1"; + public static final String Migration_fromModule1 = "http://www.simantics.org/Sysdyn-1.1/Migration/fromModule1"; + public static final String ModelBrowser = "http://www.simantics.org/Sysdyn-1.1/ModelBrowser"; + public static final String ModelingActionContext = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext"; + public static final String ModelingActionContext_Actions = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions"; + public static final String ModelingActionContext_Actions_ChartDropAction = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/ChartDropAction"; + public static final String ModelingActionContext_Actions_FunctionDropAction = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/FunctionDropAction"; + public static final String ModelingActionContext_Actions_NewBarChart = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewBarChart"; + public static final String ModelingActionContext_Actions_NewEnumeration = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewEnumeration"; + public static final String ModelingActionContext_Actions_NewExperiment = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewExperiment"; + public static final String ModelingActionContext_Actions_NewFunction = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewFunction"; + public static final String ModelingActionContext_Actions_NewFunctionLibrary = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewFunctionLibrary"; + public static final String ModelingActionContext_Actions_NewHistoryData = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewHistoryData"; + public static final String ModelingActionContext_Actions_NewLineChart = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewLineChart"; + public static final String ModelingActionContext_Actions_NewModuleType = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewModuleType"; + public static final String ModelingActionContext_Actions_NewPieChart = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewPieChart"; + public static final String ModelingActionContext_Actions_NewSharedFunctionLibrary = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewSharedFunctionLibrary"; + public static final String ModelingActionContext_Actions_NewSheet = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewSheet"; + public static final String ModelingActionContext_Actions_NewSimulationPlaybackExperiment = "http://www.simantics.org/Sysdyn-1.1/ModelingActionContext/Actions/NewSimulationPlaybackExperiment"; + public static final String ModelingBrowseContext = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext"; + public static final String ModelingBrowseContext_ActiveLabelDecorationRule = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ActiveLabelDecorationRule"; + public static final String ModelingBrowseContext_BuiltinFunctions = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/BuiltinFunctions"; + public static final String ModelingBrowseContext_ChartImageRule = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ChartImageRule"; + public static final String ModelingBrowseContext_ChartsFolder = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ChartsFolder"; + public static final String ModelingBrowseContext_ExperimentsFolder = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ExperimentsFolder"; + public static final String ModelingBrowseContext_FunctionsFolder = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/FunctionsFolder"; + public static final String ModelingBrowseContext_ModuleContentChildRule = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ModuleContentChildRule"; + public static final String ModelingBrowseContext_ModuleSymbol = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ModuleSymbol"; + public static final String ModelingBrowseContext_ModuleSymbolNodeType = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ModuleSymbolNodeType"; + public static final String ModelingBrowseContext_ModuleTypeChildRule = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ModuleTypeChildRule"; + public static final String ModelingBrowseContext_ModuleTypeLabelRule = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ModuleTypeLabelRule"; + public static final String ModelingBrowseContext_ModulesFolder = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ModulesFolder"; + public static final String ModelingBrowseContext_ResultImageRule = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/ResultImageRule"; + public static final String ModelingBrowseContext_SharedFunctionsFolder = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/SharedFunctionsFolder"; + public static final String ModelingBrowseContext_Variable = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/Variable"; + public static final String ModelingBrowseContext_VariableChildRule = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/VariableChildRule"; + public static final String ModelingBrowseContext_VariableImageRule = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/VariableImageRule"; + public static final String ModelingBrowseContext_VariableNameLabelRule = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/VariableNameLabelRule"; + public static final String ModelingBrowseContext_VariableNodeType = "http://www.simantics.org/Sysdyn-1.1/ModelingBrowseContext/VariableNodeType"; + public static final String Module = "http://www.simantics.org/Sysdyn-1.1/Module"; + public static final String ModuleSymbol = "http://www.simantics.org/Sysdyn-1.1/ModuleSymbol"; + public static final String Module_ParameterOverride = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverride"; + public static final String Module_ParameterOverrideBrowseContext = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverrideBrowseContext"; + public static final String Module_ParameterOverrideBrowseContext_Node = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverrideBrowseContext/Node"; + public static final String Module_ParameterOverrideBrowseContext_NodeType = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverrideBrowseContext/NodeType"; + public static final String Module_ParameterOverrideBrowseContext_ParameterChildRule = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverrideBrowseContext/ParameterChildRule"; + public static final String Module_ParameterOverrideBrowseContext_ParameterLabelDecorationRule = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverrideBrowseContext/ParameterLabelDecorationRule"; + public static final String Module_ParameterOverrideBrowseContext_ParameterLabelRule = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverrideBrowseContext/ParameterLabelRule"; + public static final String Module_ParameterOverrideBrowseContext_ParameterModifierRule = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverrideBrowseContext/ParameterModifierRule"; + public static final String Module_ParameterOverrideBrowseContext_ParameterSorterRule = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverrideBrowseContext/ParameterSorterRule"; + public static final String Module_ParameterOverride_overriddenParameter = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverride/overriddenParameter"; + public static final String Module_ParameterOverride_overrideExpression = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverride/overrideExpression"; + public static final String Module_ParameterOverride_overrideExpression_Inverse = "http://www.simantics.org/Sysdyn-1.1/Module/ParameterOverride/overrideExpression/Inverse"; + public static final String Module_parameterOverride = "http://www.simantics.org/Sysdyn-1.1/Module/parameterOverride"; + public static final String Module_parameterOverride_Inverse = "http://www.simantics.org/Sysdyn-1.1/Module/parameterOverride/Inverse"; + public static final String Module_redeclaration = "http://www.simantics.org/Sysdyn-1.1/Module/redeclaration"; + public static final String Module_redeclaration_Inverse = "http://www.simantics.org/Sysdyn-1.1/Module/redeclaration/Inverse"; + public static final String ModulesSearchFunction = "http://www.simantics.org/Sysdyn-1.1/ModulesSearchFunction"; + public static final String NormalDistribution = "http://www.simantics.org/Sysdyn-1.1/NormalDistribution"; + public static final String NormalDistribution_maxValue = "http://www.simantics.org/Sysdyn-1.1/NormalDistribution/maxValue"; + public static final String NormalDistribution_maxValue_Inverse = "http://www.simantics.org/Sysdyn-1.1/NormalDistribution/maxValue/Inverse"; + public static final String NormalDistribution_mean = "http://www.simantics.org/Sysdyn-1.1/NormalDistribution/mean"; + public static final String NormalDistribution_mean_Inverse = "http://www.simantics.org/Sysdyn-1.1/NormalDistribution/mean/Inverse"; + public static final String NormalDistribution_minValue = "http://www.simantics.org/Sysdyn-1.1/NormalDistribution/minValue"; + public static final String NormalDistribution_minValue_Inverse = "http://www.simantics.org/Sysdyn-1.1/NormalDistribution/minValue/Inverse"; + public static final String NormalDistribution_stdDeviation = "http://www.simantics.org/Sysdyn-1.1/NormalDistribution/stdDeviation"; + public static final String NormalDistribution_stdDeviation_Inverse = "http://www.simantics.org/Sysdyn-1.1/NormalDistribution/stdDeviation/Inverse"; + public static final String NormalExpression = "http://www.simantics.org/Sysdyn-1.1/NormalExpression"; + public static final String Orientation = "http://www.simantics.org/Sysdyn-1.1/Orientation"; + public static final String ParameterExpression = "http://www.simantics.org/Sysdyn-1.1/ParameterExpression"; + public static final String PlaybackExperiment = "http://www.simantics.org/Sysdyn-1.1/PlaybackExperiment"; + public static final String ProbabilityDistribution = "http://www.simantics.org/Sysdyn-1.1/ProbabilityDistribution"; + public static final String Profiles = "http://www.simantics.org/Sysdyn-1.1/Profiles"; + public static final String Profiles_IssueWarnings = "http://www.simantics.org/Sysdyn-1.1/Profiles/IssueWarnings"; + public static final String Profiles_ShadowVisualizations = "http://www.simantics.org/Sysdyn-1.1/Profiles/ShadowVisualizations"; + public static final String Profiles_SimulationPlaybackColours = "http://www.simantics.org/Sysdyn-1.1/Profiles/SimulationPlaybackColours"; + public static final String RandomGenerator = "http://www.simantics.org/Sysdyn-1.1/RandomGenerator"; + public static final String Redeclaration = "http://www.simantics.org/Sysdyn-1.1/Redeclaration"; + public static final String Redeclaration_replacedEnumeration = "http://www.simantics.org/Sysdyn-1.1/Redeclaration/replacedEnumeration"; + public static final String Redeclaration_replacedEnumeration_Inverse = "http://www.simantics.org/Sysdyn-1.1/Redeclaration/replacedEnumeration/Inverse"; + public static final String Redeclaration_replacingEnumeration = "http://www.simantics.org/Sysdyn-1.1/Redeclaration/replacingEnumeration"; + public static final String Redeclaration_replacingEnumeration_Inverse = "http://www.simantics.org/Sysdyn-1.1/Redeclaration/replacingEnumeration/Inverse"; + public static final String Result = "http://www.simantics.org/Sysdyn-1.1/Result"; + public static final String ResultSet = "http://www.simantics.org/Sysdyn-1.1/ResultSet"; + public static final String Result_parameterFile = "http://www.simantics.org/Sysdyn-1.1/Result/parameterFile"; + public static final String Result_parameterFile_Inverse = "http://www.simantics.org/Sysdyn-1.1/Result/parameterFile/Inverse"; + public static final String Result_resultFile = "http://www.simantics.org/Sysdyn-1.1/Result/resultFile"; + public static final String Result_resultFile_Inverse = "http://www.simantics.org/Sysdyn-1.1/Result/resultFile/Inverse"; + public static final String Result_showResult = "http://www.simantics.org/Sysdyn-1.1/Result/showResult"; + public static final String Result_time = "http://www.simantics.org/Sysdyn-1.1/Result/time"; + public static final String Result_time_Inverse = "http://www.simantics.org/Sysdyn-1.1/Result/time/Inverse"; + public static final String Right = "http://www.simantics.org/Sysdyn-1.1/Right"; + public static final String SearchContribution = "http://www.simantics.org/Sysdyn-1.1/SearchContribution"; + public static final String SelectedSharedFunctionLibraries = "http://www.simantics.org/Sysdyn-1.1/SelectedSharedFunctionLibraries"; + public static final String SensitivityAnalysisExperiment = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment"; + public static final String SensitivityAnalysisExperiment_Parameter = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter"; + public static final String SensitivityAnalysisExperiment_ParameterActionContext = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/ParameterActionContext"; + public static final String SensitivityAnalysisExperiment_ParameterActionContext_Actions = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/ParameterActionContext/Actions"; + public static final String SensitivityAnalysisExperiment_ParameterBrowseContext = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/ParameterBrowseContext"; + public static final String SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterChildRule = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/ParameterBrowseContext/ParameterChildRule"; + public static final String SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterLabelRule = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/ParameterBrowseContext/ParameterLabelRule"; + public static final String SensitivityAnalysisExperiment_Parameter_indexes = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/indexes"; + public static final String SensitivityAnalysisExperiment_Parameter_indexes_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/indexes/Inverse"; + public static final String SensitivityAnalysisExperiment_Parameter_propabilityDistribution = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/propabilityDistribution"; + public static final String SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/propabilityDistribution/Inverse"; + public static final String SensitivityAnalysisExperiment_Parameter_variable = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/variable"; + public static final String SensitivityAnalysisExperiment_Parameter_variable_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/variable/Inverse"; + public static final String SensitivityAnalysisExperiment_method = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/method"; + public static final String SensitivityAnalysisExperiment_method_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/method/Inverse"; + public static final String SensitivityAnalysisExperiment_numberOfValues = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/numberOfValues"; + public static final String SensitivityAnalysisExperiment_numberOfValues_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/numberOfValues/Inverse"; + public static final String SensitivityAnalysisExperiment_parameterList = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/parameterList"; + public static final String SensitivityAnalysisExperiment_parameterList_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/parameterList/Inverse"; + public static final String SensitivityAnalysisExperiment_randomSeed = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/randomSeed"; + public static final String SensitivityAnalysisExperiment_randomSeed_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/randomSeed/Inverse"; + public static final String SensitivityAnalysisExperiment_resultRefreshRate = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/resultRefreshRate"; + public static final String SensitivityAnalysisExperiment_resultRefreshRate_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/resultRefreshRate/Inverse"; + public static final String Shadow = "http://www.simantics.org/Sysdyn-1.1/Shadow"; + public static final String ShadowStyle = "http://www.simantics.org/Sysdyn-1.1/ShadowStyle"; + public static final String ShadowSymbol = "http://www.simantics.org/Sysdyn-1.1/ShadowSymbol"; + public static final String Shadow_original = "http://www.simantics.org/Sysdyn-1.1/Shadow/original"; + public static final String Shadow_original_Inverse = "http://www.simantics.org/Sysdyn-1.1/Shadow/original/Inverse"; + public static final String SharedFunctionOntology = "http://www.simantics.org/Sysdyn-1.1/SharedFunctionOntology"; + public static final String SharedModuleOntology = "http://www.simantics.org/Sysdyn-1.1/SharedModuleOntology"; + public static final String SimulateOnChangeExperiment = "http://www.simantics.org/Sysdyn-1.1/SimulateOnChangeExperiment"; + public static final String SimulationPlaybackProfile = "http://www.simantics.org/Sysdyn-1.1/SimulationPlaybackProfile"; + public static final String SimulationPlaybackStyle = "http://www.simantics.org/Sysdyn-1.1/SimulationPlaybackStyle"; + public static final String Stock = "http://www.simantics.org/Sysdyn-1.1/Stock"; + public static final String StockExpression = "http://www.simantics.org/Sysdyn-1.1/StockExpression"; + public static final String StockExpression_initialEquation = "http://www.simantics.org/Sysdyn-1.1/StockExpression/initialEquation"; + public static final String StockExpression_initialEquation_Inverse = "http://www.simantics.org/Sysdyn-1.1/StockExpression/initialEquation/Inverse"; + public static final String StockExpression_integralEquation = "http://www.simantics.org/Sysdyn-1.1/StockExpression/integralEquation"; + public static final String StockExpression_integralEquation_Inverse = "http://www.simantics.org/Sysdyn-1.1/StockExpression/integralEquation/Inverse"; + public static final String StockExpression_useCustomIntegral = "http://www.simantics.org/Sysdyn-1.1/StockExpression/useCustomIntegral"; + public static final String StockSymbol = "http://www.simantics.org/Sysdyn-1.1/StockSymbol"; + public static final String SymbolReferences = "http://www.simantics.org/Sysdyn-1.1/SymbolReferences"; + public static final String SymbolReferences_BasicSymbols = "http://www.simantics.org/Sysdyn-1.1/SymbolReferences/BasicSymbols"; + public static final String SymbolReferences_CommentSymbols = "http://www.simantics.org/Sysdyn-1.1/SymbolReferences/CommentSymbols"; + public static final String Symbols = "http://www.simantics.org/Sysdyn-1.1/Symbols"; + public static final String SysdynConnectionType = "http://www.simantics.org/Sysdyn-1.1/SysdynConnectionType"; + public static final String SysdynDiagramModelingRules = "http://www.simantics.org/Sysdyn-1.1/SysdynDiagramModelingRules"; + public static final String SysdynModel = "http://www.simantics.org/Sysdyn-1.1/SysdynModel"; + public static final String SysdynModel_fmuFile = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/fmuFile"; + public static final String SysdynModel_fmuFile_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/fmuFile/Inverse"; + public static final String SysdynModel_lastExportFileName = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/lastExportFileName"; + public static final String SysdynModel_lastExportFileName_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/lastExportFileName/Inverse"; + public static final String SysdynModel_lastExportFilePath = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/lastExportFilePath"; + public static final String SysdynModel_lastExportFilePath_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/lastExportFilePath/Inverse"; + public static final String SysdynModel_outputInterval = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/outputInterval"; + public static final String SysdynModel_outputInterval_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/outputInterval/Inverse"; + public static final String SysdynModel_simulationStepLength = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/simulationStepLength"; + public static final String SysdynModel_simulationStepLength_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/simulationStepLength/Inverse"; + public static final String SysdynModel_solver = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/solver"; + public static final String SysdynModel_solver_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/solver/Inverse"; + public static final String SysdynModel_startTime = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/startTime"; + public static final String SysdynModel_startTime_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/startTime/Inverse"; + public static final String SysdynModel_stopTime = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/stopTime"; + public static final String SysdynModel_stopTime_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/stopTime/Inverse"; + public static final String SysdynModel_timeUnit = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/timeUnit"; + public static final String SysdynModel_timeUnit_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/timeUnit/Inverse"; + public static final String SysdynModel_tolerance = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/tolerance"; + public static final String SysdynModel_tolerance_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/tolerance/Inverse"; + public static final String SysdynModel_variableFilter = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/variableFilter"; + public static final String SysdynModel_variableFilter_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/variableFilter/Inverse"; + public static final String SysdynModelicaFunction = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction"; + public static final String SysdynModelicaFunctionLibrary = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunctionLibrary"; + public static final String SysdynModelicaFunction_Input = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/Input"; + public static final String SysdynModelicaFunction_InterfaceVariable = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/InterfaceVariable"; + public static final String SysdynModelicaFunction_Output = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/Output"; + public static final String SysdynModelicaFunction_VariableLengthInput = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/VariableLengthInput"; + public static final String SysdynModelicaFunction_VariableLengthInput_shownLabels = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/VariableLengthInput/shownLabels"; + public static final String SysdynModelicaFunction_VariableLengthInput_shownLabels_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/VariableLengthInput/shownLabels/Inverse"; + public static final String SysdynModelicaFunction_definition = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/definition"; + public static final String SysdynModelicaFunction_definition_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/definition/Inverse"; + public static final String SysdynModelicaFunction_inputs = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/inputs"; + public static final String SysdynModelicaFunction_inputs_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/inputs/Inverse"; + public static final String SysdynModelicaFunction_modelicaFunctionCode = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/modelicaFunctionCode"; + public static final String SysdynModelicaFunction_modelicaFunctionCode_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/modelicaFunctionCode/Inverse"; + public static final String SysdynModelicaFunction_modelicaFunctionInterface = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/modelicaFunctionInterface"; + public static final String SysdynModelicaFunction_modelicaFunctionInterface_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/modelicaFunctionInterface/Inverse"; + public static final String SysdynModelicaFunction_optional = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/optional"; + public static final String SysdynModelicaFunction_optional_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/optional/Inverse"; + public static final String SysdynModelicaFunction_outputs = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/outputs"; + public static final String SysdynModelicaFunction_outputs_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/outputs/Inverse"; + public static final String SysdynModelicaFunction_unit = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/unit"; + public static final String SysdynModelicaFunction_unit_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModelicaFunction/unit/Inverse"; + public static final String SysdynModuleLibrary = "http://www.simantics.org/Sysdyn-1.1/SysdynModuleLibrary"; + public static final String SysdynOperationBrowser = "http://www.simantics.org/Sysdyn-1.1/SysdynOperationBrowser"; + public static final String SysdynSymbol = "http://www.simantics.org/Sysdyn-1.1/SysdynSymbol"; + public static final String SysdynTerminal = "http://www.simantics.org/Sysdyn-1.1/SysdynTerminal"; + public static final String Top = "http://www.simantics.org/Sysdyn-1.1/Top"; + public static final String UniformDistribution = "http://www.simantics.org/Sysdyn-1.1/UniformDistribution"; + public static final String UniformDistribution_maxValue = "http://www.simantics.org/Sysdyn-1.1/UniformDistribution/maxValue"; + public static final String UniformDistribution_maxValue_Inverse = "http://www.simantics.org/Sysdyn-1.1/UniformDistribution/maxValue/Inverse"; + public static final String UniformDistribution_minValue = "http://www.simantics.org/Sysdyn-1.1/UniformDistribution/minValue"; + public static final String UniformDistribution_minValue_Inverse = "http://www.simantics.org/Sysdyn-1.1/UniformDistribution/minValue/Inverse"; + public static final String UsedVariableIndexes = "http://www.simantics.org/Sysdyn-1.1/UsedVariableIndexes"; + public static final String Validations = "http://www.simantics.org/Sysdyn-1.1/Validations"; + public static final String Validations_Dependencies = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies"; + public static final String Validations_Dependencies_DependencyConnectionsIssueSource = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/DependencyConnectionsIssueSource"; + public static final String Validations_Dependencies_MissingDependencyConnectionsIssueSource = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/MissingDependencyConnectionsIssueSource"; + public static final String Validations_Dependencies_dependencyValidator = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/dependencyValidator"; + public static final String Validations_Dependencies_invalidSheetReferenceIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/invalidSheetReferenceIssueDescription"; + public static final String Validations_Dependencies_missingDependencyValidator = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/missingDependencyValidator"; + public static final String Validations_Dependencies_missingLinkIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/missingLinkIssueDescription"; + public static final String Validations_Dependencies_noSuchVariableIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/noSuchVariableIssueDescription"; + public static final String Validations_Dependencies_rangeIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/rangeIssueDescription"; + public static final String Validations_Dependencies_rangeWarningDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/rangeWarningDescription"; + public static final String Validations_Dependencies_unusedDependencyIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/unusedDependencyIssueDescription"; + public static final String Validations_DependencyConstraint = "http://www.simantics.org/Sysdyn-1.1/Validations/DependencyConstraint"; + public static final String Validations_EmptyEnumerationIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/EmptyEnumerationIssue"; + public static final String Validations_EnumerationConstraint = "http://www.simantics.org/Sysdyn-1.1/Validations/EnumerationConstraint"; + public static final String Validations_Enumerations = "http://www.simantics.org/Sysdyn-1.1/Validations/Enumerations"; + public static final String Validations_Enumerations_EnumerationIssueSource = "http://www.simantics.org/Sysdyn-1.1/Validations/Enumerations/EnumerationIssueSource"; + public static final String Validations_Enumerations_emptyEnumerationIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Enumerations/emptyEnumerationIssueDescription"; + public static final String Validations_Enumerations_enumerationIndexValidator = "http://www.simantics.org/Sysdyn-1.1/Validations/Enumerations/enumerationIndexValidator"; + public static final String Validations_ExpressionConstraint = "http://www.simantics.org/Sysdyn-1.1/Validations/ExpressionConstraint"; + public static final String Validations_ExpressionIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/ExpressionIssue"; + public static final String Validations_Expressions = "http://www.simantics.org/Sysdyn-1.1/Validations/Expressions"; + public static final String Validations_Expressions_ExpressionIssueSource = "http://www.simantics.org/Sysdyn-1.1/Validations/Expressions/ExpressionIssueSource"; + public static final String Validations_Expressions_expressionIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Expressions/expressionIssueDescription"; + public static final String Validations_Expressions_expressionValidator = "http://www.simantics.org/Sysdyn-1.1/Validations/Expressions/expressionValidator"; + public static final String Validations_Functions = "http://www.simantics.org/Sysdyn-1.1/Validations/Functions"; + public static final String Validations_Functions_baseRealizationFunction = "http://www.simantics.org/Sysdyn-1.1/Validations/Functions/baseRealizationFunction"; + public static final String Validations_Functions_path = "http://www.simantics.org/Sysdyn-1.1/Validations/Functions/path"; + public static final String Validations_InvalidSheetReferenceIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/InvalidSheetReferenceIssue"; + public static final String Validations_Issue = "http://www.simantics.org/Sysdyn-1.1/Validations/Issue"; + public static final String Validations_Issue_stringContexts = "http://www.simantics.org/Sysdyn-1.1/Validations/Issue/stringContexts"; + public static final String Validations_Issue_stringContexts_Inverse = "http://www.simantics.org/Sysdyn-1.1/Validations/Issue/stringContexts/Inverse"; + public static final String Validations_MissingDependencyConstraint = "http://www.simantics.org/Sysdyn-1.1/Validations/MissingDependencyConstraint"; + public static final String Validations_MissingLinkIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/MissingLinkIssue"; + public static final String Validations_ModuleInputUnitWarning = "http://www.simantics.org/Sysdyn-1.1/Validations/ModuleInputUnitWarning"; + public static final String Validations_ModuleOutputUnitWarning = "http://www.simantics.org/Sysdyn-1.1/Validations/ModuleOutputUnitWarning"; + public static final String Validations_NoSuchVariableIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/NoSuchVariableIssue"; + public static final String Validations_RangeIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/RangeIssue"; + public static final String Validations_RangeWarning = "http://www.simantics.org/Sysdyn-1.1/Validations/RangeWarning"; + public static final String Validations_UnitConstraint = "http://www.simantics.org/Sysdyn-1.1/Validations/UnitConstraint"; + public static final String Validations_UnitWarning = "http://www.simantics.org/Sysdyn-1.1/Validations/UnitWarning"; + public static final String Validations_Units = "http://www.simantics.org/Sysdyn-1.1/Validations/Units"; + public static final String Validations_Units_UnitIssueSource = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/UnitIssueSource"; + public static final String Validations_Units_UnitIssueSource_allowEquivalents = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/UnitIssueSource/allowEquivalents"; + public static final String Validations_Units_UnitIssueSource_allowEquivalents_Inverse = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/UnitIssueSource/allowEquivalents/Inverse"; + public static final String Validations_Units_moduleInputUnitWarningDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/moduleInputUnitWarningDescription"; + public static final String Validations_Units_moduleInterfaceExtension = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/moduleInterfaceExtension"; + public static final String Validations_Units_moduleOutputUnitWarningDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/moduleOutputUnitWarningDescription"; + public static final String Validations_Units_unitValidator = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/unitValidator"; + public static final String Validations_Units_unitWarningDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/unitWarningDescription"; + public static final String Validations_UnusedDependencyIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/UnusedDependencyIssue"; + public static final String Validations_constraint = "http://www.simantics.org/Sysdyn-1.1/Validations/constraint"; + public static final String Validations_issue = "http://www.simantics.org/Sysdyn-1.1/Validations/issue"; + public static final String Validations_listeningConstraint = "http://www.simantics.org/Sysdyn-1.1/Validations/listeningConstraint"; + public static final String ValueGeneratorMethod = "http://www.simantics.org/Sysdyn-1.1/ValueGeneratorMethod"; + public static final String Valve = "http://www.simantics.org/Sysdyn-1.1/Valve"; + public static final String ValveSymbol = "http://www.simantics.org/Sysdyn-1.1/ValveSymbol"; + public static final String ValveSymbol_orientation = "http://www.simantics.org/Sysdyn-1.1/ValveSymbol/orientation"; + public static final String ValveSymbol_textLocation = "http://www.simantics.org/Sysdyn-1.1/ValveSymbol/textLocation"; + public static final String Variable = "http://www.simantics.org/Sysdyn-1.1/Variable"; + public static final String Variable_HasHead = "http://www.simantics.org/Sysdyn-1.1/Variable/HasHead"; + public static final String Variable_HasTail = "http://www.simantics.org/Sysdyn-1.1/Variable/HasTail"; + public static final String Variable_activeDatasets = "http://www.simantics.org/Sysdyn-1.1/Variable/activeDatasets"; + public static final String Variable_activeDatasets_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/activeDatasets/Inverse"; + public static final String Variable_arrayIndexes = "http://www.simantics.org/Sysdyn-1.1/Variable/arrayIndexes"; + public static final String Variable_arrayIndexesList = "http://www.simantics.org/Sysdyn-1.1/Variable/arrayIndexesList"; + public static final String Variable_arrayIndexesList_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/arrayIndexesList/Inverse"; + public static final String Variable_arrayIndexes_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/arrayIndexes/Inverse"; + public static final String Variable_expressionList = "http://www.simantics.org/Sysdyn-1.1/Variable/expressionList"; + public static final String Variable_expressionList_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/expressionList/Inverse"; + public static final String Variable_expressions = "http://www.simantics.org/Sysdyn-1.1/Variable/expressions"; + public static final String Variable_expressions_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/expressions/Inverse"; + public static final String Variable_isHeadOf = "http://www.simantics.org/Sysdyn-1.1/Variable/isHeadOf"; + public static final String Variable_isTailOf = "http://www.simantics.org/Sysdyn-1.1/Variable/isTailOf"; + public static final String Variable_names = "http://www.simantics.org/Sysdyn-1.1/Variable/names"; + public static final String Variable_names_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/names/Inverse"; + public static final String Variable_time = "http://www.simantics.org/Sysdyn-1.1/Variable/time"; + public static final String Variable_time_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/time/Inverse"; + public static final String Variable_times = "http://www.simantics.org/Sysdyn-1.1/Variable/times"; + public static final String Variable_times_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/times/Inverse"; + public static final String Variable_type = "http://www.simantics.org/Sysdyn-1.1/Variable/type"; + public static final String Variable_type_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/type/Inverse"; + public static final String Variable_unit = "http://www.simantics.org/Sysdyn-1.1/Variable/unit"; + public static final String Variable_unit_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/unit/Inverse"; + public static final String Variable_value = "http://www.simantics.org/Sysdyn-1.1/Variable/value"; + public static final String Variable_value_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/value/Inverse"; + public static final String Variable_values = "http://www.simantics.org/Sysdyn-1.1/Variable/values"; + public static final String Variable_values_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/values/Inverse"; + public static final String Variable_variability = "http://www.simantics.org/Sysdyn-1.1/Variable/variability"; + public static final String Variable_variability_Inverse = "http://www.simantics.org/Sysdyn-1.1/Variable/variability/Inverse"; + public static final String Vertical = "http://www.simantics.org/Sysdyn-1.1/Vertical"; + public static final String WithLookupExpression = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression"; + public static final String WithLookupExpression_expression = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression/expression"; + public static final String WithLookupExpression_expression_Inverse = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression/expression/Inverse"; + public static final String WithLookupExpression_lookup = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression/lookup"; + public static final String WithLookupExpression_lookup_Inverse = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression/lookup/Inverse"; + public static final String WithLookupExpression_maxX = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression/maxX"; + public static final String WithLookupExpression_maxY = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression/maxY"; + public static final String WithLookupExpression_minX = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression/minX"; + public static final String WithLookupExpression_minY = "http://www.simantics.org/Sysdyn-1.1/WithLookupExpression/minY"; + } + + public static Resource getResourceOrNull(ReadGraph graph, String uri) { + try { + return graph.getResource(uri); + } catch(DatabaseException e) { + System.err.println(e.getMessage()); + return null; + } + } + + public SysdynResource(ReadGraph graph) { + AdditionalSymbols = getResourceOrNull(graph, URIs.AdditionalSymbols); + AdditionalSymbols_MultilineText = getResourceOrNull(graph, URIs.AdditionalSymbols_MultilineText); + AllElementsGroup = getResourceOrNull(graph, URIs.AllElementsGroup); + ArrayIndexes = getResourceOrNull(graph, URIs.ArrayIndexes); + ArrayIndexes_Inverse = getResourceOrNull(graph, URIs.ArrayIndexes_Inverse); + Auxiliary = getResourceOrNull(graph, URIs.Auxiliary); + AuxiliarySymbol = getResourceOrNull(graph, URIs.AuxiliarySymbol); + AvailableSharedFunctionLibraries = getResourceOrNull(graph, URIs.AvailableSharedFunctionLibraries); + AvailableVariableIndexes = getResourceOrNull(graph, URIs.AvailableVariableIndexes); + BasicExperiment = getResourceOrNull(graph, URIs.BasicExperiment); + Bottom = getResourceOrNull(graph, URIs.Bottom); + Browser = getResourceOrNull(graph, URIs.Browser); + Built$in_Functions = getResourceOrNull(graph, URIs.Built$in_Functions); + Built$in_Functions_Modelica_Array_Functions = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions); + Built$in_Functions_Modelica_Array_Functions_array = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_array); + Built$in_Functions_Modelica_Array_Functions_array_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_array_A); + Built$in_Functions_Modelica_Array_Functions_array_A_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_array_A_A); + Built$in_Functions_Modelica_Array_Functions_array_A_B = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_array_A_B); + Built$in_Functions_Modelica_Array_Functions_array_A_C = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_array_A_C); + Built$in_Functions_Modelica_Array_Functions_array_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_array_result); + Built$in_Functions_Modelica_Array_Functions_cat = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cat); + Built$in_Functions_Modelica_Array_Functions_cat_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cat_A); + Built$in_Functions_Modelica_Array_Functions_cat_A_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cat_A_A); + Built$in_Functions_Modelica_Array_Functions_cat_A_B = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cat_A_B); + Built$in_Functions_Modelica_Array_Functions_cat_A_C = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cat_A_C); + Built$in_Functions_Modelica_Array_Functions_cat_k = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cat_k); + Built$in_Functions_Modelica_Array_Functions_cat_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cat_result); + Built$in_Functions_Modelica_Array_Functions_cross = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cross); + Built$in_Functions_Modelica_Array_Functions_cross_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cross_result); + Built$in_Functions_Modelica_Array_Functions_cross_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cross_x); + Built$in_Functions_Modelica_Array_Functions_cross_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_cross_y); + Built$in_Functions_Modelica_Array_Functions_diagonal = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_diagonal); + Built$in_Functions_Modelica_Array_Functions_diagonal_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_diagonal_result); + Built$in_Functions_Modelica_Array_Functions_diagonal_v = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_diagonal_v); + Built$in_Functions_Modelica_Array_Functions_fill = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_fill); + Built$in_Functions_Modelica_Array_Functions_fill_n = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_fill_n); + Built$in_Functions_Modelica_Array_Functions_fill_n_n1 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_fill_n_n1); + Built$in_Functions_Modelica_Array_Functions_fill_n_n2 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_fill_n_n2); + Built$in_Functions_Modelica_Array_Functions_fill_n_n3 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_fill_n_n3); + Built$in_Functions_Modelica_Array_Functions_fill_o = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_fill_o); + Built$in_Functions_Modelica_Array_Functions_fill_s = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_fill_s); + Built$in_Functions_Modelica_Array_Functions_identity = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_identity); + Built$in_Functions_Modelica_Array_Functions_identity_n = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_identity_n); + Built$in_Functions_Modelica_Array_Functions_identity_outArray = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_identity_outArray); + Built$in_Functions_Modelica_Array_Functions_linspace = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_linspace); + Built$in_Functions_Modelica_Array_Functions_linspace_n = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_linspace_n); + Built$in_Functions_Modelica_Array_Functions_linspace_v = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_linspace_v); + Built$in_Functions_Modelica_Array_Functions_linspace_x1 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_linspace_x1); + Built$in_Functions_Modelica_Array_Functions_linspace_x2 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_linspace_x2); + Built$in_Functions_Modelica_Array_Functions_matrix = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_matrix); + Built$in_Functions_Modelica_Array_Functions_matrix_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_matrix_A); + Built$in_Functions_Modelica_Array_Functions_matrix_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_matrix_result); + Built$in_Functions_Modelica_Array_Functions_max = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_max); + Built$in_Functions_Modelica_Array_Functions_max_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_max_A); + Built$in_Functions_Modelica_Array_Functions_max_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_max_result); + Built$in_Functions_Modelica_Array_Functions_min = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_min); + Built$in_Functions_Modelica_Array_Functions_min_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_min_A); + Built$in_Functions_Modelica_Array_Functions_min_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_min_result); + Built$in_Functions_Modelica_Array_Functions_ndims = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_ndims); + Built$in_Functions_Modelica_Array_Functions_ndims_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_ndims_A); + Built$in_Functions_Modelica_Array_Functions_ndims_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_ndims_result); + Built$in_Functions_Modelica_Array_Functions_ones = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_ones); + Built$in_Functions_Modelica_Array_Functions_ones_n = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_ones_n); + Built$in_Functions_Modelica_Array_Functions_ones_n_n1 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_ones_n_n1); + Built$in_Functions_Modelica_Array_Functions_ones_n_n2 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_ones_n_n2); + Built$in_Functions_Modelica_Array_Functions_ones_n_n3 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_ones_n_n3); + Built$in_Functions_Modelica_Array_Functions_ones_o = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_ones_o); + Built$in_Functions_Modelica_Array_Functions_product = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_product); + Built$in_Functions_Modelica_Array_Functions_product_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_product_A); + Built$in_Functions_Modelica_Array_Functions_product_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_product_result); + Built$in_Functions_Modelica_Array_Functions_scalar = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_scalar); + Built$in_Functions_Modelica_Array_Functions_scalar_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_scalar_A); + Built$in_Functions_Modelica_Array_Functions_scalar_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_scalar_result); + Built$in_Functions_Modelica_Array_Functions_size = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_size); + Built$in_Functions_Modelica_Array_Functions_size_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_size_A); + Built$in_Functions_Modelica_Array_Functions_size_i = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_size_i); + Built$in_Functions_Modelica_Array_Functions_size_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_size_result); + Built$in_Functions_Modelica_Array_Functions_skew = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_skew); + Built$in_Functions_Modelica_Array_Functions_skew_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_skew_result); + Built$in_Functions_Modelica_Array_Functions_skew_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_skew_x); + Built$in_Functions_Modelica_Array_Functions_sum = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_sum); + Built$in_Functions_Modelica_Array_Functions_sum_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_sum_A); + Built$in_Functions_Modelica_Array_Functions_sum_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_sum_result); + Built$in_Functions_Modelica_Array_Functions_transpose = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_transpose); + Built$in_Functions_Modelica_Array_Functions_transpose_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_transpose_A); + Built$in_Functions_Modelica_Array_Functions_transpose_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_transpose_result); + Built$in_Functions_Modelica_Array_Functions_vector = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_vector); + Built$in_Functions_Modelica_Array_Functions_vector_A = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_vector_A); + Built$in_Functions_Modelica_Array_Functions_vector_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_vector_result); + Built$in_Functions_Modelica_Array_Functions_zeros = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_zeros); + Built$in_Functions_Modelica_Array_Functions_zeros_n = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_zeros_n); + Built$in_Functions_Modelica_Array_Functions_zeros_n_n1 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_zeros_n_n1); + Built$in_Functions_Modelica_Array_Functions_zeros_n_n2 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_zeros_n_n2); + Built$in_Functions_Modelica_Array_Functions_zeros_n_n3 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_zeros_n_n3); + Built$in_Functions_Modelica_Array_Functions_zeros_o = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Array_Functions_zeros_o); + Built$in_Functions_Modelica_Functions = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions); + Built$in_Functions_Modelica_Functions_abs = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_abs); + Built$in_Functions_Modelica_Functions_abs_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_abs_result); + Built$in_Functions_Modelica_Functions_abs_v = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_abs_v); + Built$in_Functions_Modelica_Functions_acos = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_acos); + Built$in_Functions_Modelica_Functions_acos_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_acos_u); + Built$in_Functions_Modelica_Functions_acos_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_acos_y); + Built$in_Functions_Modelica_Functions_asin = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_asin); + Built$in_Functions_Modelica_Functions_asin_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_asin_u); + Built$in_Functions_Modelica_Functions_asin_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_asin_y); + Built$in_Functions_Modelica_Functions_atan = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_atan); + Built$in_Functions_Modelica_Functions_atan2 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_atan2); + Built$in_Functions_Modelica_Functions_atan2_u1 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_atan2_u1); + Built$in_Functions_Modelica_Functions_atan2_u2 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_atan2_u2); + Built$in_Functions_Modelica_Functions_atan2_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_atan2_y); + Built$in_Functions_Modelica_Functions_atan_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_atan_u); + Built$in_Functions_Modelica_Functions_atan_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_atan_y); + Built$in_Functions_Modelica_Functions_ceil = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_ceil); + Built$in_Functions_Modelica_Functions_ceil_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_ceil_x); + Built$in_Functions_Modelica_Functions_ceil_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_ceil_y); + Built$in_Functions_Modelica_Functions_cos = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_cos); + Built$in_Functions_Modelica_Functions_cos_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_cos_u); + Built$in_Functions_Modelica_Functions_cos_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_cos_y); + Built$in_Functions_Modelica_Functions_cosh = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_cosh); + Built$in_Functions_Modelica_Functions_cosh_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_cosh_u); + Built$in_Functions_Modelica_Functions_cosh_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_cosh_y); + Built$in_Functions_Modelica_Functions_delay = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_delay); + Built$in_Functions_Modelica_Functions_delay_delayMax = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_delay_delayMax); + Built$in_Functions_Modelica_Functions_delay_delayTime = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_delay_delayTime); + Built$in_Functions_Modelica_Functions_delay_expr = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_delay_expr); + Built$in_Functions_Modelica_Functions_delay_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_delay_result); + Built$in_Functions_Modelica_Functions_der = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_der); + Built$in_Functions_Modelica_Functions_der_dexpr = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_der_dexpr); + Built$in_Functions_Modelica_Functions_der_expr = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_der_expr); + Built$in_Functions_Modelica_Functions_div = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_div); + Built$in_Functions_Modelica_Functions_div_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_div_result); + Built$in_Functions_Modelica_Functions_div_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_div_x); + Built$in_Functions_Modelica_Functions_div_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_div_y); + Built$in_Functions_Modelica_Functions_edge = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_edge); + Built$in_Functions_Modelica_Functions_edge_b = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_edge_b); + Built$in_Functions_Modelica_Functions_edge_edgeEvent = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_edge_edgeEvent); + Built$in_Functions_Modelica_Functions_exp = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_exp); + Built$in_Functions_Modelica_Functions_exp_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_exp_u); + Built$in_Functions_Modelica_Functions_exp_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_exp_y); + Built$in_Functions_Modelica_Functions_floor = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_floor); + Built$in_Functions_Modelica_Functions_floor_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_floor_x); + Built$in_Functions_Modelica_Functions_floor_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_floor_y); + Built$in_Functions_Modelica_Functions_initial = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_initial); + Built$in_Functions_Modelica_Functions_initial_isInitial = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_initial_isInitial); + Built$in_Functions_Modelica_Functions_log = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_log); + Built$in_Functions_Modelica_Functions_log10 = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_log10); + Built$in_Functions_Modelica_Functions_log10_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_log10_u); + Built$in_Functions_Modelica_Functions_log10_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_log10_y); + Built$in_Functions_Modelica_Functions_log_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_log_u); + Built$in_Functions_Modelica_Functions_log_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_log_y); + Built$in_Functions_Modelica_Functions_max = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_max); + Built$in_Functions_Modelica_Functions_max_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_max_result); + Built$in_Functions_Modelica_Functions_max_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_max_x); + Built$in_Functions_Modelica_Functions_max_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_max_y); + Built$in_Functions_Modelica_Functions_min = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_min); + Built$in_Functions_Modelica_Functions_min_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_min_result); + Built$in_Functions_Modelica_Functions_min_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_min_x); + Built$in_Functions_Modelica_Functions_min_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_min_y); + Built$in_Functions_Modelica_Functions_mod = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_mod); + Built$in_Functions_Modelica_Functions_mod_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_mod_result); + Built$in_Functions_Modelica_Functions_mod_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_mod_x); + Built$in_Functions_Modelica_Functions_mod_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_mod_y); + Built$in_Functions_Modelica_Functions_noEvent = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_noEvent); + Built$in_Functions_Modelica_Functions_noEvent_expr = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_noEvent_expr); + Built$in_Functions_Modelica_Functions_noEvent_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_noEvent_result); + Built$in_Functions_Modelica_Functions_pre = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_pre); + Built$in_Functions_Modelica_Functions_pre_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_pre_result); + Built$in_Functions_Modelica_Functions_pre_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_pre_y); + Built$in_Functions_Modelica_Functions_rem = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_rem); + Built$in_Functions_Modelica_Functions_rem_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_rem_result); + Built$in_Functions_Modelica_Functions_rem_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_rem_x); + Built$in_Functions_Modelica_Functions_rem_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_rem_y); + Built$in_Functions_Modelica_Functions_sample = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sample); + Built$in_Functions_Modelica_Functions_sample_interval = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sample_interval); + Built$in_Functions_Modelica_Functions_sample_isSample = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sample_isSample); + Built$in_Functions_Modelica_Functions_sample_start = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sample_start); + Built$in_Functions_Modelica_Functions_semiLinear = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_semiLinear); + Built$in_Functions_Modelica_Functions_semiLinear_negativeSlope = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_semiLinear_negativeSlope); + Built$in_Functions_Modelica_Functions_semiLinear_positiveSlope = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_semiLinear_positiveSlope); + Built$in_Functions_Modelica_Functions_semiLinear_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_semiLinear_result); + Built$in_Functions_Modelica_Functions_semiLinear_x = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_semiLinear_x); + Built$in_Functions_Modelica_Functions_sign = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sign); + Built$in_Functions_Modelica_Functions_sign_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sign_result); + Built$in_Functions_Modelica_Functions_sign_v = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sign_v); + Built$in_Functions_Modelica_Functions_sin = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sin); + Built$in_Functions_Modelica_Functions_sin_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sin_u); + Built$in_Functions_Modelica_Functions_sin_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sin_y); + Built$in_Functions_Modelica_Functions_sinh = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sinh); + Built$in_Functions_Modelica_Functions_sinh_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sinh_u); + Built$in_Functions_Modelica_Functions_sinh_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sinh_y); + Built$in_Functions_Modelica_Functions_smooth = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_smooth); + Built$in_Functions_Modelica_Functions_smooth_expr = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_smooth_expr); + Built$in_Functions_Modelica_Functions_smooth_p = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_smooth_p); + Built$in_Functions_Modelica_Functions_smooth_result = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_smooth_result); + Built$in_Functions_Modelica_Functions_sqrt = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sqrt); + Built$in_Functions_Modelica_Functions_sqrt_v = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sqrt_v); + Built$in_Functions_Modelica_Functions_sqrt_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_sqrt_y); + Built$in_Functions_Modelica_Functions_tan = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_tan); + Built$in_Functions_Modelica_Functions_tan_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_tan_u); + Built$in_Functions_Modelica_Functions_tan_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_tan_y); + Built$in_Functions_Modelica_Functions_tanh = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_tanh); + Built$in_Functions_Modelica_Functions_tanh_u = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_tanh_u); + Built$in_Functions_Modelica_Functions_tanh_y = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_tanh_y); + Built$in_Functions_Modelica_Functions_terminal = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_terminal); + Built$in_Functions_Modelica_Functions_terminal_isTerminal = getResourceOrNull(graph, URIs.Built$in_Functions_Modelica_Functions_terminal_isTerminal); + Built$in_Functions_Vensim_Functions = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions); + Built$in_Functions_Vensim_Functions_ABS = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_ABS); + Built$in_Functions_Vensim_Functions_ABS_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_ABS_x); + Built$in_Functions_Vensim_Functions_ABS_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_ABS_z); + Built$in_Functions_Vensim_Functions_COS = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_COS); + Built$in_Functions_Vensim_Functions_COSH = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_COSH); + Built$in_Functions_Vensim_Functions_COSH_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_COSH_x); + Built$in_Functions_Vensim_Functions_COSH_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_COSH_z); + Built$in_Functions_Vensim_Functions_COS_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_COS_x); + Built$in_Functions_Vensim_Functions_COS_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_COS_z); + Built$in_Functions_Vensim_Functions_EXP = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_EXP); + Built$in_Functions_Vensim_Functions_EXP_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_EXP_x); + Built$in_Functions_Vensim_Functions_EXP_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_EXP_z); + Built$in_Functions_Vensim_Functions_IFTHENELSE = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_IFTHENELSE); + Built$in_Functions_Vensim_Functions_IFTHENELSE_cond = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_IFTHENELSE_cond); + Built$in_Functions_Vensim_Functions_IFTHENELSE_onfalse = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_IFTHENELSE_onfalse); + Built$in_Functions_Vensim_Functions_IFTHENELSE_ontrue = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_IFTHENELSE_ontrue); + Built$in_Functions_Vensim_Functions_IFTHENELSE_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_IFTHENELSE_z); + Built$in_Functions_Vensim_Functions_LN = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_LN); + Built$in_Functions_Vensim_Functions_LN_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_LN_x); + Built$in_Functions_Vensim_Functions_LN_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_LN_z); + Built$in_Functions_Vensim_Functions_MAX = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MAX); + Built$in_Functions_Vensim_Functions_MAX_a = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MAX_a); + Built$in_Functions_Vensim_Functions_MAX_b = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MAX_b); + Built$in_Functions_Vensim_Functions_MAX_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MAX_z); + Built$in_Functions_Vensim_Functions_MIN = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MIN); + Built$in_Functions_Vensim_Functions_MIN_a = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MIN_a); + Built$in_Functions_Vensim_Functions_MIN_b = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MIN_b); + Built$in_Functions_Vensim_Functions_MIN_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MIN_z); + Built$in_Functions_Vensim_Functions_MODULO = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MODULO); + Built$in_Functions_Vensim_Functions_MODULO_a = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MODULO_a); + Built$in_Functions_Vensim_Functions_MODULO_b = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MODULO_b); + Built$in_Functions_Vensim_Functions_MODULO_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_MODULO_z); + Built$in_Functions_Vensim_Functions_PULSE = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_PULSE); + Built$in_Functions_Vensim_Functions_PULSE_start = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_PULSE_start); + Built$in_Functions_Vensim_Functions_PULSE_width = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_PULSE_width); + Built$in_Functions_Vensim_Functions_PULSE_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_PULSE_z); + Built$in_Functions_Vensim_Functions_RAMP = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_RAMP); + Built$in_Functions_Vensim_Functions_RAMP_endTime = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_RAMP_endTime); + Built$in_Functions_Vensim_Functions_RAMP_slope = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_RAMP_slope); + Built$in_Functions_Vensim_Functions_RAMP_startTime = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_RAMP_startTime); + Built$in_Functions_Vensim_Functions_RAMP_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_RAMP_z); + Built$in_Functions_Vensim_Functions_SIN = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_SIN); + Built$in_Functions_Vensim_Functions_SINH = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_SINH); + Built$in_Functions_Vensim_Functions_SINH_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_SINH_x); + Built$in_Functions_Vensim_Functions_SINH_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_SINH_z); + Built$in_Functions_Vensim_Functions_SIN_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_SIN_x); + Built$in_Functions_Vensim_Functions_SIN_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_SIN_z); + Built$in_Functions_Vensim_Functions_SQRT = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_SQRT); + Built$in_Functions_Vensim_Functions_SQRT_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_SQRT_x); + Built$in_Functions_Vensim_Functions_SQRT_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_SQRT_z); + Built$in_Functions_Vensim_Functions_STEP = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_STEP); + Built$in_Functions_Vensim_Functions_STEP_height = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_STEP_height); + Built$in_Functions_Vensim_Functions_STEP_stepTime = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_STEP_stepTime); + Built$in_Functions_Vensim_Functions_STEP_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_STEP_z); + Built$in_Functions_Vensim_Functions_TAN = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_TAN); + Built$in_Functions_Vensim_Functions_TANH = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_TANH); + Built$in_Functions_Vensim_Functions_TANH_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_TANH_x); + Built$in_Functions_Vensim_Functions_TANH_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_TANH_z); + Built$in_Functions_Vensim_Functions_TAN_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_TAN_x); + Built$in_Functions_Vensim_Functions_TAN_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_TAN_z); + Built$in_Functions_Vensim_Functions_XIDZ = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_XIDZ); + Built$in_Functions_Vensim_Functions_XIDZ_a = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_XIDZ_a); + Built$in_Functions_Vensim_Functions_XIDZ_b = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_XIDZ_b); + Built$in_Functions_Vensim_Functions_XIDZ_x = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_XIDZ_x); + Built$in_Functions_Vensim_Functions_XIDZ_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_XIDZ_z); + Built$in_Functions_Vensim_Functions_ZIDZ = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_ZIDZ); + Built$in_Functions_Vensim_Functions_ZIDZ_a = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_ZIDZ_a); + Built$in_Functions_Vensim_Functions_ZIDZ_b = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_ZIDZ_b); + Built$in_Functions_Vensim_Functions_ZIDZ_z = getResourceOrNull(graph, URIs.Built$in_Functions_Vensim_Functions_ZIDZ_z); + Built$in_Functions_interpolate = getResourceOrNull(graph, URIs.Built$in_Functions_interpolate); + Built$in_Functions_interpolateFull = getResourceOrNull(graph, URIs.Built$in_Functions_interpolateFull); + Built$in_Functions_interpolateFull_icol = getResourceOrNull(graph, URIs.Built$in_Functions_interpolateFull_icol); + Built$in_Functions_interpolateFull_table = getResourceOrNull(graph, URIs.Built$in_Functions_interpolateFull_table); + Built$in_Functions_interpolateFull_u = getResourceOrNull(graph, URIs.Built$in_Functions_interpolateFull_u); + Built$in_Functions_interpolateFull_y = getResourceOrNull(graph, URIs.Built$in_Functions_interpolateFull_y); + Built$in_Functions_interpolate_table = getResourceOrNull(graph, URIs.Built$in_Functions_interpolate_table); + Built$in_Functions_interpolate_u = getResourceOrNull(graph, URIs.Built$in_Functions_interpolate_u); + Built$in_Functions_interpolate_y = getResourceOrNull(graph, URIs.Built$in_Functions_interpolate_y); + Built$in_Functions_minmax = getResourceOrNull(graph, URIs.Built$in_Functions_minmax); + Built$in_Functions_minmax_expression = getResourceOrNull(graph, URIs.Built$in_Functions_minmax_expression); + Built$in_Functions_minmax_maximum = getResourceOrNull(graph, URIs.Built$in_Functions_minmax_maximum); + Built$in_Functions_minmax_minimum = getResourceOrNull(graph, URIs.Built$in_Functions_minmax_minimum); + Built$in_Functions_minmax_result = getResourceOrNull(graph, URIs.Built$in_Functions_minmax_result); + Built$in_Functions_xidz = getResourceOrNull(graph, URIs.Built$in_Functions_xidz); + Built$in_Functions_xidz_divident = getResourceOrNull(graph, URIs.Built$in_Functions_xidz_divident); + Built$in_Functions_xidz_divisor = getResourceOrNull(graph, URIs.Built$in_Functions_xidz_divisor); + Built$in_Functions_xidz_x = getResourceOrNull(graph, URIs.Built$in_Functions_xidz_x); + Built$in_Functions_xidz_z = getResourceOrNull(graph, URIs.Built$in_Functions_xidz_z); + Built$in_Functions_zidz = getResourceOrNull(graph, URIs.Built$in_Functions_zidz); + Built$in_Functions_zidz_divident = getResourceOrNull(graph, URIs.Built$in_Functions_zidz_divident); + Built$in_Functions_zidz_divisor = getResourceOrNull(graph, URIs.Built$in_Functions_zidz_divisor); + Built$in_Functions_zidz_z = getResourceOrNull(graph, URIs.Built$in_Functions_zidz_z); + Center = getResourceOrNull(graph, URIs.Center); + Charts = getResourceOrNull(graph, URIs.Charts); + Charts_SensitivityDataset = getResourceOrNull(graph, URIs.Charts_SensitivityDataset); + Charts_SensitivityDataset_ConfidenceBound = getResourceOrNull(graph, URIs.Charts_SensitivityDataset_ConfidenceBound); + Charts_SensitivityDataset_ConfidenceBound_color = getResourceOrNull(graph, URIs.Charts_SensitivityDataset_ConfidenceBound_color); + Charts_SensitivityDataset_ConfidenceBound_color_Inverse = getResourceOrNull(graph, URIs.Charts_SensitivityDataset_ConfidenceBound_color_Inverse); + Charts_SensitivityDataset_ConfidenceBound_percent = getResourceOrNull(graph, URIs.Charts_SensitivityDataset_ConfidenceBound_percent); + Charts_SensitivityDataset_ConfidenceBound_percent_Inverse = getResourceOrNull(graph, URIs.Charts_SensitivityDataset_ConfidenceBound_percent_Inverse); + Charts_SensitivityDataset_confidenceBounds = getResourceOrNull(graph, URIs.Charts_SensitivityDataset_confidenceBounds); + Charts_SensitivityDataset_confidenceBounds_Inverse = getResourceOrNull(graph, URIs.Charts_SensitivityDataset_confidenceBounds_Inverse); + Charts_SensitivityDataset_median = getResourceOrNull(graph, URIs.Charts_SensitivityDataset_median); + Charts_SensitivityDataset_median_Inverse = getResourceOrNull(graph, URIs.Charts_SensitivityDataset_median_Inverse); + Charts_SensitivityPlot = getResourceOrNull(graph, URIs.Charts_SensitivityPlot); + Cloud = getResourceOrNull(graph, URIs.Cloud); + CloudSymbol = getResourceOrNull(graph, URIs.CloudSymbol); + Component = getResourceOrNull(graph, URIs.Component); + Configuration = getResourceOrNull(graph, URIs.Configuration); + ConfigurationDiagram = getResourceOrNull(graph, URIs.ConfigurationDiagram); + ConfigurationDiagramTemplate = getResourceOrNull(graph, URIs.ConfigurationDiagramTemplate); + ConfigurationDiagram_selection = getResourceOrNull(graph, URIs.ConfigurationDiagram_selection); + ConfigurationDiagram_selection_Inverse = getResourceOrNull(graph, URIs.ConfigurationDiagram_selection_Inverse); + ConstantExpression = getResourceOrNull(graph, URIs.ConstantExpression); + DefaultFont = getResourceOrNull(graph, URIs.DefaultFont); + DefaultProfile = getResourceOrNull(graph, URIs.DefaultProfile); + DefaultRealization = getResourceOrNull(graph, URIs.DefaultRealization); + DelayExpression = getResourceOrNull(graph, URIs.DelayExpression); + DelayExpression_delayTime = getResourceOrNull(graph, URIs.DelayExpression_delayTime); + DelayExpression_delayTime_Inverse = getResourceOrNull(graph, URIs.DelayExpression_delayTime_Inverse); + DelayExpression_expression = getResourceOrNull(graph, URIs.DelayExpression_expression); + DelayExpression_expression_Inverse = getResourceOrNull(graph, URIs.DelayExpression_expression_Inverse); + DelayExpression_initialValue = getResourceOrNull(graph, URIs.DelayExpression_initialValue); + DelayExpression_initialValue_Inverse = getResourceOrNull(graph, URIs.DelayExpression_initialValue_Inverse); + DelayExpression_order = getResourceOrNull(graph, URIs.DelayExpression_order); + DelayExpression_order_Inverse = getResourceOrNull(graph, URIs.DelayExpression_order_Inverse); + Dependency = getResourceOrNull(graph, URIs.Dependency); + DependencyConnection = getResourceOrNull(graph, URIs.DependencyConnection); + DependencyConnection_delayMark = getResourceOrNull(graph, URIs.DependencyConnection_delayMark); + DependencyConnection_hideArrow = getResourceOrNull(graph, URIs.DependencyConnection_hideArrow); + DependencyConnection_polarity = getResourceOrNull(graph, URIs.DependencyConnection_polarity); + DependencyConnection_polarityLocation = getResourceOrNull(graph, URIs.DependencyConnection_polarityLocation); + DependencyConnection_polarityLocation_Inverse = getResourceOrNull(graph, URIs.DependencyConnection_polarityLocation_Inverse); + DependencyConnection_polarity_Inverse = getResourceOrNull(graph, URIs.DependencyConnection_polarity_Inverse); + DependencyConnection_strokeWidth = getResourceOrNull(graph, URIs.DependencyConnection_strokeWidth); + DependencyConnection_strokeWidth_Inverse = getResourceOrNull(graph, URIs.DependencyConnection_strokeWidth_Inverse); + Dependency_angle = getResourceOrNull(graph, URIs.Dependency_angle); + Dependency_angle_Inverse = getResourceOrNull(graph, URIs.Dependency_angle_Inverse); + Dependency_refersTo = getResourceOrNull(graph, URIs.Dependency_refersTo); + DiagramToCompositeMapping = getResourceOrNull(graph, URIs.DiagramToCompositeMapping); + Enumeration = getResourceOrNull(graph, URIs.Enumeration); + EnumerationIndex = getResourceOrNull(graph, URIs.EnumerationIndex); + EnumerationIndex_showEnumerationIndexInCharts = getResourceOrNull(graph, URIs.EnumerationIndex_showEnumerationIndexInCharts); + EnumerationIndex_showEnumerationIndexInCharts_Inverse = getResourceOrNull(graph, URIs.EnumerationIndex_showEnumerationIndexInCharts_Inverse); + EnumerationIndexes = getResourceOrNull(graph, URIs.EnumerationIndexes); + EnumerationIndexes_Inverse = getResourceOrNull(graph, URIs.EnumerationIndexes_Inverse); + EnumerationReplacement = getResourceOrNull(graph, URIs.EnumerationReplacement); + Enumeration_enumerationIndexList = getResourceOrNull(graph, URIs.Enumeration_enumerationIndexList); + Enumeration_enumerationIndexList_Inverse = getResourceOrNull(graph, URIs.Enumeration_enumerationIndexList_Inverse); + Enumeration_enumerationIndexes = getResourceOrNull(graph, URIs.Enumeration_enumerationIndexes); + Enumeration_enumerationIndexes_Inverse = getResourceOrNull(graph, URIs.Enumeration_enumerationIndexes_Inverse); + Enumeration_isReplaceable = getResourceOrNull(graph, URIs.Enumeration_isReplaceable); + Enumeration_isReplaceable_Inverse = getResourceOrNull(graph, URIs.Enumeration_isReplaceable_Inverse); + Experiment = getResourceOrNull(graph, URIs.Experiment); + Experiment_Run = getResourceOrNull(graph, URIs.Experiment_Run); + Experiment_Run_time = getResourceOrNull(graph, URIs.Experiment_Run_time); + Experiment_Run_time_Inverse = getResourceOrNull(graph, URIs.Experiment_Run_time_Inverse); + Experiment_result = getResourceOrNull(graph, URIs.Experiment_result); + Experiment_resultSet = getResourceOrNull(graph, URIs.Experiment_resultSet); + Experiment_resultSet_Inverse = getResourceOrNull(graph, URIs.Experiment_resultSet_Inverse); + Experiment_result_Inverse = getResourceOrNull(graph, URIs.Experiment_result_Inverse); + ExportModuleTree = getResourceOrNull(graph, URIs.ExportModuleTree); + Expression = getResourceOrNull(graph, URIs.Expression); + Expression_arrayRange = getResourceOrNull(graph, URIs.Expression_arrayRange); + Expression_arrayRange_Inverse = getResourceOrNull(graph, URIs.Expression_arrayRange_Inverse); + Expression_equation = getResourceOrNull(graph, URIs.Expression_equation); + Expression_equation_Inverse = getResourceOrNull(graph, URIs.Expression_equation_Inverse); + Expressions = getResourceOrNull(graph, URIs.Expressions); + Expressions_Inverse = getResourceOrNull(graph, URIs.Expressions_Inverse); + ExternalFiles = getResourceOrNull(graph, URIs.ExternalFiles); + ExternalFunctionFile = getResourceOrNull(graph, URIs.ExternalFunctionFile); + ExternalFunctionFile_externalFile = getResourceOrNull(graph, URIs.ExternalFunctionFile_externalFile); + ExternalFunctionFile_externalFile_Inverse = getResourceOrNull(graph, URIs.ExternalFunctionFile_externalFile_Inverse); + Flow = getResourceOrNull(graph, URIs.Flow); + FlowConnection = getResourceOrNull(graph, URIs.FlowConnection); + FlowConnection_width = getResourceOrNull(graph, URIs.FlowConnection_width); + FlowConnection_width_Inverse = getResourceOrNull(graph, URIs.FlowConnection_width_Inverse); + FunctionTree = getResourceOrNull(graph, URIs.FunctionTree); + Functions = getResourceOrNull(graph, URIs.Functions); + Functions_runChildren = getResourceOrNull(graph, URIs.Functions_runChildren); + Functions_runProperties = getResourceOrNull(graph, URIs.Functions_runProperties); + Functions_valuePropertyProperties = getResourceOrNull(graph, URIs.Functions_valuePropertyProperties); + Functions_valuePropertyValue = getResourceOrNull(graph, URIs.Functions_valuePropertyValue); + GameExperiment = getResourceOrNull(graph, URIs.GameExperiment); + GameExperiment_stepDuration = getResourceOrNull(graph, URIs.GameExperiment_stepDuration); + GameExperiment_stepDuration_Inverse = getResourceOrNull(graph, URIs.GameExperiment_stepDuration_Inverse); + GameExperiment_stepLength = getResourceOrNull(graph, URIs.GameExperiment_stepLength); + GameExperiment_stepLength_Inverse = getResourceOrNull(graph, URIs.GameExperiment_stepLength_Inverse); + HaltonSequenceGenerator = getResourceOrNull(graph, URIs.HaltonSequenceGenerator); + HasEquationOrEmpty = getResourceOrNull(graph, URIs.HasEquationOrEmpty); + HasEquationOrEmpty_Inverse = getResourceOrNull(graph, URIs.HasEquationOrEmpty_Inverse); + HasHeadTerminal = getResourceOrNull(graph, URIs.HasHeadTerminal); + HasRangeEnd = getResourceOrNull(graph, URIs.HasRangeEnd); + HasRangeEnd_Inverse = getResourceOrNull(graph, URIs.HasRangeEnd_Inverse); + HasRangeStart = getResourceOrNull(graph, URIs.HasRangeStart); + HasRangeStart_Inverse = getResourceOrNull(graph, URIs.HasRangeStart_Inverse); + HasRangeStep = getResourceOrNull(graph, URIs.HasRangeStep); + HasRangeStep_Inverse = getResourceOrNull(graph, URIs.HasRangeStep_Inverse); + HasTailTerminal = getResourceOrNull(graph, URIs.HasTailTerminal); + HistoryDataset = getResourceOrNull(graph, URIs.HistoryDataset); + HistoryDataset_FoundVariableNameNode = getResourceOrNull(graph, URIs.HistoryDataset_FoundVariableNameNode); + HistoryDataset_HistoryDatasetVariablesBrowseContext = getResourceOrNull(graph, URIs.HistoryDataset_HistoryDatasetVariablesBrowseContext); + HistoryDataset_HistoryDatasetVariablesBrowseContext_StringNodeType = getResourceOrNull(graph, URIs.HistoryDataset_HistoryDatasetVariablesBrowseContext_StringNodeType); + HistoryDataset_HistoryDatasetVariablesBrowseContext_VariableChildRule = getResourceOrNull(graph, URIs.HistoryDataset_HistoryDatasetVariablesBrowseContext_VariableChildRule); + HistoryDataset_HistoryDatasetVariablesBrowseContext_VariableLabelRule = getResourceOrNull(graph, URIs.HistoryDataset_HistoryDatasetVariablesBrowseContext_VariableLabelRule); + HistoryDataset_columns = getResourceOrNull(graph, URIs.HistoryDataset_columns); + HistoryDataset_columns_Inverse = getResourceOrNull(graph, URIs.HistoryDataset_columns_Inverse); + HistoryDataset_end = getResourceOrNull(graph, URIs.HistoryDataset_end); + HistoryDataset_end_Inverse = getResourceOrNull(graph, URIs.HistoryDataset_end_Inverse); + HistoryDataset_sheet = getResourceOrNull(graph, URIs.HistoryDataset_sheet); + HistoryDataset_start = getResourceOrNull(graph, URIs.HistoryDataset_start); + HistoryDataset_start_Inverse = getResourceOrNull(graph, URIs.HistoryDataset_start_Inverse); + HistoryDataset_timeName = getResourceOrNull(graph, URIs.HistoryDataset_timeName); + HistoryDataset_timeName_Inverse = getResourceOrNull(graph, URIs.HistoryDataset_timeName_Inverse); + HistoryRealization = getResourceOrNull(graph, URIs.HistoryRealization); + Horizontal = getResourceOrNull(graph, URIs.Horizontal); + ImportModuleTree = getResourceOrNull(graph, URIs.ImportModuleTree); + ImportedOntologies = getResourceOrNull(graph, URIs.ImportedOntologies); + IndependentVariable = getResourceOrNull(graph, URIs.IndependentVariable); + IndependentVariable_activeExpression = getResourceOrNull(graph, URIs.IndependentVariable_activeExpression); + IndependentVariable_isUninitialized = getResourceOrNull(graph, URIs.IndependentVariable_isUninitialized); + IndependentVariable_isUninitialized_Inverse = getResourceOrNull(graph, URIs.IndependentVariable_isUninitialized_Inverse); + IndependentVariable_rangeEnd = getResourceOrNull(graph, URIs.IndependentVariable_rangeEnd); + IndependentVariable_rangeEnd_Inverse = getResourceOrNull(graph, URIs.IndependentVariable_rangeEnd_Inverse); + IndependentVariable_rangeStart = getResourceOrNull(graph, URIs.IndependentVariable_rangeStart); + IndependentVariable_rangeStart_Inverse = getResourceOrNull(graph, URIs.IndependentVariable_rangeStart_Inverse); + IndependentVariable_rangeStep = getResourceOrNull(graph, URIs.IndependentVariable_rangeStep); + IndependentVariable_rangeStep_Inverse = getResourceOrNull(graph, URIs.IndependentVariable_rangeStep_Inverse); + IndependentVariable_unit = getResourceOrNull(graph, URIs.IndependentVariable_unit); + IndependentVariable_unit_Inverse = getResourceOrNull(graph, URIs.IndependentVariable_unit_Inverse); + Input = getResourceOrNull(graph, URIs.Input); + InputSymbol = getResourceOrNull(graph, URIs.InputSymbol); + Input_defaultInputValue = getResourceOrNull(graph, URIs.Input_defaultInputValue); + Input_defaultInputValue_Inverse = getResourceOrNull(graph, URIs.Input_defaultInputValue_Inverse); + Interval = getResourceOrNull(graph, URIs.Interval); + Interval_maxValue = getResourceOrNull(graph, URIs.Interval_maxValue); + Interval_maxValue_Inverse = getResourceOrNull(graph, URIs.Interval_maxValue_Inverse); + Interval_minValue = getResourceOrNull(graph, URIs.Interval_minValue); + Interval_minValue_Inverse = getResourceOrNull(graph, URIs.Interval_minValue_Inverse); + IsHeadOfTerminal = getResourceOrNull(graph, URIs.IsHeadOfTerminal); + IsOutput = getResourceOrNull(graph, URIs.IsOutput); + IsTailOfTerminal = getResourceOrNull(graph, URIs.IsTailOfTerminal); + IssueStyle = getResourceOrNull(graph, URIs.IssueStyle); + Left = getResourceOrNull(graph, URIs.Left); + Location = getResourceOrNull(graph, URIs.Location); + LookupExpression = getResourceOrNull(graph, URIs.LookupExpression); + LookupExpression_lookup = getResourceOrNull(graph, URIs.LookupExpression_lookup); + LookupExpression_lookup_Inverse = getResourceOrNull(graph, URIs.LookupExpression_lookup_Inverse); + Loop = getResourceOrNull(graph, URIs.Loop); + LoopSymbol = getResourceOrNull(graph, URIs.LoopSymbol); + LoopSymbol_Clockwise = getResourceOrNull(graph, URIs.LoopSymbol_Clockwise); + LoopSymbol_Clockwise_Inverse = getResourceOrNull(graph, URIs.LoopSymbol_Clockwise_Inverse); + Loop_Comment = getResourceOrNull(graph, URIs.Loop_Comment); + Loop_Comment_Inverse = getResourceOrNull(graph, URIs.Loop_Comment_Inverse); + Loop_Items = getResourceOrNull(graph, URIs.Loop_Items); + Loop_Items_Inverse = getResourceOrNull(graph, URIs.Loop_Items_Inverse); + Migration = getResourceOrNull(graph, URIs.Migration); + Migration_from1$6to1$7 = getResourceOrNull(graph, URIs.Migration_from1$6to1$7); + Migration_from1$6to1$7_Ontologies = getResourceOrNull(graph, URIs.Migration_from1$6to1$7_Ontologies); + Migration_from1$6to1$7_OrderedSetsToLists = getResourceOrNull(graph, URIs.Migration_from1$6to1$7_OrderedSetsToLists); + Migration_from1$6to1$7_Spreadsheets = getResourceOrNull(graph, URIs.Migration_from1$6to1$7_Spreadsheets); + Migration_from1$6to1$7_SysdynChanges = getResourceOrNull(graph, URIs.Migration_from1$6to1$7_SysdynChanges); + Migration_fromFunctionLibrary1 = getResourceOrNull(graph, URIs.Migration_fromFunctionLibrary1); + Migration_fromModel1 = getResourceOrNull(graph, URIs.Migration_fromModel1); + Migration_fromModule1 = getResourceOrNull(graph, URIs.Migration_fromModule1); + ModelBrowser = getResourceOrNull(graph, URIs.ModelBrowser); + ModelingActionContext = getResourceOrNull(graph, URIs.ModelingActionContext); + ModelingActionContext_Actions = getResourceOrNull(graph, URIs.ModelingActionContext_Actions); + ModelingActionContext_Actions_ChartDropAction = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_ChartDropAction); + ModelingActionContext_Actions_FunctionDropAction = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_FunctionDropAction); + ModelingActionContext_Actions_NewBarChart = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewBarChart); + ModelingActionContext_Actions_NewEnumeration = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewEnumeration); + ModelingActionContext_Actions_NewExperiment = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewExperiment); + ModelingActionContext_Actions_NewFunction = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewFunction); + ModelingActionContext_Actions_NewFunctionLibrary = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewFunctionLibrary); + ModelingActionContext_Actions_NewHistoryData = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewHistoryData); + ModelingActionContext_Actions_NewLineChart = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewLineChart); + ModelingActionContext_Actions_NewModuleType = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewModuleType); + ModelingActionContext_Actions_NewPieChart = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewPieChart); + ModelingActionContext_Actions_NewSharedFunctionLibrary = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewSharedFunctionLibrary); + ModelingActionContext_Actions_NewSheet = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewSheet); + ModelingActionContext_Actions_NewSimulationPlaybackExperiment = getResourceOrNull(graph, URIs.ModelingActionContext_Actions_NewSimulationPlaybackExperiment); + ModelingBrowseContext = getResourceOrNull(graph, URIs.ModelingBrowseContext); + ModelingBrowseContext_ActiveLabelDecorationRule = getResourceOrNull(graph, URIs.ModelingBrowseContext_ActiveLabelDecorationRule); + ModelingBrowseContext_BuiltinFunctions = getResourceOrNull(graph, URIs.ModelingBrowseContext_BuiltinFunctions); + ModelingBrowseContext_ChartImageRule = getResourceOrNull(graph, URIs.ModelingBrowseContext_ChartImageRule); + ModelingBrowseContext_ChartsFolder = getResourceOrNull(graph, URIs.ModelingBrowseContext_ChartsFolder); + ModelingBrowseContext_ExperimentsFolder = getResourceOrNull(graph, URIs.ModelingBrowseContext_ExperimentsFolder); + ModelingBrowseContext_FunctionsFolder = getResourceOrNull(graph, URIs.ModelingBrowseContext_FunctionsFolder); + ModelingBrowseContext_ModuleContentChildRule = getResourceOrNull(graph, URIs.ModelingBrowseContext_ModuleContentChildRule); + ModelingBrowseContext_ModuleSymbol = getResourceOrNull(graph, URIs.ModelingBrowseContext_ModuleSymbol); + ModelingBrowseContext_ModuleSymbolNodeType = getResourceOrNull(graph, URIs.ModelingBrowseContext_ModuleSymbolNodeType); + ModelingBrowseContext_ModuleTypeChildRule = getResourceOrNull(graph, URIs.ModelingBrowseContext_ModuleTypeChildRule); + ModelingBrowseContext_ModuleTypeLabelRule = getResourceOrNull(graph, URIs.ModelingBrowseContext_ModuleTypeLabelRule); + ModelingBrowseContext_ModulesFolder = getResourceOrNull(graph, URIs.ModelingBrowseContext_ModulesFolder); + ModelingBrowseContext_ResultImageRule = getResourceOrNull(graph, URIs.ModelingBrowseContext_ResultImageRule); + ModelingBrowseContext_SharedFunctionsFolder = getResourceOrNull(graph, URIs.ModelingBrowseContext_SharedFunctionsFolder); + ModelingBrowseContext_Variable = getResourceOrNull(graph, URIs.ModelingBrowseContext_Variable); + ModelingBrowseContext_VariableChildRule = getResourceOrNull(graph, URIs.ModelingBrowseContext_VariableChildRule); + ModelingBrowseContext_VariableImageRule = getResourceOrNull(graph, URIs.ModelingBrowseContext_VariableImageRule); + ModelingBrowseContext_VariableNameLabelRule = getResourceOrNull(graph, URIs.ModelingBrowseContext_VariableNameLabelRule); + ModelingBrowseContext_VariableNodeType = getResourceOrNull(graph, URIs.ModelingBrowseContext_VariableNodeType); + Module = getResourceOrNull(graph, URIs.Module); + ModuleSymbol = getResourceOrNull(graph, URIs.ModuleSymbol); + Module_ParameterOverride = getResourceOrNull(graph, URIs.Module_ParameterOverride); + Module_ParameterOverrideBrowseContext = getResourceOrNull(graph, URIs.Module_ParameterOverrideBrowseContext); + Module_ParameterOverrideBrowseContext_Node = getResourceOrNull(graph, URIs.Module_ParameterOverrideBrowseContext_Node); + Module_ParameterOverrideBrowseContext_NodeType = getResourceOrNull(graph, URIs.Module_ParameterOverrideBrowseContext_NodeType); + Module_ParameterOverrideBrowseContext_ParameterChildRule = getResourceOrNull(graph, URIs.Module_ParameterOverrideBrowseContext_ParameterChildRule); + Module_ParameterOverrideBrowseContext_ParameterLabelDecorationRule = getResourceOrNull(graph, URIs.Module_ParameterOverrideBrowseContext_ParameterLabelDecorationRule); + Module_ParameterOverrideBrowseContext_ParameterLabelRule = getResourceOrNull(graph, URIs.Module_ParameterOverrideBrowseContext_ParameterLabelRule); + Module_ParameterOverrideBrowseContext_ParameterModifierRule = getResourceOrNull(graph, URIs.Module_ParameterOverrideBrowseContext_ParameterModifierRule); + Module_ParameterOverrideBrowseContext_ParameterSorterRule = getResourceOrNull(graph, URIs.Module_ParameterOverrideBrowseContext_ParameterSorterRule); + Module_ParameterOverride_overriddenParameter = getResourceOrNull(graph, URIs.Module_ParameterOverride_overriddenParameter); + Module_ParameterOverride_overrideExpression = getResourceOrNull(graph, URIs.Module_ParameterOverride_overrideExpression); + Module_ParameterOverride_overrideExpression_Inverse = getResourceOrNull(graph, URIs.Module_ParameterOverride_overrideExpression_Inverse); + Module_parameterOverride = getResourceOrNull(graph, URIs.Module_parameterOverride); + Module_parameterOverride_Inverse = getResourceOrNull(graph, URIs.Module_parameterOverride_Inverse); + Module_redeclaration = getResourceOrNull(graph, URIs.Module_redeclaration); + Module_redeclaration_Inverse = getResourceOrNull(graph, URIs.Module_redeclaration_Inverse); + ModulesSearchFunction = getResourceOrNull(graph, URIs.ModulesSearchFunction); + NormalDistribution = getResourceOrNull(graph, URIs.NormalDistribution); + NormalDistribution_maxValue = getResourceOrNull(graph, URIs.NormalDistribution_maxValue); + NormalDistribution_maxValue_Inverse = getResourceOrNull(graph, URIs.NormalDistribution_maxValue_Inverse); + NormalDistribution_mean = getResourceOrNull(graph, URIs.NormalDistribution_mean); + NormalDistribution_mean_Inverse = getResourceOrNull(graph, URIs.NormalDistribution_mean_Inverse); + NormalDistribution_minValue = getResourceOrNull(graph, URIs.NormalDistribution_minValue); + NormalDistribution_minValue_Inverse = getResourceOrNull(graph, URIs.NormalDistribution_minValue_Inverse); + NormalDistribution_stdDeviation = getResourceOrNull(graph, URIs.NormalDistribution_stdDeviation); + NormalDistribution_stdDeviation_Inverse = getResourceOrNull(graph, URIs.NormalDistribution_stdDeviation_Inverse); + NormalExpression = getResourceOrNull(graph, URIs.NormalExpression); + Orientation = getResourceOrNull(graph, URIs.Orientation); + ParameterExpression = getResourceOrNull(graph, URIs.ParameterExpression); + PlaybackExperiment = getResourceOrNull(graph, URIs.PlaybackExperiment); + ProbabilityDistribution = getResourceOrNull(graph, URIs.ProbabilityDistribution); + Profiles = getResourceOrNull(graph, URIs.Profiles); + Profiles_IssueWarnings = getResourceOrNull(graph, URIs.Profiles_IssueWarnings); + Profiles_ShadowVisualizations = getResourceOrNull(graph, URIs.Profiles_ShadowVisualizations); + Profiles_SimulationPlaybackColours = getResourceOrNull(graph, URIs.Profiles_SimulationPlaybackColours); + RandomGenerator = getResourceOrNull(graph, URIs.RandomGenerator); + Redeclaration = getResourceOrNull(graph, URIs.Redeclaration); + Redeclaration_replacedEnumeration = getResourceOrNull(graph, URIs.Redeclaration_replacedEnumeration); + Redeclaration_replacedEnumeration_Inverse = getResourceOrNull(graph, URIs.Redeclaration_replacedEnumeration_Inverse); + Redeclaration_replacingEnumeration = getResourceOrNull(graph, URIs.Redeclaration_replacingEnumeration); + Redeclaration_replacingEnumeration_Inverse = getResourceOrNull(graph, URIs.Redeclaration_replacingEnumeration_Inverse); + Result = getResourceOrNull(graph, URIs.Result); + ResultSet = getResourceOrNull(graph, URIs.ResultSet); + Result_parameterFile = getResourceOrNull(graph, URIs.Result_parameterFile); + Result_parameterFile_Inverse = getResourceOrNull(graph, URIs.Result_parameterFile_Inverse); + Result_resultFile = getResourceOrNull(graph, URIs.Result_resultFile); + Result_resultFile_Inverse = getResourceOrNull(graph, URIs.Result_resultFile_Inverse); + Result_showResult = getResourceOrNull(graph, URIs.Result_showResult); + Result_time = getResourceOrNull(graph, URIs.Result_time); + Result_time_Inverse = getResourceOrNull(graph, URIs.Result_time_Inverse); + Right = getResourceOrNull(graph, URIs.Right); + SearchContribution = getResourceOrNull(graph, URIs.SearchContribution); + SelectedSharedFunctionLibraries = getResourceOrNull(graph, URIs.SelectedSharedFunctionLibraries); + SensitivityAnalysisExperiment = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment); + SensitivityAnalysisExperiment_Parameter = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter); + SensitivityAnalysisExperiment_ParameterActionContext = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_ParameterActionContext); + SensitivityAnalysisExperiment_ParameterActionContext_Actions = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_ParameterActionContext_Actions); + SensitivityAnalysisExperiment_ParameterBrowseContext = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_ParameterBrowseContext); + SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterChildRule = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterChildRule); + SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterLabelRule = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterLabelRule); + SensitivityAnalysisExperiment_Parameter_indexes = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_indexes); + SensitivityAnalysisExperiment_Parameter_indexes_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_indexes_Inverse); + SensitivityAnalysisExperiment_Parameter_propabilityDistribution = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_propabilityDistribution); + SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse); + SensitivityAnalysisExperiment_Parameter_variable = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_variable); + SensitivityAnalysisExperiment_Parameter_variable_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_variable_Inverse); + SensitivityAnalysisExperiment_method = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_method); + SensitivityAnalysisExperiment_method_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_method_Inverse); + SensitivityAnalysisExperiment_numberOfValues = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_numberOfValues); + SensitivityAnalysisExperiment_numberOfValues_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_numberOfValues_Inverse); + SensitivityAnalysisExperiment_parameterList = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_parameterList); + SensitivityAnalysisExperiment_parameterList_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_parameterList_Inverse); + SensitivityAnalysisExperiment_randomSeed = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_randomSeed); + SensitivityAnalysisExperiment_randomSeed_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_randomSeed_Inverse); + SensitivityAnalysisExperiment_resultRefreshRate = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_resultRefreshRate); + SensitivityAnalysisExperiment_resultRefreshRate_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_resultRefreshRate_Inverse); + Shadow = getResourceOrNull(graph, URIs.Shadow); + ShadowStyle = getResourceOrNull(graph, URIs.ShadowStyle); + ShadowSymbol = getResourceOrNull(graph, URIs.ShadowSymbol); + Shadow_original = getResourceOrNull(graph, URIs.Shadow_original); + Shadow_original_Inverse = getResourceOrNull(graph, URIs.Shadow_original_Inverse); + SharedFunctionOntology = getResourceOrNull(graph, URIs.SharedFunctionOntology); + SharedModuleOntology = getResourceOrNull(graph, URIs.SharedModuleOntology); + SimulateOnChangeExperiment = getResourceOrNull(graph, URIs.SimulateOnChangeExperiment); + SimulationPlaybackProfile = getResourceOrNull(graph, URIs.SimulationPlaybackProfile); + SimulationPlaybackStyle = getResourceOrNull(graph, URIs.SimulationPlaybackStyle); + Stock = getResourceOrNull(graph, URIs.Stock); + StockExpression = getResourceOrNull(graph, URIs.StockExpression); + StockExpression_initialEquation = getResourceOrNull(graph, URIs.StockExpression_initialEquation); + StockExpression_initialEquation_Inverse = getResourceOrNull(graph, URIs.StockExpression_initialEquation_Inverse); + StockExpression_integralEquation = getResourceOrNull(graph, URIs.StockExpression_integralEquation); + StockExpression_integralEquation_Inverse = getResourceOrNull(graph, URIs.StockExpression_integralEquation_Inverse); + StockExpression_useCustomIntegral = getResourceOrNull(graph, URIs.StockExpression_useCustomIntegral); + StockSymbol = getResourceOrNull(graph, URIs.StockSymbol); + SymbolReferences = getResourceOrNull(graph, URIs.SymbolReferences); + SymbolReferences_BasicSymbols = getResourceOrNull(graph, URIs.SymbolReferences_BasicSymbols); + SymbolReferences_CommentSymbols = getResourceOrNull(graph, URIs.SymbolReferences_CommentSymbols); + Symbols = getResourceOrNull(graph, URIs.Symbols); + SysdynConnectionType = getResourceOrNull(graph, URIs.SysdynConnectionType); + SysdynDiagramModelingRules = getResourceOrNull(graph, URIs.SysdynDiagramModelingRules); + SysdynModel = getResourceOrNull(graph, URIs.SysdynModel); + SysdynModel_fmuFile = getResourceOrNull(graph, URIs.SysdynModel_fmuFile); + SysdynModel_fmuFile_Inverse = getResourceOrNull(graph, URIs.SysdynModel_fmuFile_Inverse); + SysdynModel_lastExportFileName = getResourceOrNull(graph, URIs.SysdynModel_lastExportFileName); + SysdynModel_lastExportFileName_Inverse = getResourceOrNull(graph, URIs.SysdynModel_lastExportFileName_Inverse); + SysdynModel_lastExportFilePath = getResourceOrNull(graph, URIs.SysdynModel_lastExportFilePath); + SysdynModel_lastExportFilePath_Inverse = getResourceOrNull(graph, URIs.SysdynModel_lastExportFilePath_Inverse); + SysdynModel_outputInterval = getResourceOrNull(graph, URIs.SysdynModel_outputInterval); + SysdynModel_outputInterval_Inverse = getResourceOrNull(graph, URIs.SysdynModel_outputInterval_Inverse); + SysdynModel_simulationStepLength = getResourceOrNull(graph, URIs.SysdynModel_simulationStepLength); + SysdynModel_simulationStepLength_Inverse = getResourceOrNull(graph, URIs.SysdynModel_simulationStepLength_Inverse); + SysdynModel_solver = getResourceOrNull(graph, URIs.SysdynModel_solver); + SysdynModel_solver_Inverse = getResourceOrNull(graph, URIs.SysdynModel_solver_Inverse); + SysdynModel_startTime = getResourceOrNull(graph, URIs.SysdynModel_startTime); + SysdynModel_startTime_Inverse = getResourceOrNull(graph, URIs.SysdynModel_startTime_Inverse); + SysdynModel_stopTime = getResourceOrNull(graph, URIs.SysdynModel_stopTime); + SysdynModel_stopTime_Inverse = getResourceOrNull(graph, URIs.SysdynModel_stopTime_Inverse); + SysdynModel_timeUnit = getResourceOrNull(graph, URIs.SysdynModel_timeUnit); + SysdynModel_timeUnit_Inverse = getResourceOrNull(graph, URIs.SysdynModel_timeUnit_Inverse); + SysdynModel_tolerance = getResourceOrNull(graph, URIs.SysdynModel_tolerance); + SysdynModel_tolerance_Inverse = getResourceOrNull(graph, URIs.SysdynModel_tolerance_Inverse); + SysdynModel_variableFilter = getResourceOrNull(graph, URIs.SysdynModel_variableFilter); + SysdynModel_variableFilter_Inverse = getResourceOrNull(graph, URIs.SysdynModel_variableFilter_Inverse); + SysdynModelicaFunction = getResourceOrNull(graph, URIs.SysdynModelicaFunction); + SysdynModelicaFunctionLibrary = getResourceOrNull(graph, URIs.SysdynModelicaFunctionLibrary); + SysdynModelicaFunction_Input = getResourceOrNull(graph, URIs.SysdynModelicaFunction_Input); + SysdynModelicaFunction_InterfaceVariable = getResourceOrNull(graph, URIs.SysdynModelicaFunction_InterfaceVariable); + SysdynModelicaFunction_Output = getResourceOrNull(graph, URIs.SysdynModelicaFunction_Output); + SysdynModelicaFunction_VariableLengthInput = getResourceOrNull(graph, URIs.SysdynModelicaFunction_VariableLengthInput); + SysdynModelicaFunction_VariableLengthInput_shownLabels = getResourceOrNull(graph, URIs.SysdynModelicaFunction_VariableLengthInput_shownLabels); + SysdynModelicaFunction_VariableLengthInput_shownLabels_Inverse = getResourceOrNull(graph, URIs.SysdynModelicaFunction_VariableLengthInput_shownLabels_Inverse); + SysdynModelicaFunction_definition = getResourceOrNull(graph, URIs.SysdynModelicaFunction_definition); + SysdynModelicaFunction_definition_Inverse = getResourceOrNull(graph, URIs.SysdynModelicaFunction_definition_Inverse); + SysdynModelicaFunction_inputs = getResourceOrNull(graph, URIs.SysdynModelicaFunction_inputs); + SysdynModelicaFunction_inputs_Inverse = getResourceOrNull(graph, URIs.SysdynModelicaFunction_inputs_Inverse); + SysdynModelicaFunction_modelicaFunctionCode = getResourceOrNull(graph, URIs.SysdynModelicaFunction_modelicaFunctionCode); + SysdynModelicaFunction_modelicaFunctionCode_Inverse = getResourceOrNull(graph, URIs.SysdynModelicaFunction_modelicaFunctionCode_Inverse); + SysdynModelicaFunction_modelicaFunctionInterface = getResourceOrNull(graph, URIs.SysdynModelicaFunction_modelicaFunctionInterface); + SysdynModelicaFunction_modelicaFunctionInterface_Inverse = getResourceOrNull(graph, URIs.SysdynModelicaFunction_modelicaFunctionInterface_Inverse); + SysdynModelicaFunction_optional = getResourceOrNull(graph, URIs.SysdynModelicaFunction_optional); + SysdynModelicaFunction_optional_Inverse = getResourceOrNull(graph, URIs.SysdynModelicaFunction_optional_Inverse); + SysdynModelicaFunction_outputs = getResourceOrNull(graph, URIs.SysdynModelicaFunction_outputs); + SysdynModelicaFunction_outputs_Inverse = getResourceOrNull(graph, URIs.SysdynModelicaFunction_outputs_Inverse); + SysdynModelicaFunction_unit = getResourceOrNull(graph, URIs.SysdynModelicaFunction_unit); + SysdynModelicaFunction_unit_Inverse = getResourceOrNull(graph, URIs.SysdynModelicaFunction_unit_Inverse); + SysdynModuleLibrary = getResourceOrNull(graph, URIs.SysdynModuleLibrary); + SysdynOperationBrowser = getResourceOrNull(graph, URIs.SysdynOperationBrowser); + SysdynSymbol = getResourceOrNull(graph, URIs.SysdynSymbol); + SysdynTerminal = getResourceOrNull(graph, URIs.SysdynTerminal); + Top = getResourceOrNull(graph, URIs.Top); + UniformDistribution = getResourceOrNull(graph, URIs.UniformDistribution); + UniformDistribution_maxValue = getResourceOrNull(graph, URIs.UniformDistribution_maxValue); + UniformDistribution_maxValue_Inverse = getResourceOrNull(graph, URIs.UniformDistribution_maxValue_Inverse); + UniformDistribution_minValue = getResourceOrNull(graph, URIs.UniformDistribution_minValue); + UniformDistribution_minValue_Inverse = getResourceOrNull(graph, URIs.UniformDistribution_minValue_Inverse); + UsedVariableIndexes = getResourceOrNull(graph, URIs.UsedVariableIndexes); + Validations = getResourceOrNull(graph, URIs.Validations); + Validations_Dependencies = getResourceOrNull(graph, URIs.Validations_Dependencies); + Validations_Dependencies_DependencyConnectionsIssueSource = getResourceOrNull(graph, URIs.Validations_Dependencies_DependencyConnectionsIssueSource); + Validations_Dependencies_MissingDependencyConnectionsIssueSource = getResourceOrNull(graph, URIs.Validations_Dependencies_MissingDependencyConnectionsIssueSource); + Validations_Dependencies_dependencyValidator = getResourceOrNull(graph, URIs.Validations_Dependencies_dependencyValidator); + Validations_Dependencies_invalidSheetReferenceIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_invalidSheetReferenceIssueDescription); + Validations_Dependencies_missingDependencyValidator = getResourceOrNull(graph, URIs.Validations_Dependencies_missingDependencyValidator); + Validations_Dependencies_missingLinkIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_missingLinkIssueDescription); + Validations_Dependencies_noSuchVariableIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_noSuchVariableIssueDescription); + Validations_Dependencies_rangeIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_rangeIssueDescription); + Validations_Dependencies_rangeWarningDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_rangeWarningDescription); + Validations_Dependencies_unusedDependencyIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_unusedDependencyIssueDescription); + Validations_DependencyConstraint = getResourceOrNull(graph, URIs.Validations_DependencyConstraint); + Validations_EmptyEnumerationIssue = getResourceOrNull(graph, URIs.Validations_EmptyEnumerationIssue); + Validations_EnumerationConstraint = getResourceOrNull(graph, URIs.Validations_EnumerationConstraint); + Validations_Enumerations = getResourceOrNull(graph, URIs.Validations_Enumerations); + Validations_Enumerations_EnumerationIssueSource = getResourceOrNull(graph, URIs.Validations_Enumerations_EnumerationIssueSource); + Validations_Enumerations_emptyEnumerationIssueDescription = getResourceOrNull(graph, URIs.Validations_Enumerations_emptyEnumerationIssueDescription); + Validations_Enumerations_enumerationIndexValidator = getResourceOrNull(graph, URIs.Validations_Enumerations_enumerationIndexValidator); + Validations_ExpressionConstraint = getResourceOrNull(graph, URIs.Validations_ExpressionConstraint); + Validations_ExpressionIssue = getResourceOrNull(graph, URIs.Validations_ExpressionIssue); + Validations_Expressions = getResourceOrNull(graph, URIs.Validations_Expressions); + Validations_Expressions_ExpressionIssueSource = getResourceOrNull(graph, URIs.Validations_Expressions_ExpressionIssueSource); + Validations_Expressions_expressionIssueDescription = getResourceOrNull(graph, URIs.Validations_Expressions_expressionIssueDescription); + Validations_Expressions_expressionValidator = getResourceOrNull(graph, URIs.Validations_Expressions_expressionValidator); + Validations_Functions = getResourceOrNull(graph, URIs.Validations_Functions); + Validations_Functions_baseRealizationFunction = getResourceOrNull(graph, URIs.Validations_Functions_baseRealizationFunction); + Validations_Functions_path = getResourceOrNull(graph, URIs.Validations_Functions_path); + Validations_InvalidSheetReferenceIssue = getResourceOrNull(graph, URIs.Validations_InvalidSheetReferenceIssue); + Validations_Issue = getResourceOrNull(graph, URIs.Validations_Issue); + Validations_Issue_stringContexts = getResourceOrNull(graph, URIs.Validations_Issue_stringContexts); + Validations_Issue_stringContexts_Inverse = getResourceOrNull(graph, URIs.Validations_Issue_stringContexts_Inverse); + Validations_MissingDependencyConstraint = getResourceOrNull(graph, URIs.Validations_MissingDependencyConstraint); + Validations_MissingLinkIssue = getResourceOrNull(graph, URIs.Validations_MissingLinkIssue); + Validations_ModuleInputUnitWarning = getResourceOrNull(graph, URIs.Validations_ModuleInputUnitWarning); + Validations_ModuleOutputUnitWarning = getResourceOrNull(graph, URIs.Validations_ModuleOutputUnitWarning); + Validations_NoSuchVariableIssue = getResourceOrNull(graph, URIs.Validations_NoSuchVariableIssue); + Validations_RangeIssue = getResourceOrNull(graph, URIs.Validations_RangeIssue); + Validations_RangeWarning = getResourceOrNull(graph, URIs.Validations_RangeWarning); + Validations_UnitConstraint = getResourceOrNull(graph, URIs.Validations_UnitConstraint); + Validations_UnitWarning = getResourceOrNull(graph, URIs.Validations_UnitWarning); + Validations_Units = getResourceOrNull(graph, URIs.Validations_Units); + Validations_Units_UnitIssueSource = getResourceOrNull(graph, URIs.Validations_Units_UnitIssueSource); + Validations_Units_UnitIssueSource_allowEquivalents = getResourceOrNull(graph, URIs.Validations_Units_UnitIssueSource_allowEquivalents); + Validations_Units_UnitIssueSource_allowEquivalents_Inverse = getResourceOrNull(graph, URIs.Validations_Units_UnitIssueSource_allowEquivalents_Inverse); + Validations_Units_moduleInputUnitWarningDescription = getResourceOrNull(graph, URIs.Validations_Units_moduleInputUnitWarningDescription); + Validations_Units_moduleInterfaceExtension = getResourceOrNull(graph, URIs.Validations_Units_moduleInterfaceExtension); + Validations_Units_moduleOutputUnitWarningDescription = getResourceOrNull(graph, URIs.Validations_Units_moduleOutputUnitWarningDescription); + Validations_Units_unitValidator = getResourceOrNull(graph, URIs.Validations_Units_unitValidator); + Validations_Units_unitWarningDescription = getResourceOrNull(graph, URIs.Validations_Units_unitWarningDescription); + Validations_UnusedDependencyIssue = getResourceOrNull(graph, URIs.Validations_UnusedDependencyIssue); + Validations_constraint = getResourceOrNull(graph, URIs.Validations_constraint); + Validations_issue = getResourceOrNull(graph, URIs.Validations_issue); + Validations_listeningConstraint = getResourceOrNull(graph, URIs.Validations_listeningConstraint); + ValueGeneratorMethod = getResourceOrNull(graph, URIs.ValueGeneratorMethod); + Valve = getResourceOrNull(graph, URIs.Valve); + ValveSymbol = getResourceOrNull(graph, URIs.ValveSymbol); + ValveSymbol_orientation = getResourceOrNull(graph, URIs.ValveSymbol_orientation); + ValveSymbol_textLocation = getResourceOrNull(graph, URIs.ValveSymbol_textLocation); + Variable = getResourceOrNull(graph, URIs.Variable); + Variable_HasHead = getResourceOrNull(graph, URIs.Variable_HasHead); + Variable_HasTail = getResourceOrNull(graph, URIs.Variable_HasTail); + Variable_activeDatasets = getResourceOrNull(graph, URIs.Variable_activeDatasets); + Variable_activeDatasets_Inverse = getResourceOrNull(graph, URIs.Variable_activeDatasets_Inverse); + Variable_arrayIndexes = getResourceOrNull(graph, URIs.Variable_arrayIndexes); + Variable_arrayIndexesList = getResourceOrNull(graph, URIs.Variable_arrayIndexesList); + Variable_arrayIndexesList_Inverse = getResourceOrNull(graph, URIs.Variable_arrayIndexesList_Inverse); + Variable_arrayIndexes_Inverse = getResourceOrNull(graph, URIs.Variable_arrayIndexes_Inverse); + Variable_expressionList = getResourceOrNull(graph, URIs.Variable_expressionList); + Variable_expressionList_Inverse = getResourceOrNull(graph, URIs.Variable_expressionList_Inverse); + Variable_expressions = getResourceOrNull(graph, URIs.Variable_expressions); + Variable_expressions_Inverse = getResourceOrNull(graph, URIs.Variable_expressions_Inverse); + Variable_isHeadOf = getResourceOrNull(graph, URIs.Variable_isHeadOf); + Variable_isTailOf = getResourceOrNull(graph, URIs.Variable_isTailOf); + Variable_names = getResourceOrNull(graph, URIs.Variable_names); + Variable_names_Inverse = getResourceOrNull(graph, URIs.Variable_names_Inverse); + Variable_time = getResourceOrNull(graph, URIs.Variable_time); + Variable_time_Inverse = getResourceOrNull(graph, URIs.Variable_time_Inverse); + Variable_times = getResourceOrNull(graph, URIs.Variable_times); + Variable_times_Inverse = getResourceOrNull(graph, URIs.Variable_times_Inverse); + Variable_type = getResourceOrNull(graph, URIs.Variable_type); + Variable_type_Inverse = getResourceOrNull(graph, URIs.Variable_type_Inverse); + Variable_unit = getResourceOrNull(graph, URIs.Variable_unit); + Variable_unit_Inverse = getResourceOrNull(graph, URIs.Variable_unit_Inverse); + Variable_value = getResourceOrNull(graph, URIs.Variable_value); + Variable_value_Inverse = getResourceOrNull(graph, URIs.Variable_value_Inverse); + Variable_values = getResourceOrNull(graph, URIs.Variable_values); + Variable_values_Inverse = getResourceOrNull(graph, URIs.Variable_values_Inverse); + Variable_variability = getResourceOrNull(graph, URIs.Variable_variability); + Variable_variability_Inverse = getResourceOrNull(graph, URIs.Variable_variability_Inverse); + Vertical = getResourceOrNull(graph, URIs.Vertical); + WithLookupExpression = getResourceOrNull(graph, URIs.WithLookupExpression); + WithLookupExpression_expression = getResourceOrNull(graph, URIs.WithLookupExpression_expression); + WithLookupExpression_expression_Inverse = getResourceOrNull(graph, URIs.WithLookupExpression_expression_Inverse); + WithLookupExpression_lookup = getResourceOrNull(graph, URIs.WithLookupExpression_lookup); + WithLookupExpression_lookup_Inverse = getResourceOrNull(graph, URIs.WithLookupExpression_lookup_Inverse); + WithLookupExpression_maxX = getResourceOrNull(graph, URIs.WithLookupExpression_maxX); + WithLookupExpression_maxY = getResourceOrNull(graph, URIs.WithLookupExpression_maxY); + WithLookupExpression_minX = getResourceOrNull(graph, URIs.WithLookupExpression_minX); + WithLookupExpression_minY = getResourceOrNull(graph, URIs.WithLookupExpression_minY); + } + + public static SysdynResource getInstance(ReadGraph graph) { + Session session = graph.getSession(); + SysdynResource ret = session.peekService(SysdynResource.class); + if(ret == null) { + QueryControl qc = graph.getService(QueryControl.class); + ret = new SysdynResource(qc.getIndependentGraph(graph)); + session.registerService(SysdynResource.class, ret); + } + return ret; + } + + public static SysdynResource getInstance(RequestProcessor session) throws DatabaseException { + SysdynResource ret = session.peekService(SysdynResource.class); + if(ret == null) { + ret = session.syncRequest(new Read() { + public SysdynResource perform(ReadGraph graph) throws DatabaseException { + QueryControl qc = graph.getService(QueryControl.class); + return new SysdynResource(qc.getIndependentGraph(graph)); + } + }); + session.registerService(SysdynResource.class, ret); + } + return ret; + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/testGraph.tg b/dev-jkauttio/org.simantics.sysdyn.ontology/testGraph.tg new file mode 100644 index 00000000..f419f044 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ontology/testGraph.tg differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ontology/testGraph/Cancer.pgraph.keep b/dev-jkauttio/org.simantics.sysdyn.ontology/testGraph/Cancer.pgraph.keep new file mode 100644 index 00000000..42efd793 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ontology/testGraph/Cancer.pgraph.keep @@ -0,0 +1,6820 @@ +L0 = +G2D = +STR = +DIA = +SIMU = +MOD = +SYSDYN = +PROJ = + +//###################################################################### +//# Example work model with two modules +//###################################################################### + +WM = : PROJ.Project + PROJ.HasFeature _ : PROJ.FeatureSpec + PROJ.HasGroupId "org.simantics.sysdyn.feature.group" + L0.PartOf + +TAGS = WM.Tags : L0.Library + +//WM.dependency : L0.Template +// @template %type %head %tail %angle +// %type +// @L0.tag TAGS.AdminIsVisible +// @L0.tag TAGS.AdminIsFocusable +// STR.HasConnectionType SYSDYN.SysdynConnectionType +// SYSDYN.angle %angle +// DIA.HasArrowConnector _ : DIA.Connector +// SYSDYN.HasHeadTerminal %head +// DIA.AreConnected _ : DIA.Connector +// SYSDYN.HasTailTerminal %tail +// DIA.IsPlainConnectorOf %type +// +//WM.flow : L0.Template +// @template %type %head %tail +// %type +// @L0.tag TAGS.AdminIsVisible +// @L0.tag TAGS.AdminIsFocusable +// STR.HasConnectionType SYSDYN.SysdynConnectionType +// DIA.HasArrowConnector _ : DIA.Connector +// SYSDYN.HasHeadTerminal %head +// DIA.AreConnected _ : DIA.Connector +// SYSDYN.HasTailTerminal %tail +// DIA.IsPlainConnectorOf %type +// +//WM.conf_dependency : L0.Template +// @template %type %head %tail +// %type +// @L0.tag MOD.Mapped +// SYSDYN.HasHead %head +// SYSDYN.HasTail %tail +// +//WM.conf_dependency_ref : L0.Template +// @template %type %head %tail %ref +// %type +// @L0.tag MOD.Mapped +// SYSDYN.HasHead %head +// SYSDYN.HasTail %tail +// SYSDYN.RefersTo %ref + +WM.CancerModel : SYSDYN.SysdynModel + L0.HasLabel "Cancer Model" + SIMU.HasConfiguration CMC + SYSDYN.HasStartTime 0.0 + SYSDYN.HasStopTime 24.0 + +WM.CancerModel.Experiment : SYSDYN.Experiment + L0.HasLabel "Experiment" + +CMC = WM.CancerModel.CancerModelConfiguration : SYSDYN.Configuration + L0.HasLabel "CancerModelConfiguration" + +CMC.LungCProgressIAIVRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIAIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIAIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIAIVNos')" + +CMC.LungCT1Progresses : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCNotProgressing1[Type,Stage,Gender,Age]*LungCT1ProgressesRate[Type,Stage,Age,Gender]" +CMC.LungCProgressIAIB : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIAIBRate[Type,Age,Gender]*LungCsIANoD[Type,Gender,Age]" +CMC.LungCT1Death : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCT1Disabling[Type,Stage,Gender,Age]*LungCT1DeathRate[Type,Stage,Age,Gender]" +CMC.LungCHealthyPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCHealthy[Gender,Age]*LungCModelPopCorrectionFactor[Gender,Age]" +CMC.LungCsIADiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIANos')" + +CMC.LungCProgress03IV : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgress03IVRate[Type,Age,Gender]*LungCs03[Type,Gender,Age]" +CMC.LungCsIIIBNoDAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCsIIIBNoD[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCsIIIBNoD[Type,Gender,Age], -1) else -LungCsIIIBNoD[Type,Gender,Age]+VECTOR_MAP(LungCsIIIBNoD[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCProgressIBIVRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIBIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIBIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIBIVNos')" + +CMC.LungCOutputs02NosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs02Diagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCProgressIIAIV : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIIAIVRate[Type,Age,Gender]*LungCsIIANoD[Type,Gender,Age]" +CMC.LungCTherapy1Mortality : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCFirstTreatmentRate*(LungCD[Type,Stage,Gender,Age]*LungCTherapy1Ratio[Type,Stage,Age,Gender])*LungCTherapy1MortalityRatio/100" +CMC.LungCCured1PopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCCured1[Type,Stage,Gender,Age]" +CMC.LungCProgress01IV : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgress01IVRate[Type,Age,Gender]*LungCs01[Type,Gender,Age]" +CMC.LungCs03Diagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCs03DiagnosisRate[Type,Age,Gender]*LungCs03[Type,Gender,Age]" +CMC.LungCs03PopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCs03[Type,Gender,Age]" +CMC.LungCProgressIAIIA : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIAIIARate[Type,Age,Gender]*LungCsIANoD[Type,Gender,Age]" +CMC.LungCDPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCD[Type,Stage,Gender,Age]" +CMC.LungCsIIIADiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIIANos')" + +CMC.LungCOutputsIANsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIANoD[NonSmall,Gender!,Age!])" + +CMC.LungCOutputTherapy1 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCTherapy1[Type!,Stage!,Gender!,Age!])+sum(LungCTherapyCure1[Type!,Stage!,Gender!,Age!])+sum(LungCTherapy1Mortality[Type!,Stage!,Gender!,Age!])" + +CMC.LungCT2ProgressesRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Re01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Re02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Re03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Re01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Re02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Re03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Re01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Re02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Re03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2ReIVNos')" + +CMC.LungCOutputTherapy2Cure : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCTherapyCure2[Type!,Stage!,Gender!,Age!])" + +CMC.LungCT2Progresses : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCNotProgressing2[Type,Stage,Gender,Age]*LungCT2ProgressesRate[Type,Stage,Age,Gender]" +CMC.LungCT1ProgToDisablingRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Di01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Di02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Di03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Di01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Di02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Di03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Di01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Di02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Di03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1DiIVNos')" + +CMC.LungCProgressIIBIIIB : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIIBIIIBRate[Type,Age,Gender]*LungCsIIBNoD[Type,Gender,Age]" +CMC.LungCsIIIANoDAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCsIIIANoD[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCsIIIANoD[Type,Gender,Age], -1) else -LungCsIIIANoD[Type,Gender,Age]+VECTOR_MAP(LungCsIIIANoD[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCOutputsIBNsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIBDiagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCOutputRelapse : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCT1Progresses[Type!,Stage!,Gender!,Age!])+sum(LungCT2Progresses[Type!,Stage!,Gender!,Age!])" + +CMC.LungCT1Deceased : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "0" + +CMC.LungCT1DisablingPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCT1Disabling[Type,Stage,Gender,Age]" +CMC.LungCOutputsIAScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIADiagnosis[Small,Gender!,Age!])" + +CMC.LungCProgressIBIV : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIBIVRate[Type,Age,Gender]*LungCsIBNoD[Type,Gender,Age]" +CMC.LungCsIVDiagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCsIVDiagnosisRate[Type,Age,Gender]*LungCsIVNoD[Type,Gender,Age]" +CMC.LungCOutputsIIIBScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIBDiagnosis[Small,Gender!,Age!])" + +CMC.LungCsIIADiagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCsIIADiagnosisRate[Type,Age,Gender]*LungCsIIANoD[Type,Gender,Age]" +CMC.LungCTherapy1Ratio : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Ra01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Ra02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Ra03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Ra01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Ra02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Ra03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Ra01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Ra02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Ra03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1RaIVNos')" + +CMC.LungCsIBNoDPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCsIBNoD[Type,Gender,Age]" +CMC.LungCsIANoDAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCsIANoD[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCsIANoD[Type,Gender,Age], -1) else -LungCsIANoD[Type,Gender,Age]+VECTOR_MAP(LungCsIANoD[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCCured1Ageing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCCured1[Type,Stage,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCCured1[Type,Stage,Gender,Age], -1) else -LungCCured1[Type,Stage,Gender,Age]+VECTOR_MAP(LungCCured1[Type,Stage,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCProgress03IARate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P03IASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P03IANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P03IANos')" + +CMC.LungCT1Disabling : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCT1DisablingIniVal[Type,Stage,Age,Gender]" + +CMC.LungCCured2PopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCCured2[Type,Stage,Gender,Age]" +CMC.LungCTreated2IniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Tr01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Tr02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Tr03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Tr01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Tr02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Tr03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2TrIVNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Tr01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Tr02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Tr03Nos')" + +CMC.LungCsIIBDiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIBNos')" + +CMC.LungCOutputNoDSc : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCOutputs01ScNoD+LungCOutputs02ScNoD+LungCOutputs03ScNoD+LungCOutputsIAScNoD+LungCOutputsIBScNoD+LungCOutputsIIAScNoD+LungCOutputsIIBScNoD+LungCOutputsIIIAScNoD+LungCOutputsIIIBScNoD+LungCOutputsIVScNoD" + +CMC.LungCOutputsIANsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIADiagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCTherapy2Failed : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCFirstTreatmentRate*(LungCD[Type,Stage,Gender,Age]*LungCTherapy2Ratio[Type,Stage,Age,Gender])*LungCTherapy2FailRatio/100" +CMC.LungCProgressIIBIIIARate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIBIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIBIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIBIIIANos')" + +CMC.LungCProgressIBIIB : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIBIIBRate[Type,Age,Gender]*LungCsIBNoD[Type,Gender,Age]" +CMC.LungCsIIIBNoD : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCsIIIBNoDIniVal[Type,Age,Gender]" + +CMC.LungCDAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCD[Type,Stage,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCD[Type,Stage,Gender,Age], -1) else -LungCD[Type,Stage,Gender,Age]+VECTOR_MAP(LungCD[Type,Stage,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCOutputProgressing2 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCT2Progressing[Type!,Stage!,Gender!,Age!])" + +CMC.LungCT1ProgressingAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCT1Progressing[Type,Stage,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCT1Progressing[Type,Stage,Gender,Age], -1) else -LungCT1Progressing[Type,Stage,Gender,Age]+VECTOR_MAP(LungCT1Progressing[Type,Stage,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCT1ProgToDisabling : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCT1Progressing[Type,Stage,Gender,Age]*LungCT1ProgToDisablingRate[Type,Stage,Age,Gender]" +CMC.LungCT2ProgressingPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCT2Progressing[Type,Stage,Gender,Age]" +CMC.LungCInception : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCHealthy[Gender,Age]*LungCSmokersPercentageOfPopulation[Age,Gender]/100*LungCInceptionRate[Small,Age,Gender]" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCHealthy[Gender,Age]*LungCSmokersPercentageOfPopulation[Age,Gender]/100*LungCInceptionRate[NonSmall,Age,Gender]" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCHealthy[Gender,Age]*LungCInceptionRate[NotSmoker,Age,Gender]*LungCInceptionRateChanges[Gender]" +CMC.LungCTherapyCure2 : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCFirstTreatmentRate*(LungCD[Type,Stage,Gender,Age]*LungCTherapy2Ratio[Type,Stage,Age,Gender]*LungCTherapy2CureRatio[Type,Stage,Age,Gender])*(1-LungCTherapy2FailRatio/100)" +CMC.LungCCured1 : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCCured1IniVal[Type,Stage,Age,Gender]" + +CMC.LungCBirth : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "TotalPopulationBirth[Gender]" +CMC.LungCT2ProgressingAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCT2Progressing[Type,Stage,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCT2Progressing[Type,Stage,Gender,Age], -1) else -LungCT2Progressing[Type,Stage,Gender,Age]+VECTOR_MAP(LungCT2Progressing[Type,Stage,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCTherapy1 : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCFirstTreatmentRate*(LungCD[Type,Stage,Gender,Age]*LungCTherapy1Ratio[Type,Stage,Age,Gender]*(1-LungCTherapy1CureRatio[Type,Stage,Age,Gender]))*(1-LungCTherapy1MortalityRatio/100)" +CMC.LungCOutputNoDNs : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCOutputs01NsNoD+LungCOutputs02NsNoD+LungCOutputs03NsNoD+LungCOutputsIANsNoD+LungCOutputsIBNsNoD+LungCOutputsIIANsNoD+LungCOutputsIIBNsNoD+LungCOutputsIIIANsNoD+LungCOutputsIIIBNsNoD+LungCOutputsIVNsNoD" + +CMC.LungCProgressIIAIIIA : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIIAIIIARate[Type,Age,Gender]*LungCsIIANoD[Type,Gender,Age]" +CMC.LungCs01PopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCs01[Type,Gender,Age]" +CMC.LungCOutputsIIBNosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIBDiagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCModelPop : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "0.1+LungCHealthy[Gender,Age]+LungCNoDSum[Gender,Age]+sum(LungCD[Type!,Stage!,Gender,Age])+sum(LungCCured1[Type!,Stage!,Gender,Age])+sum(LungCNotProgressing1[Type!,Stage!,Gender,Age])+sum(LungCT1Progressing[Type!,Stage!,Gender,Age])+sum(LungCT1Disabling[Type!,Stage!,Gender,Age])+sum(LungCCured2[Type!,Stage!,Gender,Age])+sum(LungCNotProgressing2[Type!,Stage!,Gender,Age])+sum(LungCT2Progressing[Type!,Stage!,Gender,Age])+sum(LungCT2Disabling[Type!,Stage!,Gender,Age])" + +CMC.LungCProgressIIIAIIIBRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIIAIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIIAIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIIAIIIBNos')" + +CMC.LungCProgress0203 : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgress0203Rate[Type,Age,Gender]*LungCs02[Type,Gender,Age]" +CMC.LungCOutputsIIBNosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIBNoD[NotSmoker,Gender!,Age!])" + +CMC.LungCsIIBDiagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCsIIBDiagnosisRate[Type,Age,Gender]*LungCsIIBNoD[Type,Gender,Age]" +CMC.LungCOutputs03ScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs03[Small,Gender!,Age!])" + +CMC.LungCsIIIBNoDPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCsIIIBNoD[Type,Gender,Age]" +CMC.LungCsIIANoDIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIANos')" + +CMC.LungCProgress02IVRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P02IVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P02IVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P02IVNos')" + +CMC.LungCOutputs01ScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01Diagnosis[Small,Gender!,Age!])" + +CMC.LungCT2Progressing : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCT2ProgressingIniVal[Type,Stage,Age,Gender]" + +CMC.LungCT2Death : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCT2Disabling[Type,Stage,Gender,Age]*LungCT2DeathRate[Type,Stage,Age,Gender]" +CMC.LungCOutputsIIAScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIADiagnosis[Small,Gender!,Age!])" + +CMC.LungCsIBNoD : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCsIBNoDIniVal[Type,Age,Gender]" + +CMC.LungCT1DisablingIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Di01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Di02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Di03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Di01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Di02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Di03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1DiIVNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Di01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Di02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Di03Nos')" + +CMC.LungCNotProgressing1 : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCTreated1IniVal[Type,Stage,Age,Gender]" + +CMC.LungCOutputsIBScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIBDiagnosis[Small,Gender!,Age!])" + +CMC.LungCOutputProgressing1 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCT1Progressing[Type!,Stage!,Gender!,Age!])" + +CMC.LungCProgressIIIAIV : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIIIAIVRate[Type,Age,Gender]*LungCsIIIANoD[Type,Gender,Age]" +CMC.LungCProgressIAIV : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIAIVRate[Type,Age,Gender]*LungCsIANoD[Type,Gender,Age]" +CMC.LungCsIADiagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCsIADiagnosisRate[Type,Age,Gender]*LungCsIANoD[Type,Gender,Age]" +CMC.LungCOutputsIVNsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIVDiagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCOutputsIIIBNsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIBDiagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCProgress01IVRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P01IVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P01IVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P01IVNos')" + +CMC.LungCProgressIIAIIB : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIIAIIBRate[Type,Age,Gender]*LungCsIIANoD[Type,Gender,Age]" +CMC.LungCOutputNotProgressing1 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCNotProgressing1[Type!,Stage!,Gender!,Age!])" + +CMC.LungCsIIANoDPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCsIIANoD[Type,Gender,Age]" +CMC.LungCOutputsIIBNsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIBNoD[NonSmall,Gender!,Age!])" + +CMC.LungCProgressIIAIIBRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIAIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIAIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIAIIBNos')" + +CMC.LungCProgress0203Rate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P0203Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P0203Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P0203Nos')" + +CMC.LungCsIIBNoDPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCsIIBNoD[Type,Gender,Age]" +CMC.LungCSmokersPercentageOfPopulation : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_DATA('LCancer.xls', 'LungC_Risk', 'PSmokingMenT', 'PSmokingMen')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_DATA('LCancer.xls', 'LungC_Risk', 'PSmokingWomenT', 'PSmokingWomen')" + +CMC.LungCOutputsIVScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIVDiagnosis[Small,Gender!,Age!])" + +CMC.LungCs01Ageing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCs01[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCs01[Type,Gender,Age], -1) else -LungCs01[Type,Gender,Age]+VECTOR_MAP(LungCs01[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCOutputsIBNosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIBNoD[NotSmoker,Gender!,Age!])" + +CMC.LungCs02 : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCs02IniVal[Type,Age,Gender]" + +CMC.LungCCausedDeath : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCT1Death[Type!,Stage!,Gender,Age])+sum(LungCT2Death[Type!,Stage!,Gender,Age])+sum(LungCTherapy1Mortality[Type!,Stage!,Gender,Age])" + +CMC.LungCsIBDiagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCsIBNoD[Type,Gender,Age]*LungCsIBDiagnosisRate[Type,Age,Gender]" +CMC.LungCProgressIIBIV : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIIBIVRate[Type,Age,Gender]*LungCsIIBNoD[Type,Gender,Age]" +CMC.LungCOutputCured2 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCCured2[Type!,Stage!,Gender!,Age!])" + +CMC.LungCsIBDiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIBNos')" + +CMC.LungCTherapy1MortalityRatio : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mor')" + +CMC.LungCTreated1PopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCNotProgressing1[Type,Stage,Gender,Age]" +CMC.LungCOutputTherapy2 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCTherapy2[Type!,Stage!,Gender!,Age!])+sum(LungCTherapyCure2[Type!,Stage!,Gender!,Age!])+sum(LungCTherapy2Failed[Type!,Stage!,Gender!,Age!])" + +CMC.LungCsIIBNoDIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIBNos')" + +CMC.LungCs03DiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PD03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PD03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PD03Nos')" + +CMC.LungCsIIIANoDIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIIANos')" + +CMC.LungCTreated1Ageing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCNotProgressing1[Type,Stage,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCNotProgressing1[Type,Stage,Gender,Age], -1) else -LungCNotProgressing1[Type,Stage,Gender,Age]+VECTOR_MAP(LungCNotProgressing1[Type,Stage,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCT2DisablingPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCT2Disabling[Type,Stage,Gender,Age]" +CMC.LungCOutputs03ScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs03Diagnosis[Small,Gender!,Age!])" + +CMC.LungCProgressIIIBIV : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIIIBIVRate[Type,Age,Gender]*LungCsIIIBNoD[Type,Gender,Age]" +CMC.LungCProgressIIIBIVRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIIBIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIIBIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIIBIVNos')" + +CMC.LungCProgressIIIAIVRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIIAIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIIAIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIIAIVNos')" + +CMC.LungCT2ProgToDisabling : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCT2Progressing[Type,Stage,Gender,Age]*LungCT2ProgToDisablingRate[Type,Stage,Age,Gender]" +CMC.LungCProgress03IVRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P03IVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P03IVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P03IVNos')" + +CMC.LungCOutputs03NosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs03[NotSmoker,Gender!,Age!])" + +CMC.LungCOutputsIIIAScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIADiagnosis[Small,Gender!,Age!])" + +CMC.LungCOutputsIIBScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIBNoD[Small,Gender!,Age!])" + +CMC.LungCOutputsIIIBNosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIBDiagnosis[NotSmoker,Gender!,Age!])" + +CMC.Cloud45 : SYSDYN.Cloud + +CMC.LungCOutputs03NosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs03Diagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCOutputs03NsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs03Diagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCOutputsIBNosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIBDiagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCOutputsIIIANsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIANoD[NonSmall,Gender!,Age!])" + +CMC.LungCHealthy : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCHealthyIniVal[Age,Gender]" + +CMC.LungCs01DiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PD01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PD01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PD01Nos')" + +CMC.LungCTreated1IniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Tr01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Tr02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Tr03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Tr01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Tr02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Tr03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1TrIVNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Tr01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Tr02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Tr03Nos')" + +CMC.LungCProgressIBIIBRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIBIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIBIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIBIIBNos')" + +CMC.LungCsIIBNoDAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCsIIBNoD[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCsIIBNoD[Type,Gender,Age], -1) else -LungCsIIBNoD[Type,Gender,Age]+VECTOR_MAP(LungCsIIBNoD[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCProgressIIIAIIIB : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCsIIIANoD[Type,Gender,Age]*LungCProgressIIIAIIIBRate[Type,Age,Gender]" +CMC.LungCOutputsIVNsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIVNoD[NonSmall,Gender!,Age!])" + +CMC.LungCT1ProgressingIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Pr01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Pr02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Pr03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Pr01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Pr02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Pr03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1PrIVNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Pr01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Pr02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Pr03Nos')" + +CMC.LungCs02Ageing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCs02[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCs02[Type,Gender,Age], -1) else -LungCs02[Type,Gender,Age]+VECTOR_MAP(LungCs02[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCOutputDisabling1 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCT1Disabling[Type!,Stage!,Gender!,Age!])" + +CMC.LungCOutputsIIIANsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIADiagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCsIIANoDAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCsIIANoD[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCsIIANoD[Type,Gender,Age], -1) else -LungCsIIANoD[Type,Gender,Age]+VECTOR_MAP(LungCsIIANoD[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCOutputsIIIANosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIANoD[NotSmoker,Gender!,Age!])" + +CMC.LungCProgress03IA : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgress03IARate[Type,Age,Gender]*LungCs03[Type,Gender,Age]" +CMC.LungCOutputsIIIANosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIADiagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCTreated2PopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCNotProgressing2[Type,Stage,Gender,Age]" +CMC.LungCsIIIBDiagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCsIIIBDiagnosisRate[Type,Age,Gender]*LungCsIIIBNoD[Type,Gender,Age]" +CMC.LungCInceptionRateChanges : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_DATA('LCancer.xls', 'LungC_Risk', 'B', 'C147')" + +CMC.LungCNotProgressing2 : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCTreated2IniVal[Type,Stage,Age,Gender]" + +CMC.LungCProgressIIBIVRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIBIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIBIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIBIVNos')" + +CMC.LungCs02Diagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCs02DiagnosisRate[Type,Age,Gender]*LungCs02[Type,Gender,Age]" +CMC.LungCFirstTreatmentRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "10" + +CMC.LungCCured2 : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCCured2IniVal[Type,Stage,Age,Gender]" + +CMC.LungCOutputs02NosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs02[NotSmoker,Gender!,Age!])" + +CMC.LungCOutputs02ScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs02[Small,Gender!,Age!])" + +CMC.LungCProgressIIBIIIA : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgressIIBIIIARate[Type,Age,Gender]*LungCsIIBNoD[Type,Gender,Age]" +CMC.LungCs03Ageing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCs03[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCs03[Type,Gender,Age], -1) else -LungCs03[Type,Gender,Age]+VECTOR_MAP(LungCs03[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCOutputNsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01Diagnosis[NonSmall,Gender!,Age!])+sum(LungCs02Diagnosis[NonSmall,Gender!,Age!])+sum(LungCs03Diagnosis[NonSmall,Gender!,Age!])+sum(LungCsIADiagnosis[NonSmall,Gender!,Age!])+sum(LungCsIBDiagnosis[NonSmall,Gender!,Age!])+sum(LungCsIIADiagnosis[NonSmall,Gender!,Age!])+sum(LungCsIIBDiagnosis[NonSmall,Gender!,Age!])+sum(LungCsIIIADiagnosis[NonSmall,Gender!,Age!])+sum(LungCsIIIBDiagnosis[NonSmall,Gender!,Age!])+sum(LungCsIVDiagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCTherapyCure1 : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCFirstTreatmentRate*(LungCD[Type,Stage,Gender,Age]*LungCTherapy1Ratio[Type,Stage,Age,Gender]*LungCTherapy1CureRatio[Type,Stage,Age,Gender])*(1-LungCTherapy1MortalityRatio/100)" +CMC.LungCT2DisablingIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Di01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Di02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Di03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Di01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Di02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Di03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2DiIVNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Di01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Di02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Di03Nos')" + +CMC.LungCsIBNoDIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIBNos')" + +CMC.LungCOutputModelPopExcludingHealthy : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPop[Gender,Age]-LungCHealthy[Gender,Age]" + +CMC.LungCsIIADiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIANos')" + +CMC.LungCProgress0102 : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgress0102Rate[Type,Age,Gender]*LungCs01[Type,Gender,Age]" +CMC.LungCsIVNoDAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCsIVNoD[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCsIVNoD[Type,Gender,Age], -1) else -LungCsIVNoD[Type,Gender,Age]+VECTOR_MAP(LungCsIVNoD[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCModelPopCorrectionRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "0.9" + +CMC.LungCTherapy2 : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCFirstTreatmentRate*(LungCD[Type,Stage,Gender,Age]*LungCTherapy2Ratio[Type,Stage,Age,Gender]*(1-LungCTherapy2CureRatio[Type,Stage,Age,Gender]))*(1-LungCTherapy2FailRatio/100)" +CMC.LungCsIIANoD : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCsIIANoDIniVal[Type,Age,Gender]" + +CMC.LungCsIIIANoD : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCsIIIANoDIniVal[Type,Age,Gender]" + +CMC.LungCOutputsIVNosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIVDiagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCTherapy2Ratio : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Ra01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Ra02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Ra03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Ra01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Ra02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Ra03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Ra01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Ra02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Ra03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2RaIVNos')" + +CMC.LungCOutputs01NosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01[NotSmoker,Gender!,Age!])" + +CMC.LungCCured2Ageing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCCured2[Type,Stage,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCCured2[Type,Stage,Gender,Age], -1) else -LungCCured2[Type,Stage,Gender,Age]+VECTOR_MAP(LungCCured2[Type,Stage,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCs03 : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCs03IniVal[Type,Age,Gender]" + +CMC.LungCOutputs03NsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs03[NonSmall,Gender!,Age!])" + +CMC.LungCOutputsIIANosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIANoD[NotSmoker,Gender!,Age!])" + +CMC.LungCsIIIANoDPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCsIIIANoD[Type,Gender,Age]" +CMC.LungCs01Diagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCs01DiagnosisRate[Type,Age,Gender]*LungCs01[Type,Gender,Age]" +CMC.LungCOutputs02NsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs02Diagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCOutputsIANosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIADiagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCProgress02IV : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCProgress02IVRate[Type,Age,Gender]*LungCs02[Type,Gender,Age]" +CMC.LungCT1Progressing : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCT1ProgressingIniVal[Type,Stage,Age,Gender]" + +CMC.LungCOutputTherapy1Cure : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCTherapyCure1[Type!,Stage!,Gender!,Age!])" + +CMC.LungCsIANoDIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIANos')" + +CMC.LungCOutputsIANosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIANoD[NotSmoker,Gender!,Age!])" + +CMC.LungCOutputTherapy1MortalityInTherapy : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCTherapy1Mortality[Type!,Stage!,Gender!,Age!])" + +CMC.LungCTreated2Ageing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCNotProgressing2[Type,Stage,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCNotProgressing2[Type,Stage,Gender,Age], -1) else -LungCNotProgressing2[Type,Stage,Gender,Age]+VECTOR_MAP(LungCNotProgressing2[Type,Stage,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCs01IniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INd01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INd01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INd01Nos')" + +CMC.LungCOutputDisabling2 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCT2Disabling[Type!,Stage!,Gender!,Age!])" + +CMC.LungCT1ProgressesRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Re01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Re02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Re03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Re01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Re02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Re03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Re01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Re02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Re03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1ReIVNos')" + +CMC.LungCs02PopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCs02[Type,Gender,Age]" +CMC.LungCOutputsIIAScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIANoD[Small,Gender!,Age!])" + +CMC.LungCsIVNoDPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCsIVNoD[Type,Gender,Age]*LungCModelPopCorrectionFactor[Gender,Age]" +CMC.LungCoutputNoDNos : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCOutputs01NosNoD+LungCOutputs02NosNoD+LungCOutputs03NosNoD+LungCOutputsIANosNoD+LungCOutputsIBNosNoD+LungCOutputsIIANosNoD+LungCOutputsIIBNosNoD+LungCOutputsIIIANosNoD+LungCOutputsIIIBNosNoD+LungCOutputsIVNosNoD" + +CMC.LungCOutputsIIANosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIADiagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCs01 : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCs01IniVal[Type,Age,Gender]" + +CMC.LungCOutputCured1 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCCured1[Type!,Stage!,Gender!,Age!])" + +CMC.LungCTherapy1CureRatio : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Cr01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Cr02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Cr03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Cr01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Cr02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Cr03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Cr01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Cr02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Cr03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1CrIVNos')" + +CMC.LungCsIIIBDiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIIIBNos')" + +CMC.LungCsIVDiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PDIVNos')" + +CMC.LungCOutputsIIBNsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIBDiagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCOutputModelPop : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCModelPop[Gender!,Age!])" + +CMC.LungCsIANoDPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCsIANoD[Type,Gender,Age]" +CMC.LungCCured2IniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Cr01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Cr02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Cr03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Cr01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Cr02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Cr03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2CrIVNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Cr01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Cr02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Cr03Nos')" + +CMC.LungCModelPopCorrectionFactor : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionRate*(TotalPopulation[Gender,Age]/LungCModelPop[Gender,Age]-1)-(TotalPopulationDeath[Gender,Age]-LungCCausedDeath[Gender,Age])/LungCModelPop[Gender,Age]" + +CMC.LungCTherapy2FailRatio : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Fail')" + +CMC.LungCsIBNoDAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age0 then -LungCsIBNoD[Type,Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCsIBNoD[Type,Gender,Age], -1) else -LungCsIBNoD[Type,Gender,Age]+VECTOR_MAP(LungCsIBNoD[Type,Gender,Age], -1)*DummyRateForUnitsConversion" +CMC.LungCOutputNosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01Diagnosis[NotSmoker,Gender!,Age!])+sum(LungCs02Diagnosis[NotSmoker,Gender!,Age!])+sum(LungCs03Diagnosis[NotSmoker,Gender!,Age!])+sum(LungCsIADiagnosis[NotSmoker,Gender!,Age!])+sum(LungCsIBDiagnosis[NotSmoker,Gender!,Age!])+sum(LungCsIIADiagnosis[NotSmoker,Gender!,Age!])+sum(LungCsIIBDiagnosis[NotSmoker,Gender!,Age!])+sum(LungCsIIIADiagnosis[NotSmoker,Gender!,Age!])+sum(LungCsIIIBDiagnosis[NotSmoker,Gender!,Age!])+sum(LungCsIVDiagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCOutputNotProgressing2 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCNotProgressing2[Type!,Stage!,Gender!,Age!])" + +CMC.LungCOutputsIIIBNosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIBNoD[NotSmoker,Gender!,Age!])" + +CMC.LungCProgressIIBIIIBRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIBIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIBIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIBIIIBNos')" + +CMC.LungCOutputT1Mortality : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCT1Death[Type!,Stage!,Gender!,Age!])" + +CMC.LungCOutputsIIIBNsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIBNoD[NonSmall,Gender!,Age!])" + +CMC.LungCDIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDia01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDia02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDia03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDia01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDia02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDia03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDiaIVNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDia01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDia02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IDia03Nos')" + +CMC.LungCOutputsIIANsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIANoD[NonSmall,Gender!,Age!])" + +CMC.LungCProgressIIAIVRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIAIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIAIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIAIVNos')" + +CMC.LungCOutputs01ScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01[Small,Gender!,Age!])" + +CMC.LungCOutputNoDSum : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCNoDSum[Gender!,Age!])" + +CMC.LungCsIVNoDIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIVNos')" + +CMC.LungCT1ProgressingPopCorr : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCModelPopCorrectionFactor[Gender,Age]*LungCT1Progressing[Type,Stage,Gender,Age]" +CMC.LungCOutputTherapy1NoCure : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCTherapy1[Type!,Stage!,Gender!,Age!])" + +CMC.LungCOutputsIVScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIVNoD[Small,Gender!,Age!])" + +CMC.LungCProgress0102Rate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P0102Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P0102Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'P0102Nos')" + +CMC.LungCOutputDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01Diagnosis[Type!,Gender!,Age!])+sum(LungCs02Diagnosis[Type!,Gender!,Age!])+sum(LungCs03Diagnosis[Type!,Gender!,Age!])+sum(LungCsIADiagnosis[Type!,Gender!,Age!])+sum(LungCsIBDiagnosis[Type!,Gender!,Age!])+sum(LungCsIIADiagnosis[Type!,Gender!,Age!])+sum(LungCsIIBDiagnosis[Type!,Gender!,Age!])+sum(LungCsIIIADiagnosis[Type!,Gender!,Age!])+sum(LungCsIIIBDiagnosis[Type!,Gender!,Age!])+sum(LungCsIVDiagnosis[Type!,Gender!,Age!])" + +CMC.LungCOutputHealthyAndTreated : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCHealthy[Gender!,Age!])+sum(LungCNotProgressing2[Type!,Stage!,Gender!,Age!])+sum(LungCNotProgressing1[Type!,Stage!,Gender!,Age!])+sum(LungCCured1[Type!,Stage!,Gender!,Age!])+sum(LungCCured2[Type!,Stage!,Gender!,Age!])" + +CMC.LungCOutputsIIANsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIADiagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCT2DeathRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Mo01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Mo02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Mo03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Mo01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Mo02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Mo03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Mo01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Mo02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Mo03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2MoIVNos')" + +CMC.LungCProgressIAIBRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIAIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIAIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIAIBNos')" + +CMC.LungCT2Deceased : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "0" + +CMC.LungCs03IniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INd03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INd03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INd03Nos')" + +CMC.LungCOutputs01NsDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01Diagnosis[NonSmall,Gender!,Age!])" + +CMC.LungCOutputs02NsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs02[NonSmall,Gender!,Age!])" + +CMC.LungCsIIIADiagnosis : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "LungCsIIIADiagnosisRate[Type,Age,Gender]*LungCsIIIANoD[Type,Gender,Age]" +CMC.LungCTherapy2CureRatio : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Cr01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Cr02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Cr03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Cr01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Cr02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Cr03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Cr01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Cr02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Cr03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2CrIVNos')" + +CMC.LungCHealthyIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IHe')" + +CMC.LungCOutputMortality : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCCausedDeath[Gender!,Age!])" + +CMC.LungCs02IniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INd02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INd02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INd02Nos')" + +CMC.LungCOutputScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01Diagnosis[Small,Gender!,Age!])+sum(LungCs02Diagnosis[Small,Gender!,Age!])+sum(LungCs03Diagnosis[Small,Gender!,Age!])+sum(LungCsIADiagnosis[Small,Gender!,Age!])+sum(LungCsIBDiagnosis[Small,Gender!,Age!])+sum(LungCsIIADiagnosis[Small,Gender!,Age!])+sum(LungCsIIBDiagnosis[Small,Gender!,Age!])+sum(LungCsIIIADiagnosis[Small,Gender!,Age!])+sum(LungCsIIIBDiagnosis[Small,Gender!,Age!])+sum(LungCsIVDiagnosis[Small,Gender!,Age!])" + +CMC.LungCOutputs01NsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01[NonSmall,Gender!,Age!])" + +CMC.LungCT1DeathRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mo01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mo02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mo03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mo01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mo02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mo03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mo01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mo02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1Mo03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT1MoIVNos')" + +CMC.LungCProgressIAIIARate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIAIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIAIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIAIIANos')" + +CMC.LungCsIIIBNoDIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'INdIIIBNos')" + +CMC.LungCOutputs01NosDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01Diagnosis[NotSmoker,Gender!,Age!])" + +CMC.LungCInceptionRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIncSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIncNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIncNos')" + +CMC.LungCs02DiagnosisRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PD02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PD02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PD02Nos')" + +CMC.LungCNoDSum : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs01[Type!,Gender,Age])+sum(LungCs02[Type!,Gender,Age])+sum(LungCs03[Type!,Gender,Age])+sum(LungCsIANoD[Type!,Gender,Age])+sum(LungCsIBNoD[Type!,Gender,Age])+sum(LungCsIIANoD[Type!,Gender,Age])+sum(LungCsIIBNoD[Type!,Gender,Age])+sum(LungCsIIIANoD[Type!,Gender,Age])+sum(LungCsIIIBNoD[Type!,Gender,Age])+sum(LungCsIVNoD[Type!,Gender,Age])" + +CMC.LungCOutputsIIIAScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIANoD[Small,Gender!,Age!])" + +CMC.LungCHealthyAgeing : SYSDYN.Valve + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "(if Age==Age0 then -LungCHealthy[Gender,Age] elseif Age==Age100 then +VECTOR_MAP(LungCHealthy[Gender,Age], -1) else -LungCHealthy[Gender,Age]+VECTOR_MAP(LungCHealthy[Gender,Age], -1))*DummyRateForUnitsConversion" +CMC.LungCsIVNoD : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCsIVNoDIniVal[Type,Age,Gender]" + +CMC.LungCOutputsIIIBScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIIBNoD[Small,Gender!,Age!])" + +CMC.LungCOutputs02ScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCs02Diagnosis[Small,Gender!,Age!])" + +CMC.LungCOutputsIBNsNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIBNoD[NonSmall,Gender!,Age!])" + +CMC.LungCT2ProgToDisablingRate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Di01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Di02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Di03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Di01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Di02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Di03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Di01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Di02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2Di03Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PT2DiIVNos')" + +CMC.LungCOutputsIAScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIANoD[Small,Gender!,Age!])" + +CMC.LungCCured1IniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Cr01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Cr02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Cr03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Cr01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Cr02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Cr03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1CrIVNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Cr01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Cr02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT1Cr03Nos')" + +CMC.LungCOutputT2Mortality : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCT2Death[Type!,Stage!,Gender!,Age!])" + +CMC.LungCOutputTherapy2NoCure : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCTherapy2[Type!,Stage!,Gender!,Age!])" + +CMC.LungCOutputsIBScNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIBNoD[Small,Gender!,Age!])" + +CMC.LungCOutputsIIBScDiagnosis : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIIBDiagnosis[Small,Gender!,Age!])" + +CMC.LungCsIIBNoD : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCsIIBNoDIniVal[Type,Age,Gender]" + +CMC.LungCT2ProgressingIniVal : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIIBSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIVSm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Pr01Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Pr02Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Pr03Sm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIIBNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIVNs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Pr01Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Pr02Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Pr03Ns')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIIANos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIIIBNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2PrIVNos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Pr01Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Pr02Nos')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'IT2Pr03Nos')" + +CMC.LungCOutputTherapy2Failed : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCTherapy2Failed[Type!,Stage!,Gender!,Age!])" + +CMC.LungCOutputsIVNosNoD : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(LungCsIVNoD[NotSmoker,Gender!,Age!])" + +CMC.LungCsIANoD : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCsIANoDIniVal[Type,Age,Gender]" + +CMC.LungCT2Disabling : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCT2DisablingIniVal[Type,Stage,Age,Gender]" + +CMC.LungCProgressIIAIIIARate : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIAIIIASm')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIAIIIANs')" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_CONSTANT('LCancer.xls', 'LungC_In', 'PIIAIIIANos')" + +CMC.LungCD : SYSDYN.Stock + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,sIA,Age,Gender]" + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,sIB,Age,Gender]" + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,sIIA,Age,Gender]" + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,sIIB,Age,Gender]" + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,sIIIA,Age,Gender]" + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,sIIIB,Age,Gender]" + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,sIV,Age,Gender]" + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,s03,Age,Gender]" + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,s02,Age,Gender]" + _ : SYSDYN.StockExpression + SYSDYN.HasInitialEquation "LungCDIniVal[Type,s01,Age,Gender]" + +CMC.d127 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCD +CMC.d882 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputs01NosNoD +CMC.d331 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIANoDAgeing CMC.DummyRateForUnitsConversion +CMC.d737 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCs02Diagnosis +CMC.f580 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCProgressIIIBIV +CMC.f805 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCTherapyCure1 CMC.LungCD +CMC.d84 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1Progresses CMC.LungCNotProgressing1 +CMC.d463 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCNotProgressing2 +CMC.f517 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCProgress03IV +CMC.d458 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCsIIIBNoD +CMC.d451 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCs02 +CMC.d220 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1ProgressingPopCorr CMC.LungCModelPopCorrectionFactor +CMC.d454 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCsIBNoD +CMC.d846 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy1 CMC.LungCTherapyCure1 +CMC.d722 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCsIVDiagnosis +CMC.d578 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIIBIV CMC.LungCsIIIBNoD +CMC.d695 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs03NsDiagnosis CMC.LungCs03Diagnosis +CMC.d728 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCsIIADiagnosis +CMC.d742 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCsIIBDiagnosis +CMC.d378 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIBDiagnosis CMC.LungCsIBNoD +CMC.d325 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIANoDPopCorr CMC.LungCsIIANoD +CMC.f29 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1Progressing CMC.LungCT1Progresses +CMC.d889 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputsIIIANosNoD +CMC.d572 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIAIV CMC.LungCsIIANoD +CMC.f540 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIIIBIV CMC.LungCsIIIBNoD +CMC.d58 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCInception CMC.LungCHealthy +CMC.d211 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1Death CMC.LungCT1DeathRate +CMC.f15 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs02 CMC.LungCProgress0102 +CMC.d861 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputs01NsNoD +CMC.f337 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIBNoD CMC.LungCsIIBNoDAgeing +CMC.d101 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTreated1Ageing CMC.DummyRateForUnitsConversion +CMC.d340 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIBNoDAgeing CMC.LungCsIIBNoD +CMC.f76 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCNotProgressing1 CMC.LungCTreated1Ageing +CMC.d62 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs01Ageing CMC.LungCs01 +CMC.d833 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured2Ageing CMC.DummyRateForUnitsConversion +CMC.d571 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIAIV CMC.LungCProgressIIAIVRate +CMC.f139 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs01 CMC.LungCs01PopCorr +CMC.d129 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPopCorrectionFactor CMC.TotalPopulationDeath +CMC.d917 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure2 CMC.LungCTherapy2FailRatio +CMC.d926 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy2Failed CMC.LungCTherapy2Failed +CMC.d548 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIANoD CMC.LungCsIIANoDIniVal +CMC.f495 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCs02Diagnosis +CMC.d739 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCsIADiagnosis +CMC.d876 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputsIBScNoD +CMC.d662 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs02ScNoD CMC.LungCs02 +CMC.d783 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIANosDiagnosis CMC.LungCsIIIADiagnosis +CMC.d758 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs03NosNoD CMC.LungCs03 +CMC.f236 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIANoD CMC.LungCProgress03IA +CMC.d706 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIAScDiagnosis CMC.LungCsIIIADiagnosis +CMC.f348 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIANoD CMC.LungCsIIIANoDAgeing +CMC.f145 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIANoD CMC.LungCsIANoDPopCorr +CMC.d627 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputProgressing2 CMC.LungCT2Progressing +CMC.d715 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCs03Diagnosis +CMC.f23 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCNotProgressing1 CMC.LungCTherapy1 +CMC.f364 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCsIVNoDAgeing +CMC.d96 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy2 CMC.LungCFirstTreatmentRate +CMC.d486 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNotProgressing1 CMC.LungCTreated1IniVal +CMC.f509 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCProgress01IV +CMC.d160 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTreated2PopCorr CMC.LungCModelPopCorrectionFactor +CMC.d569 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIBIV CMC.LungCProgressIBIVRate +CMC.d367 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIVNoDAgeing CMC.LungCsIVNoD +CMC.d716 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCsIADiagnosis +CMC.d391 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIBDiagnosis CMC.LungCsIIBDiagnosisRate +CMC.d778 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs03NosDiagnosis CMC.LungCs03Diagnosis +CMC.d743 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCsIIIADiagnosis +CMC.d720 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCsIIIADiagnosis +CMC.d723 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCs01Diagnosis +CMC.d453 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCsIANoD +CMC.d180 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2ProgressingAgeing CMC.DummyRateForUnitsConversion +CMC.d244 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress0203 CMC.LungCs02 +CMC.d351 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIANoDAgeing CMC.DummyRateForUnitsConversion +CMC.f246 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs02 CMC.LungCs02PopCorr +CMC.d488 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1Disabling CMC.LungCT1DisablingIniVal +CMC.d835 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured2PopCorr CMC.LungCModelPopCorrectionFactor +CMC.d415 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIAIB CMC.LungCProgressIAIBRate +CMC.d452 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCs03 +CMC.f342 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIANoD CMC.LungCsIIIANoDPopCorr +CMC.d862 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputs02NsNoD +CMC.f579 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCProgressIIIAIV +CMC.f295 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIIBIIIA CMC.LungCsIIBNoD +CMC.d341 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIBNoDAgeing CMC.DummyRateForUnitsConversion +CMC.d87 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1Progresses CMC.LungCT1ProgressesRate +CMC.d508 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs01Diagnosis CMC.LungCs01DiagnosisRate +CMC.d221 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1ProgressingPopCorr CMC.LungCT1Progressing +CMC.d64 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress0102 CMC.LungCProgress0102Rate +CMC.d417 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIBIIB CMC.LungCProgressIBIIBRate +CMC.f12 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCInception CMC.LungCHealthy +CMC.d881 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputsIVScNoD +CMC.d765 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIVNosNoD CMC.LungCsIVNoD +CMC.d784 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIBNosDiagnosis CMC.LungCsIIIBDiagnosis +CMC.d507 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs01Diagnosis CMC.LungCs01 +CMC.d405 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIADiagnosis CMC.LungCsIIANoD +CMC.d573 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIBIV CMC.LungCProgressIIBIVRate +CMC.f237 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgress03IA CMC.LungCs03 +CMC.f370 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCsIVNoDPopCorr +CMC.f309 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIBNoD CMC.LungCsIBNoDPopCorr +CMC.d762 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIBNosNoD CMC.LungCsIIBNoD +CMC.d734 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCInception CMC.LungCInceptionRateChanges +CMC.d875 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputsIAScNoD +CMC.d567 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress03IV CMC.LungCs03 +CMC.d116 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCausedDeath CMC.LungCT2Death +CMC.d144 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs01PopCorr CMC.LungCs01 +CMC.d914 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy2Failed CMC.LungCFirstTreatmentRate +CMC.d380 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIBDiagnosis CMC.LungCsIBDiagnosisRate +CMC.d100 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs01Ageing CMC.DummyRateForUnitsConversion +CMC.f824 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCCured2 CMC.LungCCured2PopCorr +CMC.d661 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs01ScNoD CMC.LungCs01 +CMC.f286 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIBNoD CMC.LungCProgressIIAIIB +CMC.d800 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured1PopCorr CMC.LungCCured1 +CMC.f381 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIADiagnosis CMC.LungCsIIANoD +CMC.d581 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCsIVNoDIniVal +CMC.d308 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIIAIIIB CMC.LungCsIIIANoD +CMC.f392 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIADiagnosis CMC.LungCsIIIANoD +CMC.f177 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2Progressing CMC.LungCT2ProgressingAgeing +CMC.f496 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs02Diagnosis CMC.LungCs02 +CMC.d605 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCsIBDiagnosis +CMC.d373 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIVNoDPopCorr CMC.LungCModelPopCorrectionFactor +CMC.d607 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCsIIBDiagnosis +CMC.d813 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCCured1 +CMC.f42 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2Death CMC.LungCT2Disabling +CMC.f205 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1Death CMC.LungCT1Disabling +CMC.d759 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIANosNoD CMC.LungCsIANoD +CMC.d644 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIANsNoD CMC.LungCsIANoD +CMC.d851 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy2Cure CMC.LungCTherapyCure2 +CMC.d927 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCausedDeath CMC.LungCTherapy1Mortality +CMC.d694 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs02ScDiagnosis CMC.LungCs02Diagnosis +CMC.d213 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1Death CMC.LungCT1Disabling +CMC.d51 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCBirth CMC.TotalPopulationBirth +CMC.d456 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCsIIBNoD +CMC.d568 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIAIV CMC.LungCsIANoD +CMC.d874 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputs03ScNoD +CMC.d171 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2ProgressingPopCorr CMC.LungCT2Progressing +CMC.d916 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy2Failed CMC.LungCTherapy2FailRatio +CMC.f386 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIBDiagnosis CMC.LungCsIIBNoD +CMC.d796 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured1Ageing CMC.LungCCured1 +CMC.f200 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1Disabling CMC.LungCT1ProgToDisabling +CMC.f525 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCProgressIBIV +CMC.d787 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCInception CMC.LungCSmokersPercentageOfPopulation +CMC.d161 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTreated2PopCorr CMC.LungCNotProgressing2 +CMC.d919 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy2Failed CMC.LungCTherapy2Ratio +CMC.f534 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIIBIV CMC.LungCsIIBNoD +CMC.d744 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCsIIIBDiagnosis +CMC.f20 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIADiagnosis CMC.LungCsIANoD +CMC.d888 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputsIIBNosNoD +CMC.d557 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress02IV CMC.LungCs02 +CMC.d718 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCsIIADiagnosis +CMC.d468 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCNoDSum +CMC.d700 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIBScDiagnosis CMC.LungCsIBDiagnosis +CMC.f287 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIIAIIB CMC.LungCsIIANoD +CMC.f475 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCTherapy2 CMC.LungCD +CMC.d868 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputsIIIANsNoD +CMC.f294 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIANoD CMC.LungCProgressIIBIIIA +CMC.d413 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIIAIIIB CMC.LungCProgressIIIAIIIBRate +CMC.d932 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputRelapse CMC.LungCT2Progresses +CMC.d764 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIBNosNoD CMC.LungCsIIIBNoD +CMC.f275 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIBNoD CMC.LungCProgressIAIB +CMC.d803 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured1PopCorr CMC.LungCModelPopCorrectionFactor +CMC.d606 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCsIIADiagnosis +CMC.d724 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCs02Diagnosis +CMC.d691 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs01NsDiagnosis CMC.LungCs01Diagnosis +CMC.d666 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIAScNoD CMC.LungCsIIANoD +CMC.d432 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIVDiagnosis CMC.LungCsIVDiagnosisRate +CMC.d346 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIANoDPopCorr CMC.LungCModelPopCorrectionFactor +CMC.f911 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCTherapy2Failed CMC.LungCD +CMC.d907 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy1 CMC.LungCTherapy1Mortality +CMC.d708 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIBScDiagnosis CMC.LungCsIIIBDiagnosis +CMC.d650 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIVNsNoD CMC.LungCsIVNoD +CMC.d710 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIVScDiagnosis CMC.LungCsIVDiagnosis +CMC.f895 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1Deceased CMC.LungCTherapy1Mortality +CMC.d856 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputHealthyAndTreated CMC.LungCCured1 +CMC.d69 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIANoDAgeing CMC.LungCsIANoD +CMC.d664 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIAScNoD CMC.LungCsIANoD +CMC.d545 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs03 CMC.LungCs03IniVal +CMC.f191 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIANoD CMC.LungCProgressIAIIA +CMC.f224 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1Disabling CMC.LungCT1DisablingPopCorr +CMC.d187 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputModelPop CMC.LungCModelPop +CMC.d646 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIANsNoD CMC.LungCsIIANoD +CMC.d262 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs03PopCorr CMC.LungCs03 +CMC.d79 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTreated1Ageing CMC.LungCNotProgressing1 +CMC.d212 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1ProgToDisabling CMC.LungCT1Progressing +CMC.d352 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIANoDAgeing CMC.LungCsIIIANoD +CMC.d126 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCHealthy +CMC.d251 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs02PopCorr CMC.LungCs02 +CMC.f426 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCsIIIBDiagnosis +CMC.f279 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIBIIB CMC.LungCsIBNoD +CMC.d176 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2DisablingPopCorr CMC.LungCT2Disabling +CMC.d256 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs02Ageing CMC.DummyRateForUnitsConversion +CMC.d810 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy1 CMC.LungCTherapy1CureRatio +CMC.d574 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIBIV CMC.LungCsIIBNoD +CMC.d170 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2ProgressingPopCorr CMC.LungCModelPopCorrectionFactor +CMC.f33 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2Progressing CMC.LungCT2Progresses +CMC.d920 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy2Failed CMC.LungCD +CMC.f428 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCsIVDiagnosis +CMC.d887 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputsIIANosNoD +CMC.d227 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1DisablingPopCorr CMC.LungCModelPopCorrectionFactor +CMC.f26 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCNotProgressing2 CMC.LungCTherapy2 +CMC.d99 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCHealthyAgeing CMC.DummyRateForUnitsConversion +CMC.d566 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIAIV CMC.LungCProgressIAIVRate +CMC.f526 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIBIV CMC.LungCsIBNoD +CMC.d72 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIADiagnosis CMC.LungCsIADiagnosisRate +CMC.d869 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputsIIIANsNoD +CMC.d806 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure1 CMC.LungCFirstTreatmentRate +CMC.d255 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs02Ageing CMC.LungCs02 +CMC.d500 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs02Diagnosis CMC.LungCs02DiagnosisRate +CMC.f790 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCCured1 CMC.LungCTherapyCure1 +CMC.f533 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCProgressIIBIV +CMC.d918 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy2 CMC.LungCTherapy2FailRatio +CMC.d604 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCsIADiagnosis +CMC.d556 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress02IV CMC.LungCProgress02IVRate +CMC.d717 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCsIBDiagnosis +CMC.f232 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs03 CMC.LungCProgress0203 +CMC.d462 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCNotProgressing1 +CMC.d843 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCCured2 +CMC.d815 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputCured1 CMC.LungCCured1 +CMC.d330 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIANoDAgeing CMC.LungCsIIANoD +CMC.f263 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs03 CMC.LungCs03Ageing +CMC.f167 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2Progressing CMC.LungCT2ProgressingPopCorr +CMC.d360 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIBNoDPopCorr CMC.LungCModelPopCorrectionFactor +CMC.d692 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs01ScDiagnosis CMC.LungCs01Diagnosis +CMC.d610 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCsIVDiagnosis +CMC.f514 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgress02IV CMC.LungCs02 +CMC.d931 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputRelapse CMC.LungCT1Progresses +CMC.d725 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCs03Diagnosis +CMC.d663 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs03ScNoD CMC.LungCs03 +CMC.f513 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCProgress02IV +CMC.d854 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy1NoCure CMC.LungCTherapy1 +CMC.f797 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCCured1 CMC.LungCCured1PopCorr +CMC.f510 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgress01IV CMC.LungCs01 +CMC.d549 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIBNoD CMC.LungCsIIBNoDIniVal +CMC.d877 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputsIIAScNoD +CMC.d645 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIBNsNoD CMC.LungCsIBNoD +CMC.f322 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIANoD CMC.LungCsIIANoDPopCorr +CMC.f469 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCDAgeing +CMC.f353 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIBNoD CMC.LungCsIIIBNoDPopCorr +CMC.d575 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIIAIV CMC.LungCProgressIIIAIVRate +CMC.f375 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIBDiagnosis CMC.LungCsIBNoD +CMC.d709 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIVNsDiagnosis CMC.LungCsIVDiagnosis +CMC.d128 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPopCorrectionFactor CMC.LungCCausedDeath +CMC.d589 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNotProgressing2 CMC.LungCNotProgressing2 +CMC.d250 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs02PopCorr CMC.LungCModelPopCorrectionFactor +CMC.f192 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIAIIA CMC.LungCsIANoD +CMC.d303 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIBIIB CMC.LungCsIBNoD +CMC.d614 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy2 CMC.LungCTherapy2 +CMC.d699 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIBNsDiagnosis CMC.LungCsIBDiagnosis +CMC.d501 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs02Diagnosis CMC.LungCs02 +CMC.f278 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIBNoD CMC.LungCProgressIBIIB +CMC.d490 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNotProgressing2 CMC.LungCTreated2IniVal +CMC.f150 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCNotProgressing1 CMC.LungCTreated1PopCorr +CMC.d155 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTreated1PopCorr CMC.LungCNotProgressing1 +CMC.d130 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPopCorrectionFactor CMC.TotalPopulation +CMC.d245 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress03IA CMC.LungCs03 +CMC.d626 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDisabling1 CMC.LungCT1Disabling +CMC.d543 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs01 CMC.LungCs01IniVal +CMC.d583 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy2 CMC.LungCTherapy2Ratio +CMC.f257 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs03 CMC.LungCs03PopCorr +CMC.d782 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIBNosDiagnosis CMC.LungCsIIBDiagnosis +CMC.d85 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2Progresses CMC.LungCNotProgressing2 +CMC.d809 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure1 CMC.LungCTherapy1CureRatio +CMC.f332 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIBNoD CMC.LungCsIIBNoDPopCorr +CMC.f425 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCsIIIADiagnosis +CMC.d745 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCsIVDiagnosis +CMC.f34 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2Progresses CMC.LungCNotProgressing2 +CMC.d832 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure2 CMC.LungCFirstTreatmentRate +CMC.d736 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCs01Diagnosis +CMC.d781 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIANosDiagnosis CMC.LungCsIIADiagnosis +CMC.d603 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCs03Diagnosis +CMC.d828 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure2 CMC.LungCTherapy2Ratio +CMC.d90 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2ProgToDisabling CMC.LungCT2Progressing +CMC.d102 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTreated2Ageing CMC.DummyRateForUnitsConversion +CMC.d565 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress03IV CMC.LungCProgress03IVRate +CMC.d620 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputT2Mortality CMC.LungCT2Death +CMC.d850 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy2NoCure CMC.LungCTherapy2 +CMC.d891 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputsIVNosNoD +CMC.f16 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgress0102 CMC.LungCs01 +CMC.d730 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCsIIIADiagnosis +CMC.d921 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCD CMC.LungCDIniVal +CMC.d55 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCHealthyAgeing CMC.LungCHealthy +CMC.f233 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgress0203 CMC.LungCs02 +CMC.d57 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCInception CMC.LungCInceptionRate +CMC.d368 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIVNoDAgeing CMC.DummyRateForUnitsConversion +CMC.f424 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCsIIADiagnosis +CMC.d872 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputs01ScNoD +CMC.d316 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIBNoDPopCorr CMC.LungCsIBNoD +CMC.d89 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2ProgToDisabling CMC.LungCT2ProgToDisablingRate +CMC.d175 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2DisablingPopCorr CMC.LungCModelPopCorrectionFactor +CMC.f11 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs01 CMC.LungCInception +CMC.d492 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2Progressing CMC.LungCT2ProgressingIniVal +CMC.d347 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIANoDPopCorr CMC.LungCsIIIANoD +CMC.d842 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputCured2 CMC.LungCCured2 +CMC.d665 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIBScNoD CMC.LungCsIBNoD +CMC.f434 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCs03Diagnosis +CMC.d93 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2Death CMC.LungCT2DeathRate +CMC.d899 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy1Mortality CMC.LungCFirstTreatmentRate +CMC.d865 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputsIBNsNoD +CMC.f291 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIIBIIIB CMC.LungCsIIBNoD +CMC.d374 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIVNoDPopCorr CMC.LungCsIVNoD +CMC.d904 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy1 CMC.LungCTherapy1MortalityRatio +CMC.f429 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVDiagnosis CMC.LungCsIVNoD +CMC.d649 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIBNsNoD CMC.LungCsIIIBNoD +CMC.d409 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIAIIIA CMC.LungCProgressIIAIIIARate +CMC.d642 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs02NsNoD CMC.LungCs02 +CMC.d648 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIANsNoD CMC.LungCsIIIANoD +CMC.d886 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputsIBNosNoD +CMC.d585 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2Progresses CMC.LungCT2ProgressesRate +CMC.f327 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIANoD CMC.LungCsIIANoDAgeing +CMC.d727 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCsIBDiagnosis +CMC.d320 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIBNoDAgeing CMC.LungCsIBNoD +CMC.d732 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCsIVDiagnosis +CMC.d811 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured1 CMC.LungCCured1IniVal +CMC.d361 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIBNoDPopCorr CMC.LungCsIIIBNoD +CMC.d465 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCT1Disabling +CMC.d184 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputHealthyAndTreated CMC.LungCNotProgressing1 +CMC.d776 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs01NosDiagnosis CMC.LungCs01Diagnosis +CMC.d894 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputModelPopExcludingHealthy CMC.LungCHealthy +CMC.d131 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPopCorrectionFactor CMC.LungCModelPopCorrectionRate +CMC.d181 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2ProgressingAgeing CMC.LungCT2Progressing +CMC.d385 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIADiagnosis CMC.LungCsIIADiagnosisRate +CMC.f502 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCs01Diagnosis +CMC.d307 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIBIIIA CMC.LungCsIIBNoD +CMC.d801 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured1Ageing CMC.DummyRateForUnitsConversion +CMC.d154 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTreated1PopCorr CMC.LungCModelPopCorrectionFactor +CMC.f830 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCTherapyCure2 CMC.LungCD +CMC.d553 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress01IV CMC.LungCProgress01IVRate +CMC.d747 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs01NosNoD CMC.LungCs01 +CMC.d847 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy2 CMC.LungCTherapyCure2 +CMC.d704 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIBScDiagnosis CMC.LungCsIIBDiagnosis +CMC.d326 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIANoDPopCorr CMC.LungCModelPopCorrectionFactor +CMC.f47 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCBirth CMC.Cloud45 +CMC.d619 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputT1Mortality CMC.LungCT1Death +CMC.f37 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2Disabling CMC.LungCT2ProgToDisabling +CMC.d335 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIBNoDPopCorr CMC.LungCsIIBNoD +CMC.d855 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy1Cure CMC.LungCTherapyCure1 +CMC.d195 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIAIIA CMC.LungCsIANoD +CMC.d698 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIAScDiagnosis CMC.LungCsIADiagnosis +CMC.d554 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress01IV CMC.LungCs01 +CMC.d831 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure2 CMC.LungCD +CMC.f521 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCProgressIAIV +CMC.f162 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCDPopCorr +CMC.d433 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIVDiagnosis CMC.LungCsIVNoD +CMC.d780 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIBNosDiagnosis CMC.LungCsIBDiagnosis +CMC.d880 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputsIIIBScNoD +CMC.d647 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIBNsNoD CMC.LungCsIIBNoD +CMC.d74 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy2 CMC.LungCD +CMC.d440 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs03Diagnosis CMC.LungCs03 +CMC.d890 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputsIIIBNosNoD +CMC.d740 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCsIBDiagnosis +CMC.f299 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIIIAIIIB CMC.LungCsIIIANoD +CMC.d103 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIANoDAgeing CMC.DummyRateForUnitsConversion +CMC.d922 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2Disabling CMC.LungCT2DisablingIniVal +CMC.f201 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1ProgToDisabling CMC.LungCT1Progressing +CMC.d602 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCs02Diagnosis +CMC.d871 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputsIVNsNoD +CMC.f423 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCsIIBDiagnosis +CMC.d719 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCsIIBDiagnosis +CMC.d902 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy1Mortality CMC.LungCTherapy1MortalityRatio +CMC.d827 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured2PopCorr CMC.LungCCured2 +CMC.d91 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT2Death CMC.LungCT2Disabling +CMC.d266 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs03Ageing CMC.LungCs03 +CMC.d467 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCT2Disabling +CMC.d701 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIANsDiagnosis CMC.LungCsIIADiagnosis +CMC.f474 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCTherapy1 CMC.LungCD +CMC.f820 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCCured2 CMC.LungCCured2Ageing +CMC.d867 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputsIIBNsNoD +CMC.f214 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1Progressing CMC.LungCT1ProgressingPopCorr +CMC.f422 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCsIBDiagnosis +CMC.f817 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCCured2 CMC.LungCTherapyCure2 +CMC.d905 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy1Mortality CMC.LungCD +CMC.d97 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy1 CMC.LungCTherapy1Ratio +CMC.f41 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2Deceased CMC.LungCT2Death +CMC.d731 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCsIIIBDiagnosis +CMC.d668 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIAScNoD CMC.LungCsIIIANoD +CMC.f52 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCHealthy CMC.LungCHealthyAgeing +CMC.d302 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIAIB CMC.LungCsIANoD +CMC.d229 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCausedDeath CMC.LungCT1Death +CMC.d866 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputsIIANsNoD +CMC.f910 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2Progressing CMC.LungCTherapy2Failed +CMC.d693 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs02NsDiagnosis CMC.LungCs02Diagnosis +CMC.f503 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs01Diagnosis CMC.LungCs01 +CMC.d315 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIBNoDPopCorr CMC.LungCModelPopCorrectionFactor +CMC.d402 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIBDiagnosis CMC.LungCsIIIBNoD +CMC.d641 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs01NsNoD CMC.LungCs01 +CMC.d893 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputModelPopExcludingHealthy CMC.LungCModelPop +CMC.d576 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIIAIV CMC.LungCsIIIANoD +CMC.d761 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIANosNoD CMC.LungCsIIANoD +CMC.d838 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure2 CMC.LungCTherapy2CureRatio +CMC.d222 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1ProgressingAgeing CMC.LungCT1Progressing +CMC.d616 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputMortality CMC.LungCCausedDeath +CMC.d738 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCs03Diagnosis +CMC.d83 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTreated2Ageing CMC.LungCNotProgressing2 +CMC.d804 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure1 CMC.LungCTherapy1Ratio +CMC.d870 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputsIIIBNsNoD +CMC.d305 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIAIIB CMC.LungCsIIANoD +CMC.f896 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCTherapy1Mortality CMC.LungCD +CMC.d544 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs02 CMC.LungCs02IniVal +CMC.f217 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1Progressing CMC.LungCT1ProgressingAgeing +CMC.d122 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCHealthyPopCorr CMC.LungCHealthy +CMC.d777 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs02NosDiagnosis CMC.LungCs02Diagnosis +CMC.d143 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs01PopCorr CMC.LungCModelPopCorrectionFactor +CMC.d269 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs03Ageing CMC.DummyRateForUnitsConversion +CMC.d464 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCT1Progressing +CMC.d628 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDisabling2 CMC.LungCT2Disabling +CMC.d878 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputsIIBScNoD +CMC.d363 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIBNoDAgeing CMC.DummyRateForUnitsConversion +CMC.f46 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCHealthy CMC.LungCBirth +CMC.d630 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSum CMC.LungCNoDSum +CMC.d183 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputHealthyAndTreated CMC.LungCHealthy +CMC.f518 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgress03IV CMC.LungCs03 +CMC.d472 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCDAgeing CMC.LungCD +CMC.d362 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIBNoDAgeing CMC.LungCsIIIBNoD +CMC.d439 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs03Diagnosis CMC.LungCs03DiagnosisRate +CMC.f317 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIBNoD CMC.LungCsIBNoDAgeing +CMC.d608 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCsIIIADiagnosis +CMC.d132 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPopCorrectionFactor CMC.LungCModelPop +CMC.d411 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIAIIB CMC.LungCProgressIIAIIBRate +CMC.d705 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIANsDiagnosis CMC.LungCsIIIADiagnosis +CMC.f398 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIBDiagnosis CMC.LungCsIIIBNoD +CMC.d836 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured2 CMC.LungCCured2IniVal +CMC.d546 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIANoD CMC.LungCsIANoDIniVal +CMC.d407 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIAIIA CMC.LungCProgressIAIIARate +CMC.f537 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIIIAIV CMC.LungCsIIIANoD +CMC.f522 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIAIV CMC.LungCsIANoD +CMC.d785 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIVNosDiagnosis CMC.LungCsIVDiagnosis +CMC.d587 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNotProgressing1 CMC.LungCNotProgressing1 +CMC.d609 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCsIIIBDiagnosis +CMC.d667 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIBScNoD CMC.LungCsIIBNoD +CMC.d741 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNosDiagnosis CMC.LungCsIIADiagnosis +CMC.f298 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIBNoD CMC.LungCProgressIIIAIIIB +CMC.d95 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy1 CMC.LungCFirstTreatmentRate +CMC.d714 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCs02Diagnosis +CMC.d601 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputDiagnosis CMC.LungCs01Diagnosis +CMC.d243 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress03IA CMC.LungCProgress03IARate +CMC.d779 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIANosDiagnosis CMC.LungCsIADiagnosis +CMC.d551 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIBNoD CMC.LungCsIIIBNoDIniVal +CMC.f529 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIVNoD CMC.LungCProgressIIAIV +CMC.d697 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIANsDiagnosis CMC.LungCsIADiagnosis +CMC.d726 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCsIADiagnosis +CMC.d397 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIADiagnosis CMC.LungCsIIIANoD +CMC.d857 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputHealthyAndTreated CMC.LungCCured2 +CMC.d707 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIBNsDiagnosis CMC.LungCsIIIBDiagnosis +CMC.d65 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress0102 CMC.LungCs01 +CMC.d261 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCs03PopCorr CMC.LungCModelPopCorrectionFactor +CMC.d459 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCsIVNoD +CMC.d321 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIBNoDAgeing CMC.DummyRateForUnitsConversion +CMC.d823 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCCured2Ageing CMC.LungCCured2 +CMC.d903 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure1 CMC.LungCTherapy1MortalityRatio +CMC.f204 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1Deceased CMC.LungCT1Death +CMC.d165 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCDPopCorr CMC.LungCModelPopCorrectionFactor +CMC.d729 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputScDiagnosis CMC.LungCsIIBDiagnosis +CMC.f435 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs03Diagnosis CMC.LungCs03 +CMC.d924 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy2 CMC.LungCTherapy2Failed +CMC.d885 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputsIANosNoD +CMC.d884 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputs03NosNoD +CMC.d228 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1DisablingPopCorr CMC.LungCT1Disabling +CMC.d760 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIBNosNoD CMC.LungCsIBNoD +CMC.d863 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputs03NsNoD +CMC.d749 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs02NosNoD CMC.LungCs02 +CMC.d268 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIANoDPopCorr CMC.LungCModelPopCorrectionFactor +CMC.f172 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2Disabling CMC.LungCT2DisablingPopCorr +CMC.f404 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIAIB CMC.LungCsIANoD +CMC.d223 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1ProgressingAgeing CMC.DummyRateForUnitsConversion +CMC.d613 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy1 CMC.LungCTherapy1 +CMC.d721 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCsIIIBDiagnosis +CMC.f282 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIANoD CMC.LungCProgressIIAIIIA +CMC.d669 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIBScNoD CMC.LungCsIIIBNoD +CMC.d121 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCHealthyPopCorr CMC.LungCModelPopCorrectionFactor +CMC.d702 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIAScDiagnosis CMC.LungCsIIADiagnosis +CMC.d487 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1Progressing CMC.LungCT1ProgressingIniVal +CMC.d873 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputs02ScNoD +CMC.d577 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIIBIV CMC.LungCProgressIIIBIVRate +CMC.d209 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCT1ProgToDisabling CMC.LungCT1ProgToDisablingRate +CMC.f117 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCHealthy CMC.LungCHealthyPopCorr +CMC.d643 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs03NsNoD CMC.LungCs03 +CMC.d455 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCsIIANoD +CMC.f80 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCNotProgressing2 CMC.LungCTreated2Ageing +CMC.d336 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIBNoDPopCorr CMC.LungCModelPopCorrectionFactor +CMC.d457 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCsIIIANoD +CMC.d696 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputs03ScDiagnosis CMC.LungCs03Diagnosis +CMC.d713 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNsDiagnosis CMC.LungCs01Diagnosis +CMC.d879 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDSc CMC.LungCOutputsIIIAScNoD +CMC.d550 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIANoD CMC.LungCsIIIANoDIniVal +CMC.d670 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIVScNoD CMC.LungCsIVNoD +CMC.d419 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIBIIIA CMC.LungCProgressIIBIIIARate +CMC.f290 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIBNoD CMC.LungCProgressIIBIIIB +CMC.d149 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIANoDPopCorr CMC.LungCsIANoD +CMC.d625 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputProgressing1 CMC.LungCT1Progressing +CMC.d304 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIAIIIA CMC.LungCsIIANoD +CMC.d547 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIBNoD CMC.LungCsIBNoDIniVal +CMC.d396 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIADiagnosis CMC.LungCsIIIADiagnosisRate +CMC.f530 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIIAIV CMC.LungCsIIANoD +CMC.f66 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIANoD CMC.LungCsIANoDAgeing +CMC.f19 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCD CMC.LungCsIADiagnosis +CMC.d306 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIBIIIB CMC.LungCsIIBNoD +CMC.d763 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIIANosNoD CMC.LungCsIIIANoD +CMC.d70 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIADiagnosis CMC.LungCsIANoD +CMC.d839 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy2 CMC.LungCTherapy2CureRatio +CMC.f793 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCCured1 CMC.LungCCured1Ageing +CMC.d166 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCDPopCorr CMC.LungCD +CMC.f30 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT1Progresses CMC.LungCNotProgressing1 +CMC.d570 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIBIV CMC.LungCsIBNoD +CMC.d909 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputTherapy1MortalityInTherapy CMC.LungCTherapy1Mortality +CMC.d403 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIIBDiagnosis CMC.LungCsIIIBDiagnosisRate +CMC.d466 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCModelPop CMC.LungCT2Progressing +CMC.f252 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs02 CMC.LungCs02Ageing +CMC.d883 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCoutputNoDNos CMC.LungCOutputs02NosNoD +CMC.f283 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCProgressIIAIIIA CMC.LungCsIIANoD +CMC.d134 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCHealthy CMC.LungCHealthyIniVal +CMC.d75 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy1 CMC.LungCD +CMC.f156 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCNotProgressing2 CMC.LungCTreated2PopCorr +CMC.d421 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgressIIBIIIB CMC.LungCProgressIIBIIIBRate +CMC.f59 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCs01 CMC.LungCs01Ageing +CMC.d450 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCNoDSum CMC.LungCs01 +CMC.d703 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputsIIBNsDiagnosis CMC.LungCsIIBDiagnosis +CMC.d864 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputNoDNs CMC.LungCOutputsIANsNoD +CMC.d900 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapy1Mortality CMC.LungCTherapy1Ratio +CMC.d473 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCDAgeing CMC.DummyRateForUnitsConversion +CMC.d185 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCOutputHealthyAndTreated CMC.LungCNotProgressing2 +CMC.d390 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCsIIBDiagnosis CMC.LungCsIIBNoD +CMC.f356 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCsIIIBNoD CMC.LungCsIIIBNoDAgeing +CMC.f38 : SYSDYN.Flow + @WM.conf_dependency CMC.LungCT2ProgToDisabling CMC.LungCT2Progressing +CMC.d807 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCTherapyCure1 CMC.LungCD +CMC.d242 : SYSDYN.Dependency + @WM.conf_dependency CMC.LungCProgress0203 CMC.LungCProgress0203Rate + +CMC.TotalPopulationT1 : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "delay(TotalPopulation[Gender,Age], 1)" + +CMC.TotalPopulationBirth : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "DummyRateForUnitsConversion*TotalPopulationT1[Gender,Age0]" + +CMC.TotalPopulationMen : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_DATA('LCancer.xls', 'Population_In', '7', 'C113')" + +CMC.OutputDataTotalPopulationMenSum : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(TotalPopulationMen[Age!])" + +CMC.TotalPopulationWomen : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "XLS_DATA('LCancer.xls', 'Population_In', '7', 'C9')" + +CMC.TotalPopulation : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "TotalPopulationMen[Age]" + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "TotalPopulationWomen[Age]" + +CMC.OutputDataTotalPopulationWomenSum : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "sum(TotalPopulationWomen[Age!])" + +CMC.DummyRateForUnitsConversion : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "1" + +CMC.TotalPopulationDeath : SYSDYN.Auxiliary + @L0.tag MOD.Mapped + SYSDYN.HasExpressions _ : SYSDYN.Expressions + @L0.orderedSet + _ : SYSDYN.NormalExpression + SYSDYN.HasEquation "if Age==Age99 then (TotalPopulation[Gender,Age99]+TotalPopulation[Gender,Age100]-TotalPopulationT1[Gender,Age100])/4 elseif Age==Age100 then (TotalPopulation[Gender,Age99]+TotalPopulation[Gender,Age100]-TotalPopulationT1[Gender,Age100])*3/4 else VECTOR_MAP(TotalPopulation[Gender,Age], 0)-VECTOR_MAP(TotalPopulationT1[Gender,Age], 1)*DummyRateForUnitsConversion" + +CMC.d6 : SYSDYN.Dependency + @WM.conf_dependency CMC.TotalPopulationDeath CMC.TotalPopulation +CMC.d21 : SYSDYN.Dependency + @WM.conf_dependency CMC.TotalPopulationDeath CMC.DummyRateForUnitsConversion +CMC.d9 : SYSDYN.Dependency + @WM.conf_dependency CMC.TotalPopulation CMC.TotalPopulationMen +CMC.d17 : SYSDYN.Dependency + @WM.conf_dependency CMC.OutputDataTotalPopulationMenSum CMC.TotalPopulationMen +CMC.d12 : SYSDYN.Dependency + @WM.conf_dependency CMC.TotalPopulationDeath CMC.TotalPopulationT1 +CMC.d20 : SYSDYN.Dependency + @WM.conf_dependency CMC.TotalPopulationBirth CMC.DummyRateForUnitsConversion +CMC.d14 : SYSDYN.Dependency + @WM.conf_dependency CMC.TotalPopulationT1 CMC.TotalPopulation +CMC.d18 : SYSDYN.Dependency + @WM.conf_dependency CMC.OutputDataTotalPopulationWomenSum CMC.TotalPopulationWomen +CMC.d10 : SYSDYN.Dependency + @WM.conf_dependency CMC.TotalPopulation CMC.TotalPopulationWomen +CMC.d13 : SYSDYN.Dependency + @WM.conf_dependency CMC.TotalPopulationBirth CMC.TotalPopulationT1 + +LungCancerConfigurationDiagram : SYSDYN.ConfigurationDiagram + + org.simantics.sysdyn.product.site.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/dev-jkauttio/org.simantics.sysdyn.product.site.feature/Resources.rmap b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/Resources.rmap new file mode 100644 index 00000000..78c416fe --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/Resources.rmap @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.product.site.feature/buckminster.cspex b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/buckminster.cspex new file mode 100644 index 00000000..46e472e2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/buckminster.cspex @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.product.site.feature/buckminster.properties b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/buckminster.properties new file mode 100644 index 00000000..f310dee4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/buckminster.properties @@ -0,0 +1,22 @@ +#buckminster.output.root=c:/simantics-build/site +#buckminster.temp.root=c:/simantics-build/temp + +# How .qualifier in versions should be replaced +qualifier.replacement.*=generator:lastRevision +generator.lastRevision.format=r{0,number,000000} + +# Pack200 compression +#site.pack200=true +#site.retain.unpack=true + +# JAR Signing +#site.signing=true +#signing.type=local +#local.sign=true + +# Generate source bundles +cbi.include.source=false + +target.os=win32 +target.ws=win32 +target.arch=* diff --git a/dev-jkauttio/org.simantics.sysdyn.product.site.feature/build.properties b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/build.properties new file mode 100644 index 00000000..82ab19c6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/dev-jkauttio/org.simantics.sysdyn.product.site.feature/build/product.ant b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/build/product.ant new file mode 100644 index 00000000..9dd09c8c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/build/product.ant @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.product.site.feature/feature.xml b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/feature.xml new file mode 100644 index 00000000..8612af15 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/feature.xml @@ -0,0 +1,24 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.product.site.feature/jenkins.buckminster.script b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/jenkins.buckminster.script new file mode 100644 index 00000000..f7398637 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/jenkins.buckminster.script @@ -0,0 +1,6 @@ +importtargetdefinition -A 'd:/target/3.7.1/target-win.target' +import 'site.cquery' +build +perform -D target.os=* -D target.ws=* -D target.arch=* org.simantics.sysdyn.product.site#site.p2 +perform -D target.os=win32 -D target.ws=win32 -D target.arch=x86 -D p2.profileName=SysdynProfile -D p2.rootId=org.simantics.sysdyn.product.Sysdyn -D build.label=SimanticsSysdyn-b${BUILD_NUMBER}-r${SVN_REVISION} org.simantics.sysdyn.product.site#create.product.zip +perform -D target.os=win32 -D target.ws=win32 -D target.arch=x86_64 -D p2.profileName=SysdynProfile -D p2.rootId=org.simantics.sysdyn.product.Sysdyn -D build.label=SimanticsSysdyn-b${BUILD_NUMBER}-r${SVN_REVISION} org.simantics.sysdyn.product.site#create.product.zip diff --git a/dev-jkauttio/org.simantics.sysdyn.product.site.feature/site.cquery b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/site.cquery new file mode 100644 index 00000000..678b963e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.product.site.feature/site.cquery @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/.classpath b/dev-jkauttio/org.simantics.sysdyn.tests/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/.project b/dev-jkauttio/org.simantics.sysdyn.tests/.project new file mode 100644 index 00000000..0736802b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/.project @@ -0,0 +1,28 @@ + + + org.simantics.sysdyn.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.sysdyn.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..f287d53c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.sysdyn.tests/META-INF/MANIFEST.MF new file mode 100644 index 00000000..62fbacb3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Sysdyn Tests +Bundle-SymbolicName: org.simantics.sysdyn.tests +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.sysdyn.tests.Activator +Require-Bundle: org.simantics.modelica;bundle-version="1.0.0", + org.junit;bundle-version="4.8.2" +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: org.osgi.framework diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/DummyFMU.fmu b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/DummyFMU.fmu new file mode 100644 index 00000000..722d10f7 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/DummyFMU.fmu differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/DummyFile.fmu b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/DummyFile.fmu new file mode 100644 index 00000000..e69de29b diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/DummyFile.txt b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/DummyFile.txt new file mode 100644 index 00000000..e69de29b diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTest.mo b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTest.mo new file mode 100644 index 00000000..078b6c64 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTest.mo @@ -0,0 +1,31 @@ +model FMUAllTypesOfVariablesTestModel + parameter Boolean b = true; + parameter Integer i = 1; + parameter Real r = 1.0; + + Boolean discreteBoolean; + Integer discreteInteger; + Real continuousReal; + + Real valveBoolean; + Real valveInteger; + Real valveReal; + + Real stockBoolean(start=0.0,fixed=true); + Real stockInteger(start=0.0,fixed=true); + Real stockReal(start=0.0,fixed=true); + + parameter Real time = 0; // Time parameter is set at each time step by simulator +equation + discreteBoolean = if initial() or b or not b then (b) else pre(discreteBoolean); + discreteInteger = if initial() or i < 0 or i >= 0 then (i) else pre(discreteInteger); + continuousReal = if initial() or r < 0 or r >= 0 then (r) else pre(continuousReal); + + valveBoolean = if initial() or b or not b then (if b then 1 else -1) else pre(valveBoolean); + valveInteger = if initial() or i < 0 or i >= 0 then (i) else pre(valveInteger); + valveReal = if initial() or r < 0 or r >= 0 then (r) else pre(valveReal); + + der(stockBoolean) = valveBoolean; + der(stockInteger) = valveInteger; + der(stockReal) = valveReal; +end FMUAllTypesOfVariablesTestModel; \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTest.mos b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTest.mos new file mode 100644 index 00000000..bb9dde31 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTest.mos @@ -0,0 +1,2 @@ +loadFile("FMUAllTypesOfVariablesTest.mo"); +translateModelFMU(FMUAllTypesOfVariablesTestModel) \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.c new file mode 100644 index 00000000..2903352a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.c @@ -0,0 +1,530 @@ +/* Simulation code for FMUAllTypesOfVariablesTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ + +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "simulation_runtime.h" +#include "omc_error.h" + +#include +#include + +#include "FMUAllTypesOfVariablesTestModel_functions.h" + +#include "_FMUAllTypesOfVariablesTestModel.h" +#include "FMUAllTypesOfVariablesTestModel_functions.c" +/* dummy VARINFO and FILEINFO */ +const FILE_INFO dummyFILE_INFO = {"",-1,-1,-1,-1,1}; +const VAR_INFO dummyVAR_INFO = {-1,"","",(FILE_INFO){"",-1,-1,-1,-1,1}}; +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _OMC_MEASURE_TIME +int measure_time_flag = 1; +#else +int measure_time_flag = 0; +#endif + +void setupDataStruc(DATA *data) +{ + ASSERT(data,"Error while initialize Data"); + data->modelData.modelName = "FMUAllTypesOfVariablesTestModel"; + data->modelData.modelFilePrefix = "FMUAllTypesOfVariablesTestModel"; + data->modelData.modelDir = ""; + data->modelData.modelGUID = "{e473ffda-4cfa-4ca5-b49b-0c9abe90687b}"; + + data->modelData.nStates = 3; + data->modelData.nVariablesReal = 2*3+4; + data->modelData.nVariablesInteger = 1; + data->modelData.nVariablesBoolean = 1; + data->modelData.nVariablesString = 0; + data->modelData.nParametersReal = 2; + data->modelData.nParametersInteger = 1; + data->modelData.nParametersBoolean = 1; + data->modelData.nParametersString = 0; + data->modelData.nInputVars = 0; + data->modelData.nOutputVars = 0; + data->modelData.nJacobians = 4; + data->modelData.nHelpVars = 0; + + data->modelData.nAliasReal = 0; + data->modelData.nAliasInteger = 0; + data->modelData.nAliasBoolean = 0; + data->modelData.nAliasString = 0; + + data->modelData.nZeroCrossings = 0; + data->modelData.nSamples = 0; + data->modelData.nInitEquations = 0; + data->modelData.nResiduals = 3; + data->modelData.nExtObjs = 0; + data->modelData.nFunctions = 0; + data->modelData.nEquations = 18; + + data->modelData.nDelayExpressions = 0; + +} + +void setupDataStruc2(DATA *data) +{ + const struct FUNCTION_INFO funcInfo[1] = {{-1,"",omc_dummyFileInfo}}; + memcpy(data->modelData.functionNames, &funcInfo, data->modelData.nFunctions*sizeof(FUNCTION_INFO)); + + const VAR_INFO** equationInfo_cref1 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref1[0] = &$PvalveReal__varInfo; + const VAR_INFO** equationInfo_cref3 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref3[0] = &$P$DER$PstockReal__varInfo; + const VAR_INFO** equationInfo_cref5 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref5[0] = &$PvalveInteger__varInfo; + const VAR_INFO** equationInfo_cref7 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref7[0] = &$P$DER$PstockInteger__varInfo; + const VAR_INFO** equationInfo_cref9 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref9[0] = &$PvalveBoolean__varInfo; + const VAR_INFO** equationInfo_cref11 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref11[0] = &$P$DER$PstockBoolean__varInfo; + const VAR_INFO** equationInfo_cref13 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref13[0] = &$PcontinuousReal__varInfo; + const VAR_INFO** equationInfo_cref15 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref15[0] = &$PdiscreteInteger__varInfo; + const VAR_INFO** equationInfo_cref17 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref17[0] = &$PdiscreteBoolean__varInfo; + const struct EQUATION_INFO equationInfo[18] = { + {1012,"SES_ALGORITHM 0", 0, NULL}, + {1013,"SES_SIMPLE_ASSIGN 1",1,equationInfo_cref1}, + {1014,"SES_ALGORITHM 2", 0, NULL}, + {1015,"SES_SIMPLE_ASSIGN 3",1,equationInfo_cref3}, + {1016,"SES_ALGORITHM 4", 0, NULL}, + {1017,"SES_SIMPLE_ASSIGN 5",1,equationInfo_cref5}, + {1018,"SES_ALGORITHM 6", 0, NULL}, + {1019,"SES_SIMPLE_ASSIGN 7",1,equationInfo_cref7}, + {1020,"SES_ALGORITHM 8", 0, NULL}, + {1021,"SES_SIMPLE_ASSIGN 9",1,equationInfo_cref9}, + {1022,"SES_ALGORITHM 10", 0, NULL}, + {1023,"SES_SIMPLE_ASSIGN 11",1,equationInfo_cref11}, + {1024,"SES_ALGORITHM 12", 0, NULL}, + {1025,"SES_SIMPLE_ASSIGN 13",1,equationInfo_cref13}, + {1026,"SES_ALGORITHM 14", 0, NULL}, + {1027,"SES_SIMPLE_ASSIGN 15",1,equationInfo_cref15}, + {1028,"SES_ALGORITHM 16", 0, NULL}, + {1029,"SES_SIMPLE_ASSIGN 17",1,equationInfo_cref17} + }; + const int n_omc_equationInfo_reverse_prof_index = 0; + const int omc_equationInfo_reverse_prof_index[] = { + + }; + memcpy(data->modelData.equationInfo, &equationInfo, data->modelData.nEquations*sizeof(EQUATION_INFO)); + + data->modelData.nProfileBlocks = n_omc_equationInfo_reverse_prof_index; + data->modelData.equationInfo_reverse_prof_index = (int*) malloc(data->modelData.nProfileBlocks*sizeof(int)); + memcpy(data->modelData.equationInfo_reverse_prof_index, omc_equationInfo_reverse_prof_index, data->modelData.nProfileBlocks*sizeof(int)); +} + +/* Has to be performed after _init.xml file has been read */ +void callExternalObjectConstructors(DATA *data) +{ + state mem_state; + mem_state = get_memory_state(); + /* data->simulationInfo.extObjs = NULL; */ +} + +void callExternalObjectDestructors(DATA *data) +{ + if (data->simulationInfo.extObjs) { + free(data->simulationInfo.extObjs); + data->simulationInfo.extObjs = 0; + } +} + + +int input_function(DATA *data) +{ + return 0; +} + +int output_function(DATA *data) +{ + return 0; +} + +/* Initializes the raw time events of the simulation using the now + calcualted parameters. */ +void function_sampleInit(DATA *data) +{ +} + +int function_updateSample(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int function_storeDelayed(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundStartValues(DATA *data) +{ + + + DEBUG_INFO(LOG_INIT, "updating start-values:"); + + return 0; +} + +int initial_residual(DATA *data, double $P$_lambda, double* initialResiduals) +{ + int i = 0; + state mem_state; + + mem_state = get_memory_state(); + DEBUG_INFO(LOG_RES_INIT, "updating initial_residuals:"); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($PstockReal - $P$START$PstockReal)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stockReal - $_start(stockReal)) = %f", i, initialResiduals[i-1]); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($PstockInteger - $P$START$PstockInteger)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stockInteger - $_start(stockInteger)) = %f", i, initialResiduals[i-1]); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($PstockBoolean - $P$START$PstockBoolean)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stockBoolean - $_start(stockBoolean)) = %f", i, initialResiduals[i-1]); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundParameters(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_0(DATA *data) { + modelica_boolean tmp0; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:24:2-24:93]*/ + tmp0 = initial(); + $PvalveBoolean = (((tmp0 || $Pb) || (!$Pb))?($Pb?1.0:-1.0):$P$PRE$PvalveBoolean); + /*#endModelicaLine*/ +} + + +void eqFunction_1(DATA *data) { + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:28:2-28:34]*/ + $P$DER$PstockBoolean = $PvalveBoolean; + /*#endModelicaLine*/ +} + + +void eqFunction_2(DATA *data) { + modelica_boolean tmp1; + modelica_boolean tmp2; + modelica_boolean tmp3; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:25:2-25:80]*/ + tmp1 = initial(); + RELATIONTOZC(tmp2, (modelica_integer)$Pi, (modelica_integer) 0, -1,Less,<); + RELATIONTOZC(tmp3, (modelica_integer)$Pi, (modelica_integer) 0, -1,GreaterEq,>=); + $PvalveInteger = (((tmp1 || tmp2) || tmp3)?((modelica_real)(modelica_integer)$Pi):$P$PRE$PvalveInteger); + /*#endModelicaLine*/ +} + + +void eqFunction_3(DATA *data) { + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:29:2-29:34]*/ + $P$DER$PstockInteger = $PvalveInteger; + /*#endModelicaLine*/ +} + + +void eqFunction_4(DATA *data) { + modelica_boolean tmp4; + modelica_boolean tmp5; + modelica_boolean tmp6; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:26:2-26:74]*/ + tmp4 = initial(); + RELATIONTOZC(tmp5, $Pr, 0.0, -1,Less,<); + RELATIONTOZC(tmp6, $Pr, 0.0, -1,GreaterEq,>=); + $PvalveReal = (((tmp4 || tmp5) || tmp6)?$Pr:$P$PRE$PvalveReal); + /*#endModelicaLine*/ +} + + +void eqFunction_5(DATA *data) { + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:30:2-30:28]*/ + $P$DER$PstockReal = $PvalveReal; + /*#endModelicaLine*/ +} + +static void functionODE_system0(DATA *data,int omc_thread_number) +{ + eqFunction_0(data); + eqFunction_1(data); + eqFunction_2(data); + eqFunction_3(data); + eqFunction_4(data); + eqFunction_5(data); +} +static void (*functionODE_systems[1])(DATA *, int) = { + functionODE_system0 +}; + +void function_initMemoryState() +{ + push_memory_states(1); +} + +int functionODE(DATA *data) +{ + int id,th_id; + state mem_state; /* We need to have separate memory pools for separate systems... */ + mem_state = get_memory_state(); + for (id=0; id<1; id++) { + th_id = omp_get_thread_num(); + functionODE_systems[id](data,th_id); + } + restore_memory_state(mem_state); + + return 0; +} +#include +const char *_omc_force_solver=_OMC_FORCE_SOLVER; +const int inline_work_states_ndims=_OMC_SOLVER_WORK_STATES_NDIMS; +int functionODE_inline(DATA* data, double stepSize) +{ + return 0; +} + + +void eqFunction_6(DATA *data) { + modelica_boolean tmp10; + modelica_boolean tmp11; + modelica_boolean tmp12; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:22:2-22:84]*/ + tmp10 = initial(); + RELATIONTOZC(tmp11, $Pr, 0.0, -1,Less,<); + RELATIONTOZC(tmp12, $Pr, 0.0, -1,GreaterEq,>=); + $PcontinuousReal = (((tmp10 || tmp11) || tmp12)?$Pr:$P$PRE$PcontinuousReal); + /*#endModelicaLine*/ +} + +/* for continuous time variables */ +int functionAlgebraics(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + eqFunction_6(data); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_7(DATA *data) { + modelica_boolean tmp13; + modelica_boolean tmp14; + modelica_boolean tmp15; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:26:2-26:74]*/ + tmp13 = initial(); + SAVEZEROCROSS(tmp14, $Pr, 0.0, -1,Less,<); + SAVEZEROCROSS(tmp15, $Pr, 0.0, -1,GreaterEq,>=); + $PvalveReal = (((tmp13 || tmp14) || tmp15)?$Pr:$P$PRE$PvalveReal); + /*#endModelicaLine*/ +} + + +void eqFunction_8(DATA *data) { + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:30:2-30:28]*/ + $P$DER$PstockReal = $PvalveReal; + /*#endModelicaLine*/ +} + + +void eqFunction_9(DATA *data) { + modelica_boolean tmp16; + modelica_boolean tmp17; + modelica_boolean tmp18; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:25:2-25:80]*/ + tmp16 = initial(); + SAVEZEROCROSS(tmp17, (modelica_integer)$Pi, (modelica_integer) 0, -1,Less,<); + SAVEZEROCROSS(tmp18, (modelica_integer)$Pi, (modelica_integer) 0, -1,GreaterEq,>=); + $PvalveInteger = (((tmp16 || tmp17) || tmp18)?((modelica_real)(modelica_integer)$Pi):$P$PRE$PvalveInteger); + /*#endModelicaLine*/ +} + + +void eqFunction_10(DATA *data) { + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:29:2-29:34]*/ + $P$DER$PstockInteger = $PvalveInteger; + /*#endModelicaLine*/ +} + + +void eqFunction_11(DATA *data) { + modelica_boolean tmp19; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:24:2-24:93]*/ + tmp19 = initial(); + $PvalveBoolean = (((tmp19 || $Pb) || (!$Pb))?($Pb?1.0:-1.0):$P$PRE$PvalveBoolean); + /*#endModelicaLine*/ +} + + +void eqFunction_12(DATA *data) { + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:28:2-28:34]*/ + $P$DER$PstockBoolean = $PvalveBoolean; + /*#endModelicaLine*/ +} + + +void eqFunction_13(DATA *data) { + modelica_boolean tmp20; + modelica_boolean tmp21; + modelica_boolean tmp22; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:22:2-22:84]*/ + tmp20 = initial(); + SAVEZEROCROSS(tmp21, $Pr, 0.0, -1,Less,<); + SAVEZEROCROSS(tmp22, $Pr, 0.0, -1,GreaterEq,>=); + $PcontinuousReal = (((tmp20 || tmp21) || tmp22)?$Pr:$P$PRE$PcontinuousReal); + /*#endModelicaLine*/ +} + + +void eqFunction_14(DATA *data) { + modelica_boolean tmp23; + modelica_boolean tmp24; + modelica_boolean tmp25; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:21:2-21:86]*/ + tmp23 = initial(); + SAVEZEROCROSS(tmp24, (modelica_integer)$Pi, (modelica_integer) 0, -1,Less,<); + SAVEZEROCROSS(tmp25, (modelica_integer)$Pi, (modelica_integer) 0, -1,GreaterEq,>=); + $PdiscreteInteger = (((tmp23 || tmp24) || tmp25)?(modelica_integer)$Pi:$P$PRE$PdiscreteInteger); + /*#endModelicaLine*/ +} + + +void eqFunction_15(DATA *data) { + modelica_boolean tmp26; + /*#modelicaLine [FMUAllTypesOfVariablesTest.mo:20:2-20:81]*/ + tmp26 = initial(); + $PdiscreteBoolean = (((tmp26 || $Pb) || (!$Pb))?$Pb:$P$PRE$PdiscreteBoolean); + /*#endModelicaLine*/ +} + +int functionDAE(DATA *data, int *needToIterate) +{ + state mem_state; + *needToIterate = 0; + + mem_state = get_memory_state(); + eqFunction_7(data); + eqFunction_8(data); + eqFunction_9(data); + eqFunction_10(data); + eqFunction_11(data); + eqFunction_12(data); + eqFunction_13(data); + eqFunction_14(data); + eqFunction_15(data); + restore_memory_state(mem_state); + + return 0; +} + +int function_onlyZeroCrossings(DATA *data, double *gout,double *t) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int checkForDiscreteChanges(DATA *data) +{ + int needToIterate = 0; + + if ($PdiscreteBoolean != $P$PRE$PdiscreteBoolean) { DEBUG_INFO2(LOG_EVENTS,"Discrete Var discreteBoolean : %d to %d", $P$PRE$PdiscreteBoolean, $PdiscreteBoolean); needToIterate=1; } + if ($PdiscreteInteger != $P$PRE$PdiscreteInteger) { DEBUG_INFO2(LOG_EVENTS,"Discrete Var discreteInteger : %ld to %ld", $P$PRE$PdiscreteInteger, $PdiscreteInteger); needToIterate=1; } + + return needToIterate; +} + +/* function to check assert after a step is done */ +int checkForAsserts(DATA *data) +{ + + + return 0; +} + + int initialAnalyticJacobianA(DATA* data){ + return 1; + } + + int initialAnalyticJacobianB(DATA* data){ + return 1; + } + + int initialAnalyticJacobianC(DATA* data){ + return 1; + } + + int initialAnalyticJacobianD(DATA* data){ + return 1; + } + int functionJacA(DATA* data, double* jac){ + return 0; + } + + int functionJacB(DATA* data, double* jac){ + return 0; + } + + int functionJacC(DATA* data, double* jac){ + return 0; + } + + int functionJacD(DATA* data, double* jac){ + return 0; + } + +const char *linear_model_frame = + "model linear_FMUAllTypesOfVariablesTestModel\n parameter Integer n = 3; // states \n parameter Integer k = 0; // top-level inputs \n parameter Integer l = 0; // top-level outputs \n" + " parameter Real x0[3] = {%s};\n" + " parameter Real u0[0] = {%s};\n" + " parameter Real A[3,3] = [%s];\n" + " parameter Real B[3,0] = zeros(3,0);%s\n" + " parameter Real C[0,3] = zeros(0,3);%s\n" + " parameter Real D[0,0] = zeros(0,0);%s\n" + " Real x[3](start=x0);\n" + " input Real u[0];\n" + " output Real y[0];\n" + "\n Real x_PstockBoolean = x[1];\n Real x_PstockInteger = x[2];\n Real x_PstockReal = x[3];\n \n" + "equation\n der(x) = A * x + B * u;\n y = C * x + D * u;\nend linear_FMUAllTypesOfVariablesTestModel;\n" +; + +#ifdef __cplusplus +} +#endif + +/* forward the main in the simulation runtime */ +extern int _main_SimulationRuntime(int argc, char**argv, DATA *data); + +/* call the simulation runtime main from our main! */ +int main(int argc, char**argv) +{ + DATA data; + setupDataStruc(&data); + return _main_SimulationRuntime(argc, argv, &data); +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.dll b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.dll new file mode 100644 index 00000000..09daf82a Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.dll differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.fmu b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.fmu new file mode 100644 index 00000000..330c53a0 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.fmu differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.lib b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.lib new file mode 100644 index 00000000..293de438 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel.lib differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_FMU.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_FMU.c new file mode 100644 index 00000000..0199232d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_FMU.c @@ -0,0 +1,202 @@ + +// define class name and unique id +#define MODEL_IDENTIFIER FMUAllTypesOfVariablesTestModel +#define MODEL_GUID "{e473ffda-4cfa-4ca5-b49b-0c9abe90687b}" + +// include fmu header files, typedefs and macros +#include +#include +#include +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "omc_error.h" +#include "fmiModelTypes.h" +#include "fmiModelFunctions.h" +#include "FMUAllTypesOfVariablesTestModel_functions.h" +#include "initialization.h" +#include "events.h" +#include "fmu_model_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void setStartValues(ModelInstance *comp); +void setDefaultStartValues(ModelInstance *comp); +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo); +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value); +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value); +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value); +fmiString getString(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value); + +// define model size +#define NUMBER_OF_STATES 3 +#define NUMBER_OF_EVENT_INDICATORS 0 +#define NUMBER_OF_REALS 12 +#define NUMBER_OF_INTEGERS 2 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_BOOLEANS 2 +#define NUMBER_OF_EXTERNALFUNCTIONS 0 + +// define variable data for model +#define $PstockBoolean_ 0 +#define $PstockInteger_ 1 +#define $PstockReal_ 2 +#define $P$DER$PstockBoolean_ 3 +#define $P$DER$PstockInteger_ 4 +#define $P$DER$PstockReal_ 5 +#define $PcontinuousReal_ 6 +#define $PvalveBoolean_ 7 +#define $PvalveInteger_ 8 +#define $PvalveReal_ 9 +#define $Pr_ 10 +#define time_ 11 +#define $PdiscreteInteger_ 0 +#define $Pi_ 1 +#define $PdiscreteBoolean_ 0 +#define $Pb_ 1 + + +// define initial state vector as vector of value references +#define STATES { $PstockBoolean_, $PstockInteger_, $PstockReal_ } +#define STATESDERIVATIVES { $P$DER$PstockBoolean_, $P$DER$PstockInteger_, $P$DER$PstockReal_ } + + +// implementation of the Model Exchange functions +#include "fmu_model_interface.c" + +// Set values for all variables that define a start value +void setDefaultStartValues(ModelInstance *comp) { + +comp->fmuData->modelData.realVarsData[0].attribute.start = 0.0; +comp->fmuData->modelData.realVarsData[1].attribute.start = 0.0; +comp->fmuData->modelData.realVarsData[2].attribute.start = 0.0; +comp->fmuData->modelData.realParameterData[0].attribute.start = 1.0; +comp->fmuData->modelData.realParameterData[1].attribute.start = 0.0; +comp->fmuData->modelData.integerParameterData[0].attribute.start = 1; +comp->fmuData->modelData.booleanParameterData[0].attribute.start = 1; +} +// Set values for all variables that define a start value +void setStartValues(ModelInstance *comp) { + + comp->fmuData->modelData.realVarsData[0].attribute.start = comp->fmuData->localData[0]->realVars[0]; + comp->fmuData->modelData.realVarsData[1].attribute.start = comp->fmuData->localData[0]->realVars[1]; + comp->fmuData->modelData.realVarsData[2].attribute.start = comp->fmuData->localData[0]->realVars[2]; + comp->fmuData->modelData.realVarsData[3].attribute.start = comp->fmuData->localData[0]->realVars[3]; + comp->fmuData->modelData.realVarsData[4].attribute.start = comp->fmuData->localData[0]->realVars[4]; + comp->fmuData->modelData.realVarsData[5].attribute.start = comp->fmuData->localData[0]->realVars[5]; + comp->fmuData->modelData.realVarsData[6].attribute.start = comp->fmuData->localData[0]->realVars[6]; + comp->fmuData->modelData.realVarsData[7].attribute.start = comp->fmuData->localData[0]->realVars[7]; + comp->fmuData->modelData.realVarsData[8].attribute.start = comp->fmuData->localData[0]->realVars[8]; + comp->fmuData->modelData.realVarsData[9].attribute.start = comp->fmuData->localData[0]->realVars[9]; + comp->fmuData->modelData.integerVarsData[0].attribute.start = comp->fmuData->localData[0]->integerVars[0]; + comp->fmuData->modelData.booleanVarsData[0].attribute.start = comp->fmuData->localData[0]->booleanVars[0]; +comp->fmuData->modelData.realParameterData[0].attribute.start = comp->fmuData->simulationInfo.realParameter[0]; +comp->fmuData->modelData.realParameterData[1].attribute.start = comp->fmuData->simulationInfo.realParameter[1]; +comp->fmuData->modelData.integerParameterData[0].attribute.start = comp->fmuData->simulationInfo.integerParameter[0]; +comp->fmuData->modelData.booleanParameterData[0].attribute.start = comp->fmuData->simulationInfo.booleanParameter[0]; +} +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $PstockBoolean_ : return comp->fmuData->localData[0]->realVars[0]; break; + case $PstockInteger_ : return comp->fmuData->localData[0]->realVars[1]; break; + case $PstockReal_ : return comp->fmuData->localData[0]->realVars[2]; break; + case $P$DER$PstockBoolean_ : return comp->fmuData->localData[0]->realVars[3]; break; + case $P$DER$PstockInteger_ : return comp->fmuData->localData[0]->realVars[4]; break; + case $P$DER$PstockReal_ : return comp->fmuData->localData[0]->realVars[5]; break; + case $PcontinuousReal_ : return comp->fmuData->localData[0]->realVars[6]; break; + case $PvalveBoolean_ : return comp->fmuData->localData[0]->realVars[7]; break; + case $PvalveInteger_ : return comp->fmuData->localData[0]->realVars[8]; break; + case $PvalveReal_ : return comp->fmuData->localData[0]->realVars[9]; break; + case $Pr_ : return comp->fmuData->simulationInfo.realParameter[0]; break; + case time_ : return comp->fmuData->simulationInfo.realParameter[1]; break; + default: + return fmiError; + } +} + +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value) { + switch (vr) { + case $PstockBoolean_ : comp->fmuData->localData[0]->realVars[0]=value; break; + case $PstockInteger_ : comp->fmuData->localData[0]->realVars[1]=value; break; + case $PstockReal_ : comp->fmuData->localData[0]->realVars[2]=value; break; + case $P$DER$PstockBoolean_ : comp->fmuData->localData[0]->realVars[3]=value; break; + case $P$DER$PstockInteger_ : comp->fmuData->localData[0]->realVars[4]=value; break; + case $P$DER$PstockReal_ : comp->fmuData->localData[0]->realVars[5]=value; break; + case $PcontinuousReal_ : comp->fmuData->localData[0]->realVars[6]=value; break; + case $PvalveBoolean_ : comp->fmuData->localData[0]->realVars[7]=value; break; + case $PvalveInteger_ : comp->fmuData->localData[0]->realVars[8]=value; break; + case $PvalveReal_ : comp->fmuData->localData[0]->realVars[9]=value; break; + case $Pr_ : comp->fmuData->simulationInfo.realParameter[0]=value; break; + case time_ : comp->fmuData->simulationInfo.realParameter[1]=value; break; + default: + return fmiError; + } + return fmiOK; +} + +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $PdiscreteInteger_ : return comp->fmuData->localData[0]->integerVars[0]; break; + case $Pi_ : return comp->fmuData->simulationInfo.integerParameter[0]; break; + default: + return 0; + } +} +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value) { + switch (vr) { + case $PdiscreteInteger_ : comp->fmuData->localData[0]->integerVars[0]=value; break; + case $Pi_ : comp->fmuData->simulationInfo.integerParameter[0]=value; break; + default: + return fmiError; + } + return fmiOK; +} +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $PdiscreteBoolean_ : return comp->fmuData->localData[0]->booleanVars[0]; break; + case $Pb_ : return comp->fmuData->simulationInfo.booleanParameter[0]; break; + default: + return 0; + } +} + +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value) { + switch (vr) { + case $PdiscreteBoolean_ : comp->fmuData->localData[0]->booleanVars[0]=value; break; + case $Pb_ : comp->fmuData->simulationInfo.booleanParameter[0]=value; break; + default: + return fmiError; + } + return fmiOK; +} + +fmiString getString(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} + +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value){ + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} + + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_functions.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_functions.c new file mode 100644 index 00000000..005d4693 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_functions.c @@ -0,0 +1,16 @@ +#include "FMUAllTypesOfVariablesTestModel_functions.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define _OMC_LIT0_data "'p" +static const size_t _OMC_LIT0_strlen = 2; +static const char _OMC_LIT0[3] = _OMC_LIT0_data; +#define _OMC_LIT1_data "'p/s" +static const size_t _OMC_LIT1_strlen = 4; +static const char _OMC_LIT1[5] = _OMC_LIT1_data; + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_functions.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_functions.h new file mode 100644 index 00000000..cf5bf6b8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_functions.h @@ -0,0 +1,17 @@ +#ifndef FMUAllTypesOfVariablesTestModel__H +#define FMUAllTypesOfVariablesTestModel__H +#define omp_get_thread_num() 0 +#include "modelica.h" +#include +#include +#include +#include "simulation_runtime.h" +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_records.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_records.c new file mode 100644 index 00000000..f4e92f38 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/FMUAllTypesOfVariablesTestModel_records.c @@ -0,0 +1,3 @@ +/* Additional record code for FMUAllTypesOfVariablesTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#include "meta_modelica.h" + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/_FMUAllTypesOfVariablesTestModel.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/_FMUAllTypesOfVariablesTestModel.h new file mode 100644 index 00000000..7cbac250 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/_FMUAllTypesOfVariablesTestModel.h @@ -0,0 +1,88 @@ +/* Simulation code for FMUAllTypesOfVariablesTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#define time data->localData[0]->timeValue + +/* States */ +#define _$PstockBoolean(i) data->localData[i]->realVars[0] +#define $PstockBoolean _$PstockBoolean(0) +#define $P$PRE$PstockBoolean data->simulationInfo.realVarsPre[0] +#define $P$START$PstockBoolean data->modelData.realVarsData[0].attribute.start +#define $PstockBoolean__varInfo data->modelData.realVarsData[0].info +#define _$PstockInteger(i) data->localData[i]->realVars[1] +#define $PstockInteger _$PstockInteger(0) +#define $P$PRE$PstockInteger data->simulationInfo.realVarsPre[1] +#define $P$START$PstockInteger data->modelData.realVarsData[1].attribute.start +#define $PstockInteger__varInfo data->modelData.realVarsData[1].info +#define _$PstockReal(i) data->localData[i]->realVars[2] +#define $PstockReal _$PstockReal(0) +#define $P$PRE$PstockReal data->simulationInfo.realVarsPre[2] +#define $P$START$PstockReal data->modelData.realVarsData[2].attribute.start +#define $PstockReal__varInfo data->modelData.realVarsData[2].info +/* StatesDerivatives */ +#define _$P$DER$PstockBoolean(i) data->localData[i]->realVars[3] +#define $P$DER$PstockBoolean _$P$DER$PstockBoolean(0) +#define $P$PRE$P$DER$PstockBoolean data->simulationInfo.realVarsPre[3] +#define $P$START$P$DER$PstockBoolean data->modelData.realVarsData[3].attribute.start +#define $P$DER$PstockBoolean__varInfo data->modelData.realVarsData[3].info +#define _$P$DER$PstockInteger(i) data->localData[i]->realVars[4] +#define $P$DER$PstockInteger _$P$DER$PstockInteger(0) +#define $P$PRE$P$DER$PstockInteger data->simulationInfo.realVarsPre[4] +#define $P$START$P$DER$PstockInteger data->modelData.realVarsData[4].attribute.start +#define $P$DER$PstockInteger__varInfo data->modelData.realVarsData[4].info +#define _$P$DER$PstockReal(i) data->localData[i]->realVars[5] +#define $P$DER$PstockReal _$P$DER$PstockReal(0) +#define $P$PRE$P$DER$PstockReal data->simulationInfo.realVarsPre[5] +#define $P$START$P$DER$PstockReal data->modelData.realVarsData[5].attribute.start +#define $P$DER$PstockReal__varInfo data->modelData.realVarsData[5].info +/* Algebraic Vars */ +#define _$PcontinuousReal(i) data->localData[i]->realVars[6] +#define $PcontinuousReal _$PcontinuousReal(0) +#define $P$PRE$PcontinuousReal data->simulationInfo.realVarsPre[6] +#define $P$START$PcontinuousReal data->modelData.realVarsData[6].attribute.start +#define $PcontinuousReal__varInfo data->modelData.realVarsData[6].info +#define _$PvalveBoolean(i) data->localData[i]->realVars[7] +#define $PvalveBoolean _$PvalveBoolean(0) +#define $P$PRE$PvalveBoolean data->simulationInfo.realVarsPre[7] +#define $P$START$PvalveBoolean data->modelData.realVarsData[7].attribute.start +#define $PvalveBoolean__varInfo data->modelData.realVarsData[7].info +#define _$PvalveInteger(i) data->localData[i]->realVars[8] +#define $PvalveInteger _$PvalveInteger(0) +#define $P$PRE$PvalveInteger data->simulationInfo.realVarsPre[8] +#define $P$START$PvalveInteger data->modelData.realVarsData[8].attribute.start +#define $PvalveInteger__varInfo data->modelData.realVarsData[8].info +#define _$PvalveReal(i) data->localData[i]->realVars[9] +#define $PvalveReal _$PvalveReal(0) +#define $P$PRE$PvalveReal data->simulationInfo.realVarsPre[9] +#define $P$START$PvalveReal data->modelData.realVarsData[9].attribute.start +#define $PvalveReal__varInfo data->modelData.realVarsData[9].info +/* Algebraic Parameter */ +#define $Pr data->simulationInfo.realParameter[0] +#define $P$START$Pr data->modelData.realParameterData[0].attribute.start +#define $Pr__varInfo data->modelData.realParameterData[0].info +#define time data->simulationInfo.realParameter[1] +#define $P$STARTtime data->modelData.realParameterData[1].attribute.start +#define time__varInfo data->modelData.realParameterData[1].info +/* External Objects */ +/* Algebraic Integer Vars */ +#define _$PdiscreteInteger(i) data->localData[i]->integerVars[0] +#define $PdiscreteInteger _$PdiscreteInteger(0) +#define $P$PRE$PdiscreteInteger data->simulationInfo.integerVarsPre[0] +#define $P$START$PdiscreteInteger data->modelData.integerVarsData[0].attribute.start +#define $PdiscreteInteger__varInfo data->modelData.integerVarsData[0].info +/* Algebraic Integer Parameter */ +#define $Pi data->simulationInfo.integerParameter[0] +#define $P$START$Pi data->modelData.integerParameterData[0].attribute.start +#define $Pi__varInfo data->modelData.integerParameterData[0].info +/* Algebraic Boolean Vars */ +#define _$PdiscreteBoolean(i) data->localData[i]->booleanVars[0] +#define $PdiscreteBoolean _$PdiscreteBoolean(0) +#define $P$PRE$PdiscreteBoolean data->simulationInfo.booleanVarsPre[0] +#define $P$START$PdiscreteBoolean data->modelData.booleanVarsData[0].attribute.start +#define $PdiscreteBoolean__varInfo data->modelData.booleanVarsData[0].info +/* Algebraic Boolean Parameters */ +#define $Pb data->simulationInfo.booleanParameter[0] +#define $P$START$Pb data->modelData.booleanParameterData[0].attribute.start +#define $Pb__varInfo data->modelData.booleanParameterData[0].info +/* Algebraic String Variables */ +/* Algebraic String Parameter */ +/* Jacobian Variables */ + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/modelDescription.xml b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/modelDescription.xml new file mode 100644 index 00000000..8dd28af7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUAllTypesOfVariablesTest/modelDescription.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTest.mo b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTest.mo new file mode 100644 index 00000000..b9885386 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTest.mo @@ -0,0 +1,9 @@ +model FMUBooleanTestModel + parameter Boolean b = true; + Real valve; + Real stock(start=0.0,fixed=true); + parameter Real time = 0; // Time parameter is set at each time step by simulator +equation + valve = if initial() or b or not b then (if b then 1 else -1) else pre(valve); + der(stock) = valve; +end FMUBooleanTestModel; \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTest.mos b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTest.mos new file mode 100644 index 00000000..cd93a4b8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTest.mos @@ -0,0 +1,2 @@ +loadFile("FMUBooleanTest.mo"); +translateModelFMU(FMUBooleanTestModel) \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.c new file mode 100644 index 00000000..08256106 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.c @@ -0,0 +1,356 @@ +/* Simulation code for FMUBooleanTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ + +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "simulation_runtime.h" +#include "omc_error.h" + +#include +#include + +#include "FMUBooleanTestModel_functions.h" + +#include "_FMUBooleanTestModel.h" +#include "FMUBooleanTestModel_functions.c" +/* dummy VARINFO and FILEINFO */ +const FILE_INFO dummyFILE_INFO = {"",-1,-1,-1,-1,1}; +const VAR_INFO dummyVAR_INFO = {-1,"","",(FILE_INFO){"",-1,-1,-1,-1,1}}; +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _OMC_MEASURE_TIME +int measure_time_flag = 1; +#else +int measure_time_flag = 0; +#endif + +void setupDataStruc(DATA *data) +{ + ASSERT(data,"Error while initialize Data"); + data->modelData.modelName = "FMUBooleanTestModel"; + data->modelData.modelFilePrefix = "FMUBooleanTestModel"; + data->modelData.modelDir = ""; + data->modelData.modelGUID = "{3286e2d9-75aa-4917-9a7e-69e4959910a6}"; + + data->modelData.nStates = 1; + data->modelData.nVariablesReal = 2*1+1; + data->modelData.nVariablesInteger = 0; + data->modelData.nVariablesBoolean = 0; + data->modelData.nVariablesString = 0; + data->modelData.nParametersReal = 1; + data->modelData.nParametersInteger = 0; + data->modelData.nParametersBoolean = 1; + data->modelData.nParametersString = 0; + data->modelData.nInputVars = 0; + data->modelData.nOutputVars = 0; + data->modelData.nJacobians = 4; + data->modelData.nHelpVars = 0; + + data->modelData.nAliasReal = 0; + data->modelData.nAliasInteger = 0; + data->modelData.nAliasBoolean = 0; + data->modelData.nAliasString = 0; + + data->modelData.nZeroCrossings = 0; + data->modelData.nSamples = 0; + data->modelData.nInitEquations = 0; + data->modelData.nResiduals = 1; + data->modelData.nExtObjs = 0; + data->modelData.nFunctions = 0; + data->modelData.nEquations = 4; + + data->modelData.nDelayExpressions = 0; + +} + +void setupDataStruc2(DATA *data) +{ + const struct FUNCTION_INFO funcInfo[1] = {{-1,"",omc_dummyFileInfo}}; + memcpy(data->modelData.functionNames, &funcInfo, data->modelData.nFunctions*sizeof(FUNCTION_INFO)); + + const VAR_INFO** equationInfo_cref1 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref1[0] = &$Pvalve__varInfo; + const VAR_INFO** equationInfo_cref3 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref3[0] = &$P$DER$Pstock__varInfo; + const struct EQUATION_INFO equationInfo[4] = { + {1003,"SES_ALGORITHM 0", 0, NULL}, + {1004,"SES_SIMPLE_ASSIGN 1",1,equationInfo_cref1}, + {1005,"SES_ALGORITHM 2", 0, NULL}, + {1006,"SES_SIMPLE_ASSIGN 3",1,equationInfo_cref3} + }; + const int n_omc_equationInfo_reverse_prof_index = 0; + const int omc_equationInfo_reverse_prof_index[] = { + + }; + memcpy(data->modelData.equationInfo, &equationInfo, data->modelData.nEquations*sizeof(EQUATION_INFO)); + + data->modelData.nProfileBlocks = n_omc_equationInfo_reverse_prof_index; + data->modelData.equationInfo_reverse_prof_index = (int*) malloc(data->modelData.nProfileBlocks*sizeof(int)); + memcpy(data->modelData.equationInfo_reverse_prof_index, omc_equationInfo_reverse_prof_index, data->modelData.nProfileBlocks*sizeof(int)); +} + +/* Has to be performed after _init.xml file has been read */ +void callExternalObjectConstructors(DATA *data) +{ + state mem_state; + mem_state = get_memory_state(); + /* data->simulationInfo.extObjs = NULL; */ +} + +void callExternalObjectDestructors(DATA *data) +{ + if (data->simulationInfo.extObjs) { + free(data->simulationInfo.extObjs); + data->simulationInfo.extObjs = 0; + } +} + + +int input_function(DATA *data) +{ + return 0; +} + +int output_function(DATA *data) +{ + return 0; +} + +/* Initializes the raw time events of the simulation using the now + calcualted parameters. */ +void function_sampleInit(DATA *data) +{ +} + +int function_updateSample(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int function_storeDelayed(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundStartValues(DATA *data) +{ + + + DEBUG_INFO(LOG_INIT, "updating start-values:"); + + return 0; +} + +int initial_residual(DATA *data, double $P$_lambda, double* initialResiduals) +{ + int i = 0; + state mem_state; + + mem_state = get_memory_state(); + DEBUG_INFO(LOG_RES_INIT, "updating initial_residuals:"); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($Pstock - $P$START$Pstock)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stock - $_start(stock)) = %f", i, initialResiduals[i-1]); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundParameters(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_0(DATA *data) { + modelica_boolean tmp0; + /*#modelicaLine [FMUBooleanTest.mo:7:2-7:79]*/ + tmp0 = initial(); + $Pvalve = (((tmp0 || $Pb) || (!$Pb))?($Pb?1.0:-1.0):$P$PRE$Pvalve); + /*#endModelicaLine*/ +} + + +void eqFunction_1(DATA *data) { + /*#modelicaLine [FMUBooleanTest.mo:8:2-8:20]*/ + $P$DER$Pstock = $Pvalve; + /*#endModelicaLine*/ +} + +static void functionODE_system0(DATA *data,int omc_thread_number) +{ + eqFunction_0(data); + eqFunction_1(data); +} +static void (*functionODE_systems[1])(DATA *, int) = { + functionODE_system0 +}; + +void function_initMemoryState() +{ + push_memory_states(1); +} + +int functionODE(DATA *data) +{ + int id,th_id; + state mem_state; /* We need to have separate memory pools for separate systems... */ + mem_state = get_memory_state(); + for (id=0; id<1; id++) { + th_id = omp_get_thread_num(); + functionODE_systems[id](data,th_id); + } + restore_memory_state(mem_state); + + return 0; +} +#include +const char *_omc_force_solver=_OMC_FORCE_SOLVER; +const int inline_work_states_ndims=_OMC_SOLVER_WORK_STATES_NDIMS; +int functionODE_inline(DATA* data, double stepSize) +{ + return 0; +} + +/* for continuous time variables */ +int functionAlgebraics(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_2(DATA *data) { + modelica_boolean tmp2; + /*#modelicaLine [FMUBooleanTest.mo:7:2-7:79]*/ + tmp2 = initial(); + $Pvalve = (((tmp2 || $Pb) || (!$Pb))?($Pb?1.0:-1.0):$P$PRE$Pvalve); + /*#endModelicaLine*/ +} + + +void eqFunction_3(DATA *data) { + /*#modelicaLine [FMUBooleanTest.mo:8:2-8:20]*/ + $P$DER$Pstock = $Pvalve; + /*#endModelicaLine*/ +} + +int functionDAE(DATA *data, int *needToIterate) +{ + state mem_state; + *needToIterate = 0; + + mem_state = get_memory_state(); + eqFunction_2(data); + eqFunction_3(data); + restore_memory_state(mem_state); + + return 0; +} + +int function_onlyZeroCrossings(DATA *data, double *gout,double *t) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int checkForDiscreteChanges(DATA *data) +{ + int needToIterate = 0; + + + return needToIterate; +} + +/* function to check assert after a step is done */ +int checkForAsserts(DATA *data) +{ + + + return 0; +} + + int initialAnalyticJacobianA(DATA* data){ + return 1; + } + + int initialAnalyticJacobianB(DATA* data){ + return 1; + } + + int initialAnalyticJacobianC(DATA* data){ + return 1; + } + + int initialAnalyticJacobianD(DATA* data){ + return 1; + } + int functionJacA(DATA* data, double* jac){ + return 0; + } + + int functionJacB(DATA* data, double* jac){ + return 0; + } + + int functionJacC(DATA* data, double* jac){ + return 0; + } + + int functionJacD(DATA* data, double* jac){ + return 0; + } + +const char *linear_model_frame = + "model linear_FMUBooleanTestModel\n parameter Integer n = 1; // states \n parameter Integer k = 0; // top-level inputs \n parameter Integer l = 0; // top-level outputs \n" + " parameter Real x0[1] = {%s};\n" + " parameter Real u0[0] = {%s};\n" + " parameter Real A[1,1] = [%s];\n" + " parameter Real B[1,0] = zeros(1,0);%s\n" + " parameter Real C[0,1] = zeros(0,1);%s\n" + " parameter Real D[0,0] = zeros(0,0);%s\n" + " Real x[1](start=x0);\n" + " input Real u[0];\n" + " output Real y[0];\n" + "\n Real x_Pstock = x[1];\n \n" + "equation\n der(x) = A * x + B * u;\n y = C * x + D * u;\nend linear_FMUBooleanTestModel;\n" +; + +#ifdef __cplusplus +} +#endif + +/* forward the main in the simulation runtime */ +extern int _main_SimulationRuntime(int argc, char**argv, DATA *data); + +/* call the simulation runtime main from our main! */ +int main(int argc, char**argv) +{ + DATA data; + setupDataStruc(&data); + return _main_SimulationRuntime(argc, argv, &data); +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.dll b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.dll new file mode 100644 index 00000000..13767711 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.dll differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.fmu b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.fmu new file mode 100644 index 00000000..4da6ff81 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.fmu differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.lib b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.lib new file mode 100644 index 00000000..734ec893 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel.lib differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_FMU.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_FMU.c new file mode 100644 index 00000000..0cc1a91a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_FMU.c @@ -0,0 +1,154 @@ + +// define class name and unique id +#define MODEL_IDENTIFIER FMUBooleanTestModel +#define MODEL_GUID "{3286e2d9-75aa-4917-9a7e-69e4959910a6}" + +// include fmu header files, typedefs and macros +#include +#include +#include +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "omc_error.h" +#include "fmiModelTypes.h" +#include "fmiModelFunctions.h" +#include "FMUBooleanTestModel_functions.h" +#include "initialization.h" +#include "events.h" +#include "fmu_model_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void setStartValues(ModelInstance *comp); +void setDefaultStartValues(ModelInstance *comp); +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo); +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value); +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value); +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value); +fmiString getString(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value); + +// define model size +#define NUMBER_OF_STATES 1 +#define NUMBER_OF_EVENT_INDICATORS 0 +#define NUMBER_OF_REALS 4 +#define NUMBER_OF_INTEGERS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_BOOLEANS 1 +#define NUMBER_OF_EXTERNALFUNCTIONS 0 + +// define variable data for model +#define $Pstock_ 0 +#define $P$DER$Pstock_ 1 +#define $Pvalve_ 2 +#define time_ 3 +#define $Pb_ 0 + + +// define initial state vector as vector of value references +#define STATES { $Pstock_ } +#define STATESDERIVATIVES { $P$DER$Pstock_ } + + +// implementation of the Model Exchange functions +#include "fmu_model_interface.c" + +// Set values for all variables that define a start value +void setDefaultStartValues(ModelInstance *comp) { + +comp->fmuData->modelData.realVarsData[0].attribute.start = 0.0; +comp->fmuData->modelData.realParameterData[0].attribute.start = 0.0; +comp->fmuData->modelData.booleanParameterData[0].attribute.start = 1; +} +// Set values for all variables that define a start value +void setStartValues(ModelInstance *comp) { + + comp->fmuData->modelData.realVarsData[0].attribute.start = comp->fmuData->localData[0]->realVars[0]; + comp->fmuData->modelData.realVarsData[1].attribute.start = comp->fmuData->localData[0]->realVars[1]; + comp->fmuData->modelData.realVarsData[2].attribute.start = comp->fmuData->localData[0]->realVars[2]; +comp->fmuData->modelData.realParameterData[0].attribute.start = comp->fmuData->simulationInfo.realParameter[0]; +comp->fmuData->modelData.booleanParameterData[0].attribute.start = comp->fmuData->simulationInfo.booleanParameter[0]; +} +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $Pstock_ : return comp->fmuData->localData[0]->realVars[0]; break; + case $P$DER$Pstock_ : return comp->fmuData->localData[0]->realVars[1]; break; + case $Pvalve_ : return comp->fmuData->localData[0]->realVars[2]; break; + case time_ : return comp->fmuData->simulationInfo.realParameter[0]; break; + default: + return fmiError; + } +} + +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value) { + switch (vr) { + case $Pstock_ : comp->fmuData->localData[0]->realVars[0]=value; break; + case $P$DER$Pstock_ : comp->fmuData->localData[0]->realVars[1]=value; break; + case $Pvalve_ : comp->fmuData->localData[0]->realVars[2]=value; break; + case time_ : comp->fmuData->simulationInfo.realParameter[0]=value; break; + default: + return fmiError; + } + return fmiOK; +} + +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value) { + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $Pb_ : return comp->fmuData->simulationInfo.booleanParameter[0]; break; + default: + return 0; + } +} + +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value) { + switch (vr) { + case $Pb_ : comp->fmuData->simulationInfo.booleanParameter[0]=value; break; + default: + return fmiError; + } + return fmiOK; +} + +fmiString getString(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} + +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value){ + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} + + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_functions.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_functions.c new file mode 100644 index 00000000..c36052e3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_functions.c @@ -0,0 +1,16 @@ +#include "FMUBooleanTestModel_functions.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define _OMC_LIT0_data "'p" +static const size_t _OMC_LIT0_strlen = 2; +static const char _OMC_LIT0[3] = _OMC_LIT0_data; +#define _OMC_LIT1_data "'p/s" +static const size_t _OMC_LIT1_strlen = 4; +static const char _OMC_LIT1[5] = _OMC_LIT1_data; + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_functions.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_functions.h new file mode 100644 index 00000000..3f2c2972 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_functions.h @@ -0,0 +1,17 @@ +#ifndef FMUBooleanTestModel__H +#define FMUBooleanTestModel__H +#define omp_get_thread_num() 0 +#include "modelica.h" +#include +#include +#include +#include "simulation_runtime.h" +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_records.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_records.c new file mode 100644 index 00000000..291900d9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/FMUBooleanTestModel_records.c @@ -0,0 +1,3 @@ +/* Additional record code for FMUBooleanTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#include "meta_modelica.h" + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/_FMUBooleanTestModel.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/_FMUBooleanTestModel.h new file mode 100644 index 00000000..4c999f68 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/_FMUBooleanTestModel.h @@ -0,0 +1,37 @@ +/* Simulation code for FMUBooleanTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#define time data->localData[0]->timeValue + +/* States */ +#define _$Pstock(i) data->localData[i]->realVars[0] +#define $Pstock _$Pstock(0) +#define $P$PRE$Pstock data->simulationInfo.realVarsPre[0] +#define $P$START$Pstock data->modelData.realVarsData[0].attribute.start +#define $Pstock__varInfo data->modelData.realVarsData[0].info +/* StatesDerivatives */ +#define _$P$DER$Pstock(i) data->localData[i]->realVars[1] +#define $P$DER$Pstock _$P$DER$Pstock(0) +#define $P$PRE$P$DER$Pstock data->simulationInfo.realVarsPre[1] +#define $P$START$P$DER$Pstock data->modelData.realVarsData[1].attribute.start +#define $P$DER$Pstock__varInfo data->modelData.realVarsData[1].info +/* Algebraic Vars */ +#define _$Pvalve(i) data->localData[i]->realVars[2] +#define $Pvalve _$Pvalve(0) +#define $P$PRE$Pvalve data->simulationInfo.realVarsPre[2] +#define $P$START$Pvalve data->modelData.realVarsData[2].attribute.start +#define $Pvalve__varInfo data->modelData.realVarsData[2].info +/* Algebraic Parameter */ +#define time data->simulationInfo.realParameter[0] +#define $P$STARTtime data->modelData.realParameterData[0].attribute.start +#define time__varInfo data->modelData.realParameterData[0].info +/* External Objects */ +/* Algebraic Integer Vars */ +/* Algebraic Integer Parameter */ +/* Algebraic Boolean Vars */ +/* Algebraic Boolean Parameters */ +#define $Pb data->simulationInfo.booleanParameter[0] +#define $P$START$Pb data->modelData.booleanParameterData[0].attribute.start +#define $Pb__varInfo data->modelData.booleanParameterData[0].info +/* Algebraic String Variables */ +/* Algebraic String Parameter */ +/* Jacobian Variables */ + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/modelDescription.xml b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/modelDescription.xml new file mode 100644 index 00000000..75163cb8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUBooleanTest/modelDescription.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTest.mo b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTest.mo new file mode 100644 index 00000000..3a19817c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTest.mo @@ -0,0 +1,19 @@ +model FMUCallBeforeInitializationTestModel + parameter Boolean b = true; + parameter Integer i = 1; + parameter Real r = 1.0; + Real valveBoolean; + Real stockBoolean(start=0.0,fixed=true); + Real valveInteger; + Real stockInteger(start=0.0,fixed=true); + Real valveReal; + Real stockReal(start=0.0,fixed=true); + parameter Real time = 0; // Time parameter is set at each time step by simulator +equation + valveBoolean = if initial() or b or not b then (if b then 1 else -1) else pre(valveBoolean); + valveInteger = if initial() or i < 0 or i >= 0 then (i) else pre(valveInteger); + valveReal = if initial() or r < 0 or r >= 0 then (r) else pre(valveReal); + der(stockBoolean) = valveBoolean; + der(stockInteger) = valveInteger; + der(stockReal) = valveReal; +end FMUCallBeforeInitializationTestModel; \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTest.mos b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTest.mos new file mode 100644 index 00000000..0a20aa78 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTest.mos @@ -0,0 +1,2 @@ +loadFile("FMUCallBeforeInitializationTest.mo"); +translateModelFMU(FMUCallBeforeInitializationTestModel) \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.c new file mode 100644 index 00000000..d27de664 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.c @@ -0,0 +1,464 @@ +/* Simulation code for FMUCallBeforeInitializationTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ + +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "simulation_runtime.h" +#include "omc_error.h" + +#include +#include + +#include "FMUCallBeforeInitializationTestModel_functions.h" + +#include "_FMUCallBeforeInitializationTestModel.h" +#include "FMUCallBeforeInitializationTestModel_functions.c" +/* dummy VARINFO and FILEINFO */ +const FILE_INFO dummyFILE_INFO = {"",-1,-1,-1,-1,1}; +const VAR_INFO dummyVAR_INFO = {-1,"","",(FILE_INFO){"",-1,-1,-1,-1,1}}; +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _OMC_MEASURE_TIME +int measure_time_flag = 1; +#else +int measure_time_flag = 0; +#endif + +void setupDataStruc(DATA *data) +{ + ASSERT(data,"Error while initialize Data"); + data->modelData.modelName = "FMUCallBeforeInitializationTestModel"; + data->modelData.modelFilePrefix = "FMUCallBeforeInitializationTestModel"; + data->modelData.modelDir = ""; + data->modelData.modelGUID = "{f4c1919a-ebce-4a1a-baca-8e57e23985cf}"; + + data->modelData.nStates = 3; + data->modelData.nVariablesReal = 2*3+3; + data->modelData.nVariablesInteger = 0; + data->modelData.nVariablesBoolean = 0; + data->modelData.nVariablesString = 0; + data->modelData.nParametersReal = 2; + data->modelData.nParametersInteger = 1; + data->modelData.nParametersBoolean = 1; + data->modelData.nParametersString = 0; + data->modelData.nInputVars = 0; + data->modelData.nOutputVars = 0; + data->modelData.nJacobians = 4; + data->modelData.nHelpVars = 0; + + data->modelData.nAliasReal = 0; + data->modelData.nAliasInteger = 0; + data->modelData.nAliasBoolean = 0; + data->modelData.nAliasString = 0; + + data->modelData.nZeroCrossings = 0; + data->modelData.nSamples = 0; + data->modelData.nInitEquations = 0; + data->modelData.nResiduals = 3; + data->modelData.nExtObjs = 0; + data->modelData.nFunctions = 0; + data->modelData.nEquations = 12; + + data->modelData.nDelayExpressions = 0; + +} + +void setupDataStruc2(DATA *data) +{ + const struct FUNCTION_INFO funcInfo[1] = {{-1,"",omc_dummyFileInfo}}; + memcpy(data->modelData.functionNames, &funcInfo, data->modelData.nFunctions*sizeof(FUNCTION_INFO)); + + const VAR_INFO** equationInfo_cref1 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref1[0] = &$PvalveReal__varInfo; + const VAR_INFO** equationInfo_cref3 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref3[0] = &$P$DER$PstockReal__varInfo; + const VAR_INFO** equationInfo_cref5 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref5[0] = &$PvalveInteger__varInfo; + const VAR_INFO** equationInfo_cref7 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref7[0] = &$P$DER$PstockInteger__varInfo; + const VAR_INFO** equationInfo_cref9 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref9[0] = &$PvalveBoolean__varInfo; + const VAR_INFO** equationInfo_cref11 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref11[0] = &$P$DER$PstockBoolean__varInfo; + const struct EQUATION_INFO equationInfo[12] = { + {1009,"SES_ALGORITHM 0", 0, NULL}, + {1010,"SES_SIMPLE_ASSIGN 1",1,equationInfo_cref1}, + {1011,"SES_ALGORITHM 2", 0, NULL}, + {1012,"SES_SIMPLE_ASSIGN 3",1,equationInfo_cref3}, + {1013,"SES_ALGORITHM 4", 0, NULL}, + {1014,"SES_SIMPLE_ASSIGN 5",1,equationInfo_cref5}, + {1015,"SES_ALGORITHM 6", 0, NULL}, + {1016,"SES_SIMPLE_ASSIGN 7",1,equationInfo_cref7}, + {1017,"SES_ALGORITHM 8", 0, NULL}, + {1018,"SES_SIMPLE_ASSIGN 9",1,equationInfo_cref9}, + {1019,"SES_ALGORITHM 10", 0, NULL}, + {1020,"SES_SIMPLE_ASSIGN 11",1,equationInfo_cref11} + }; + const int n_omc_equationInfo_reverse_prof_index = 0; + const int omc_equationInfo_reverse_prof_index[] = { + + }; + memcpy(data->modelData.equationInfo, &equationInfo, data->modelData.nEquations*sizeof(EQUATION_INFO)); + + data->modelData.nProfileBlocks = n_omc_equationInfo_reverse_prof_index; + data->modelData.equationInfo_reverse_prof_index = (int*) malloc(data->modelData.nProfileBlocks*sizeof(int)); + memcpy(data->modelData.equationInfo_reverse_prof_index, omc_equationInfo_reverse_prof_index, data->modelData.nProfileBlocks*sizeof(int)); +} + +/* Has to be performed after _init.xml file has been read */ +void callExternalObjectConstructors(DATA *data) +{ + state mem_state; + mem_state = get_memory_state(); + /* data->simulationInfo.extObjs = NULL; */ +} + +void callExternalObjectDestructors(DATA *data) +{ + if (data->simulationInfo.extObjs) { + free(data->simulationInfo.extObjs); + data->simulationInfo.extObjs = 0; + } +} + + +int input_function(DATA *data) +{ + return 0; +} + +int output_function(DATA *data) +{ + return 0; +} + +/* Initializes the raw time events of the simulation using the now + calcualted parameters. */ +void function_sampleInit(DATA *data) +{ +} + +int function_updateSample(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int function_storeDelayed(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundStartValues(DATA *data) +{ + + + DEBUG_INFO(LOG_INIT, "updating start-values:"); + + return 0; +} + +int initial_residual(DATA *data, double $P$_lambda, double* initialResiduals) +{ + int i = 0; + state mem_state; + + mem_state = get_memory_state(); + DEBUG_INFO(LOG_RES_INIT, "updating initial_residuals:"); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($PstockReal - $P$START$PstockReal)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stockReal - $_start(stockReal)) = %f", i, initialResiduals[i-1]); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($PstockInteger - $P$START$PstockInteger)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stockInteger - $_start(stockInteger)) = %f", i, initialResiduals[i-1]); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($PstockBoolean - $P$START$PstockBoolean)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stockBoolean - $_start(stockBoolean)) = %f", i, initialResiduals[i-1]); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundParameters(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_0(DATA *data) { + modelica_boolean tmp0; + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:13:2-13:93]*/ + tmp0 = initial(); + $PvalveBoolean = (((tmp0 || $Pb) || (!$Pb))?($Pb?1.0:-1.0):$P$PRE$PvalveBoolean); + /*#endModelicaLine*/ +} + + +void eqFunction_1(DATA *data) { + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:16:2-16:34]*/ + $P$DER$PstockBoolean = $PvalveBoolean; + /*#endModelicaLine*/ +} + + +void eqFunction_2(DATA *data) { + modelica_boolean tmp1; + modelica_boolean tmp2; + modelica_boolean tmp3; + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:14:2-14:80]*/ + tmp1 = initial(); + RELATIONTOZC(tmp2, (modelica_integer)$Pi, (modelica_integer) 0, -1,Less,<); + RELATIONTOZC(tmp3, (modelica_integer)$Pi, (modelica_integer) 0, -1,GreaterEq,>=); + $PvalveInteger = (((tmp1 || tmp2) || tmp3)?((modelica_real)(modelica_integer)$Pi):$P$PRE$PvalveInteger); + /*#endModelicaLine*/ +} + + +void eqFunction_3(DATA *data) { + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:17:2-17:34]*/ + $P$DER$PstockInteger = $PvalveInteger; + /*#endModelicaLine*/ +} + + +void eqFunction_4(DATA *data) { + modelica_boolean tmp4; + modelica_boolean tmp5; + modelica_boolean tmp6; + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:15:2-15:74]*/ + tmp4 = initial(); + RELATIONTOZC(tmp5, $Pr, 0.0, -1,Less,<); + RELATIONTOZC(tmp6, $Pr, 0.0, -1,GreaterEq,>=); + $PvalveReal = (((tmp4 || tmp5) || tmp6)?$Pr:$P$PRE$PvalveReal); + /*#endModelicaLine*/ +} + + +void eqFunction_5(DATA *data) { + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:18:2-18:28]*/ + $P$DER$PstockReal = $PvalveReal; + /*#endModelicaLine*/ +} + +static void functionODE_system0(DATA *data,int omc_thread_number) +{ + eqFunction_0(data); + eqFunction_1(data); + eqFunction_2(data); + eqFunction_3(data); + eqFunction_4(data); + eqFunction_5(data); +} +static void (*functionODE_systems[1])(DATA *, int) = { + functionODE_system0 +}; + +void function_initMemoryState() +{ + push_memory_states(1); +} + +int functionODE(DATA *data) +{ + int id,th_id; + state mem_state; /* We need to have separate memory pools for separate systems... */ + mem_state = get_memory_state(); + for (id=0; id<1; id++) { + th_id = omp_get_thread_num(); + functionODE_systems[id](data,th_id); + } + restore_memory_state(mem_state); + + return 0; +} +#include +const char *_omc_force_solver=_OMC_FORCE_SOLVER; +const int inline_work_states_ndims=_OMC_SOLVER_WORK_STATES_NDIMS; +int functionODE_inline(DATA* data, double stepSize) +{ + return 0; +} + +/* for continuous time variables */ +int functionAlgebraics(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_6(DATA *data) { + modelica_boolean tmp10; + modelica_boolean tmp11; + modelica_boolean tmp12; + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:15:2-15:74]*/ + tmp10 = initial(); + SAVEZEROCROSS(tmp11, $Pr, 0.0, -1,Less,<); + SAVEZEROCROSS(tmp12, $Pr, 0.0, -1,GreaterEq,>=); + $PvalveReal = (((tmp10 || tmp11) || tmp12)?$Pr:$P$PRE$PvalveReal); + /*#endModelicaLine*/ +} + + +void eqFunction_7(DATA *data) { + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:18:2-18:28]*/ + $P$DER$PstockReal = $PvalveReal; + /*#endModelicaLine*/ +} + + +void eqFunction_8(DATA *data) { + modelica_boolean tmp13; + modelica_boolean tmp14; + modelica_boolean tmp15; + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:14:2-14:80]*/ + tmp13 = initial(); + SAVEZEROCROSS(tmp14, (modelica_integer)$Pi, (modelica_integer) 0, -1,Less,<); + SAVEZEROCROSS(tmp15, (modelica_integer)$Pi, (modelica_integer) 0, -1,GreaterEq,>=); + $PvalveInteger = (((tmp13 || tmp14) || tmp15)?((modelica_real)(modelica_integer)$Pi):$P$PRE$PvalveInteger); + /*#endModelicaLine*/ +} + + +void eqFunction_9(DATA *data) { + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:17:2-17:34]*/ + $P$DER$PstockInteger = $PvalveInteger; + /*#endModelicaLine*/ +} + + +void eqFunction_10(DATA *data) { + modelica_boolean tmp16; + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:13:2-13:93]*/ + tmp16 = initial(); + $PvalveBoolean = (((tmp16 || $Pb) || (!$Pb))?($Pb?1.0:-1.0):$P$PRE$PvalveBoolean); + /*#endModelicaLine*/ +} + + +void eqFunction_11(DATA *data) { + /*#modelicaLine [FMUCallBeforeInitializationTest.mo:16:2-16:34]*/ + $P$DER$PstockBoolean = $PvalveBoolean; + /*#endModelicaLine*/ +} + +int functionDAE(DATA *data, int *needToIterate) +{ + state mem_state; + *needToIterate = 0; + + mem_state = get_memory_state(); + eqFunction_6(data); + eqFunction_7(data); + eqFunction_8(data); + eqFunction_9(data); + eqFunction_10(data); + eqFunction_11(data); + restore_memory_state(mem_state); + + return 0; +} + +int function_onlyZeroCrossings(DATA *data, double *gout,double *t) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int checkForDiscreteChanges(DATA *data) +{ + int needToIterate = 0; + + + return needToIterate; +} + +/* function to check assert after a step is done */ +int checkForAsserts(DATA *data) +{ + + + return 0; +} + + int initialAnalyticJacobianA(DATA* data){ + return 1; + } + + int initialAnalyticJacobianB(DATA* data){ + return 1; + } + + int initialAnalyticJacobianC(DATA* data){ + return 1; + } + + int initialAnalyticJacobianD(DATA* data){ + return 1; + } + int functionJacA(DATA* data, double* jac){ + return 0; + } + + int functionJacB(DATA* data, double* jac){ + return 0; + } + + int functionJacC(DATA* data, double* jac){ + return 0; + } + + int functionJacD(DATA* data, double* jac){ + return 0; + } + +const char *linear_model_frame = + "model linear_FMUCallBeforeInitializationTestModel\n parameter Integer n = 3; // states \n parameter Integer k = 0; // top-level inputs \n parameter Integer l = 0; // top-level outputs \n" + " parameter Real x0[3] = {%s};\n" + " parameter Real u0[0] = {%s};\n" + " parameter Real A[3,3] = [%s];\n" + " parameter Real B[3,0] = zeros(3,0);%s\n" + " parameter Real C[0,3] = zeros(0,3);%s\n" + " parameter Real D[0,0] = zeros(0,0);%s\n" + " Real x[3](start=x0);\n" + " input Real u[0];\n" + " output Real y[0];\n" + "\n Real x_PstockBoolean = x[1];\n Real x_PstockInteger = x[2];\n Real x_PstockReal = x[3];\n \n" + "equation\n der(x) = A * x + B * u;\n y = C * x + D * u;\nend linear_FMUCallBeforeInitializationTestModel;\n" +; + +#ifdef __cplusplus +} +#endif + +/* forward the main in the simulation runtime */ +extern int _main_SimulationRuntime(int argc, char**argv, DATA *data); + +/* call the simulation runtime main from our main! */ +int main(int argc, char**argv) +{ + DATA data; + setupDataStruc(&data); + return _main_SimulationRuntime(argc, argv, &data); +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.dll b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.dll new file mode 100644 index 00000000..d296450e Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.dll differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.fmu b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.fmu new file mode 100644 index 00000000..0a901a57 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.fmu differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.lib b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.lib new file mode 100644 index 00000000..da146e39 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel.lib differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_FMU.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_FMU.c new file mode 100644 index 00000000..3c57e878 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_FMU.c @@ -0,0 +1,190 @@ + +// define class name and unique id +#define MODEL_IDENTIFIER FMUCallBeforeInitializationTestModel +#define MODEL_GUID "{f4c1919a-ebce-4a1a-baca-8e57e23985cf}" + +// include fmu header files, typedefs and macros +#include +#include +#include +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "omc_error.h" +#include "fmiModelTypes.h" +#include "fmiModelFunctions.h" +#include "FMUCallBeforeInitializationTestModel_functions.h" +#include "initialization.h" +#include "events.h" +#include "fmu_model_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void setStartValues(ModelInstance *comp); +void setDefaultStartValues(ModelInstance *comp); +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo); +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value); +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value); +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value); +fmiString getString(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value); + +// define model size +#define NUMBER_OF_STATES 3 +#define NUMBER_OF_EVENT_INDICATORS 0 +#define NUMBER_OF_REALS 11 +#define NUMBER_OF_INTEGERS 1 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_BOOLEANS 1 +#define NUMBER_OF_EXTERNALFUNCTIONS 0 + +// define variable data for model +#define $PstockBoolean_ 0 +#define $PstockInteger_ 1 +#define $PstockReal_ 2 +#define $P$DER$PstockBoolean_ 3 +#define $P$DER$PstockInteger_ 4 +#define $P$DER$PstockReal_ 5 +#define $PvalveBoolean_ 6 +#define $PvalveInteger_ 7 +#define $PvalveReal_ 8 +#define $Pr_ 9 +#define time_ 10 +#define $Pi_ 0 +#define $Pb_ 0 + + +// define initial state vector as vector of value references +#define STATES { $PstockBoolean_, $PstockInteger_, $PstockReal_ } +#define STATESDERIVATIVES { $P$DER$PstockBoolean_, $P$DER$PstockInteger_, $P$DER$PstockReal_ } + + +// implementation of the Model Exchange functions +#include "fmu_model_interface.c" + +// Set values for all variables that define a start value +void setDefaultStartValues(ModelInstance *comp) { + +comp->fmuData->modelData.realVarsData[0].attribute.start = 0.0; +comp->fmuData->modelData.realVarsData[1].attribute.start = 0.0; +comp->fmuData->modelData.realVarsData[2].attribute.start = 0.0; +comp->fmuData->modelData.realParameterData[0].attribute.start = 1.0; +comp->fmuData->modelData.realParameterData[1].attribute.start = 0.0; +comp->fmuData->modelData.integerParameterData[0].attribute.start = 1; +comp->fmuData->modelData.booleanParameterData[0].attribute.start = 1; +} +// Set values for all variables that define a start value +void setStartValues(ModelInstance *comp) { + + comp->fmuData->modelData.realVarsData[0].attribute.start = comp->fmuData->localData[0]->realVars[0]; + comp->fmuData->modelData.realVarsData[1].attribute.start = comp->fmuData->localData[0]->realVars[1]; + comp->fmuData->modelData.realVarsData[2].attribute.start = comp->fmuData->localData[0]->realVars[2]; + comp->fmuData->modelData.realVarsData[3].attribute.start = comp->fmuData->localData[0]->realVars[3]; + comp->fmuData->modelData.realVarsData[4].attribute.start = comp->fmuData->localData[0]->realVars[4]; + comp->fmuData->modelData.realVarsData[5].attribute.start = comp->fmuData->localData[0]->realVars[5]; + comp->fmuData->modelData.realVarsData[6].attribute.start = comp->fmuData->localData[0]->realVars[6]; + comp->fmuData->modelData.realVarsData[7].attribute.start = comp->fmuData->localData[0]->realVars[7]; + comp->fmuData->modelData.realVarsData[8].attribute.start = comp->fmuData->localData[0]->realVars[8]; +comp->fmuData->modelData.realParameterData[0].attribute.start = comp->fmuData->simulationInfo.realParameter[0]; +comp->fmuData->modelData.realParameterData[1].attribute.start = comp->fmuData->simulationInfo.realParameter[1]; +comp->fmuData->modelData.integerParameterData[0].attribute.start = comp->fmuData->simulationInfo.integerParameter[0]; +comp->fmuData->modelData.booleanParameterData[0].attribute.start = comp->fmuData->simulationInfo.booleanParameter[0]; +} +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $PstockBoolean_ : return comp->fmuData->localData[0]->realVars[0]; break; + case $PstockInteger_ : return comp->fmuData->localData[0]->realVars[1]; break; + case $PstockReal_ : return comp->fmuData->localData[0]->realVars[2]; break; + case $P$DER$PstockBoolean_ : return comp->fmuData->localData[0]->realVars[3]; break; + case $P$DER$PstockInteger_ : return comp->fmuData->localData[0]->realVars[4]; break; + case $P$DER$PstockReal_ : return comp->fmuData->localData[0]->realVars[5]; break; + case $PvalveBoolean_ : return comp->fmuData->localData[0]->realVars[6]; break; + case $PvalveInteger_ : return comp->fmuData->localData[0]->realVars[7]; break; + case $PvalveReal_ : return comp->fmuData->localData[0]->realVars[8]; break; + case $Pr_ : return comp->fmuData->simulationInfo.realParameter[0]; break; + case time_ : return comp->fmuData->simulationInfo.realParameter[1]; break; + default: + return fmiError; + } +} + +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value) { + switch (vr) { + case $PstockBoolean_ : comp->fmuData->localData[0]->realVars[0]=value; break; + case $PstockInteger_ : comp->fmuData->localData[0]->realVars[1]=value; break; + case $PstockReal_ : comp->fmuData->localData[0]->realVars[2]=value; break; + case $P$DER$PstockBoolean_ : comp->fmuData->localData[0]->realVars[3]=value; break; + case $P$DER$PstockInteger_ : comp->fmuData->localData[0]->realVars[4]=value; break; + case $P$DER$PstockReal_ : comp->fmuData->localData[0]->realVars[5]=value; break; + case $PvalveBoolean_ : comp->fmuData->localData[0]->realVars[6]=value; break; + case $PvalveInteger_ : comp->fmuData->localData[0]->realVars[7]=value; break; + case $PvalveReal_ : comp->fmuData->localData[0]->realVars[8]=value; break; + case $Pr_ : comp->fmuData->simulationInfo.realParameter[0]=value; break; + case time_ : comp->fmuData->simulationInfo.realParameter[1]=value; break; + default: + return fmiError; + } + return fmiOK; +} + +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $Pi_ : return comp->fmuData->simulationInfo.integerParameter[0]; break; + default: + return 0; + } +} +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value) { + switch (vr) { + case $Pi_ : comp->fmuData->simulationInfo.integerParameter[0]=value; break; + default: + return fmiError; + } + return fmiOK; +} +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $Pb_ : return comp->fmuData->simulationInfo.booleanParameter[0]; break; + default: + return 0; + } +} + +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value) { + switch (vr) { + case $Pb_ : comp->fmuData->simulationInfo.booleanParameter[0]=value; break; + default: + return fmiError; + } + return fmiOK; +} + +fmiString getString(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} + +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value){ + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} + + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_functions.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_functions.c new file mode 100644 index 00000000..621cd413 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_functions.c @@ -0,0 +1,16 @@ +#include "FMUCallBeforeInitializationTestModel_functions.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define _OMC_LIT0_data "'p" +static const size_t _OMC_LIT0_strlen = 2; +static const char _OMC_LIT0[3] = _OMC_LIT0_data; +#define _OMC_LIT1_data "'p/s" +static const size_t _OMC_LIT1_strlen = 4; +static const char _OMC_LIT1[5] = _OMC_LIT1_data; + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_functions.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_functions.h new file mode 100644 index 00000000..a350862c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_functions.h @@ -0,0 +1,17 @@ +#ifndef FMUCallBeforeInitializationTestModel__H +#define FMUCallBeforeInitializationTestModel__H +#define omp_get_thread_num() 0 +#include "modelica.h" +#include +#include +#include +#include "simulation_runtime.h" +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_records.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_records.c new file mode 100644 index 00000000..ed3c84ce --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/FMUCallBeforeInitializationTestModel_records.c @@ -0,0 +1,3 @@ +/* Additional record code for FMUCallBeforeInitializationTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#include "meta_modelica.h" + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/_FMUCallBeforeInitializationTestModel.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/_FMUCallBeforeInitializationTestModel.h new file mode 100644 index 00000000..57ae6827 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/_FMUCallBeforeInitializationTestModel.h @@ -0,0 +1,73 @@ +/* Simulation code for FMUCallBeforeInitializationTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#define time data->localData[0]->timeValue + +/* States */ +#define _$PstockBoolean(i) data->localData[i]->realVars[0] +#define $PstockBoolean _$PstockBoolean(0) +#define $P$PRE$PstockBoolean data->simulationInfo.realVarsPre[0] +#define $P$START$PstockBoolean data->modelData.realVarsData[0].attribute.start +#define $PstockBoolean__varInfo data->modelData.realVarsData[0].info +#define _$PstockInteger(i) data->localData[i]->realVars[1] +#define $PstockInteger _$PstockInteger(0) +#define $P$PRE$PstockInteger data->simulationInfo.realVarsPre[1] +#define $P$START$PstockInteger data->modelData.realVarsData[1].attribute.start +#define $PstockInteger__varInfo data->modelData.realVarsData[1].info +#define _$PstockReal(i) data->localData[i]->realVars[2] +#define $PstockReal _$PstockReal(0) +#define $P$PRE$PstockReal data->simulationInfo.realVarsPre[2] +#define $P$START$PstockReal data->modelData.realVarsData[2].attribute.start +#define $PstockReal__varInfo data->modelData.realVarsData[2].info +/* StatesDerivatives */ +#define _$P$DER$PstockBoolean(i) data->localData[i]->realVars[3] +#define $P$DER$PstockBoolean _$P$DER$PstockBoolean(0) +#define $P$PRE$P$DER$PstockBoolean data->simulationInfo.realVarsPre[3] +#define $P$START$P$DER$PstockBoolean data->modelData.realVarsData[3].attribute.start +#define $P$DER$PstockBoolean__varInfo data->modelData.realVarsData[3].info +#define _$P$DER$PstockInteger(i) data->localData[i]->realVars[4] +#define $P$DER$PstockInteger _$P$DER$PstockInteger(0) +#define $P$PRE$P$DER$PstockInteger data->simulationInfo.realVarsPre[4] +#define $P$START$P$DER$PstockInteger data->modelData.realVarsData[4].attribute.start +#define $P$DER$PstockInteger__varInfo data->modelData.realVarsData[4].info +#define _$P$DER$PstockReal(i) data->localData[i]->realVars[5] +#define $P$DER$PstockReal _$P$DER$PstockReal(0) +#define $P$PRE$P$DER$PstockReal data->simulationInfo.realVarsPre[5] +#define $P$START$P$DER$PstockReal data->modelData.realVarsData[5].attribute.start +#define $P$DER$PstockReal__varInfo data->modelData.realVarsData[5].info +/* Algebraic Vars */ +#define _$PvalveBoolean(i) data->localData[i]->realVars[6] +#define $PvalveBoolean _$PvalveBoolean(0) +#define $P$PRE$PvalveBoolean data->simulationInfo.realVarsPre[6] +#define $P$START$PvalveBoolean data->modelData.realVarsData[6].attribute.start +#define $PvalveBoolean__varInfo data->modelData.realVarsData[6].info +#define _$PvalveInteger(i) data->localData[i]->realVars[7] +#define $PvalveInteger _$PvalveInteger(0) +#define $P$PRE$PvalveInteger data->simulationInfo.realVarsPre[7] +#define $P$START$PvalveInteger data->modelData.realVarsData[7].attribute.start +#define $PvalveInteger__varInfo data->modelData.realVarsData[7].info +#define _$PvalveReal(i) data->localData[i]->realVars[8] +#define $PvalveReal _$PvalveReal(0) +#define $P$PRE$PvalveReal data->simulationInfo.realVarsPre[8] +#define $P$START$PvalveReal data->modelData.realVarsData[8].attribute.start +#define $PvalveReal__varInfo data->modelData.realVarsData[8].info +/* Algebraic Parameter */ +#define $Pr data->simulationInfo.realParameter[0] +#define $P$START$Pr data->modelData.realParameterData[0].attribute.start +#define $Pr__varInfo data->modelData.realParameterData[0].info +#define time data->simulationInfo.realParameter[1] +#define $P$STARTtime data->modelData.realParameterData[1].attribute.start +#define time__varInfo data->modelData.realParameterData[1].info +/* External Objects */ +/* Algebraic Integer Vars */ +/* Algebraic Integer Parameter */ +#define $Pi data->simulationInfo.integerParameter[0] +#define $P$START$Pi data->modelData.integerParameterData[0].attribute.start +#define $Pi__varInfo data->modelData.integerParameterData[0].info +/* Algebraic Boolean Vars */ +/* Algebraic Boolean Parameters */ +#define $Pb data->simulationInfo.booleanParameter[0] +#define $P$START$Pb data->modelData.booleanParameterData[0].attribute.start +#define $Pb__varInfo data->modelData.booleanParameterData[0].info +/* Algebraic String Variables */ +/* Algebraic String Parameter */ +/* Jacobian Variables */ + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/modelDescription.xml b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/modelDescription.xml new file mode 100644 index 00000000..102788e1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUCallBeforeInitializationTest/modelDescription.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTest.mo b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTest.mo new file mode 100644 index 00000000..fd9af846 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTest.mo @@ -0,0 +1,10 @@ +model FMUIntegerTestModel + parameter Integer i1 = 1; + parameter Integer i2 = 1; + Real valve; + Real stock(start=0.0,fixed=true); + parameter Real time = 0; // Time parameter is set at each time step by simulator +equation + valve = if initial() or i1 < 0 or i1 >= 0 then (i1 + i2) else pre(valve); + der(stock) = valve; +end FMUIntegerTestModel; \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTest.mos b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTest.mos new file mode 100644 index 00000000..ee7b2b12 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTest.mos @@ -0,0 +1,2 @@ +loadFile("FMUIntegerTest.mo"); +translateModelFMU(FMUIntegerTestModel) \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.c new file mode 100644 index 00000000..ed54ffb5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.c @@ -0,0 +1,364 @@ +/* Simulation code for FMUIntegerTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ + +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "simulation_runtime.h" +#include "omc_error.h" + +#include +#include + +#include "FMUIntegerTestModel_functions.h" + +#include "_FMUIntegerTestModel.h" +#include "FMUIntegerTestModel_functions.c" +/* dummy VARINFO and FILEINFO */ +const FILE_INFO dummyFILE_INFO = {"",-1,-1,-1,-1,1}; +const VAR_INFO dummyVAR_INFO = {-1,"","",(FILE_INFO){"",-1,-1,-1,-1,1}}; +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _OMC_MEASURE_TIME +int measure_time_flag = 1; +#else +int measure_time_flag = 0; +#endif + +void setupDataStruc(DATA *data) +{ + ASSERT(data,"Error while initialize Data"); + data->modelData.modelName = "FMUIntegerTestModel"; + data->modelData.modelFilePrefix = "FMUIntegerTestModel"; + data->modelData.modelDir = ""; + data->modelData.modelGUID = "{2d294e78-8670-49d1-89de-38199246249e}"; + + data->modelData.nStates = 1; + data->modelData.nVariablesReal = 2*1+1; + data->modelData.nVariablesInteger = 0; + data->modelData.nVariablesBoolean = 0; + data->modelData.nVariablesString = 0; + data->modelData.nParametersReal = 1; + data->modelData.nParametersInteger = 2; + data->modelData.nParametersBoolean = 0; + data->modelData.nParametersString = 0; + data->modelData.nInputVars = 0; + data->modelData.nOutputVars = 0; + data->modelData.nJacobians = 4; + data->modelData.nHelpVars = 0; + + data->modelData.nAliasReal = 0; + data->modelData.nAliasInteger = 0; + data->modelData.nAliasBoolean = 0; + data->modelData.nAliasString = 0; + + data->modelData.nZeroCrossings = 0; + data->modelData.nSamples = 0; + data->modelData.nInitEquations = 0; + data->modelData.nResiduals = 1; + data->modelData.nExtObjs = 0; + data->modelData.nFunctions = 0; + data->modelData.nEquations = 4; + + data->modelData.nDelayExpressions = 0; + +} + +void setupDataStruc2(DATA *data) +{ + const struct FUNCTION_INFO funcInfo[1] = {{-1,"",omc_dummyFileInfo}}; + memcpy(data->modelData.functionNames, &funcInfo, data->modelData.nFunctions*sizeof(FUNCTION_INFO)); + + const VAR_INFO** equationInfo_cref1 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref1[0] = &$Pvalve__varInfo; + const VAR_INFO** equationInfo_cref3 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref3[0] = &$P$DER$Pstock__varInfo; + const struct EQUATION_INFO equationInfo[4] = { + {1003,"SES_ALGORITHM 0", 0, NULL}, + {1004,"SES_SIMPLE_ASSIGN 1",1,equationInfo_cref1}, + {1005,"SES_ALGORITHM 2", 0, NULL}, + {1006,"SES_SIMPLE_ASSIGN 3",1,equationInfo_cref3} + }; + const int n_omc_equationInfo_reverse_prof_index = 0; + const int omc_equationInfo_reverse_prof_index[] = { + + }; + memcpy(data->modelData.equationInfo, &equationInfo, data->modelData.nEquations*sizeof(EQUATION_INFO)); + + data->modelData.nProfileBlocks = n_omc_equationInfo_reverse_prof_index; + data->modelData.equationInfo_reverse_prof_index = (int*) malloc(data->modelData.nProfileBlocks*sizeof(int)); + memcpy(data->modelData.equationInfo_reverse_prof_index, omc_equationInfo_reverse_prof_index, data->modelData.nProfileBlocks*sizeof(int)); +} + +/* Has to be performed after _init.xml file has been read */ +void callExternalObjectConstructors(DATA *data) +{ + state mem_state; + mem_state = get_memory_state(); + /* data->simulationInfo.extObjs = NULL; */ +} + +void callExternalObjectDestructors(DATA *data) +{ + if (data->simulationInfo.extObjs) { + free(data->simulationInfo.extObjs); + data->simulationInfo.extObjs = 0; + } +} + + +int input_function(DATA *data) +{ + return 0; +} + +int output_function(DATA *data) +{ + return 0; +} + +/* Initializes the raw time events of the simulation using the now + calcualted parameters. */ +void function_sampleInit(DATA *data) +{ +} + +int function_updateSample(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int function_storeDelayed(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundStartValues(DATA *data) +{ + + + DEBUG_INFO(LOG_INIT, "updating start-values:"); + + return 0; +} + +int initial_residual(DATA *data, double $P$_lambda, double* initialResiduals) +{ + int i = 0; + state mem_state; + + mem_state = get_memory_state(); + DEBUG_INFO(LOG_RES_INIT, "updating initial_residuals:"); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($Pstock - $P$START$Pstock)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stock - $_start(stock)) = %f", i, initialResiduals[i-1]); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundParameters(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_0(DATA *data) { + modelica_boolean tmp0; + modelica_boolean tmp1; + modelica_boolean tmp2; + /*#modelicaLine [FMUIntegerTest.mo:8:2-8:74]*/ + tmp0 = initial(); + RELATIONTOZC(tmp1, (modelica_integer)$Pi1, (modelica_integer) 0, -1,Less,<); + RELATIONTOZC(tmp2, (modelica_integer)$Pi1, (modelica_integer) 0, -1,GreaterEq,>=); + $Pvalve = (((tmp0 || tmp1) || tmp2)?((modelica_real)((modelica_integer)$Pi1 + (modelica_integer)$Pi2)):$P$PRE$Pvalve); + /*#endModelicaLine*/ +} + + +void eqFunction_1(DATA *data) { + /*#modelicaLine [FMUIntegerTest.mo:9:2-9:20]*/ + $P$DER$Pstock = $Pvalve; + /*#endModelicaLine*/ +} + +static void functionODE_system0(DATA *data,int omc_thread_number) +{ + eqFunction_0(data); + eqFunction_1(data); +} +static void (*functionODE_systems[1])(DATA *, int) = { + functionODE_system0 +}; + +void function_initMemoryState() +{ + push_memory_states(1); +} + +int functionODE(DATA *data) +{ + int id,th_id; + state mem_state; /* We need to have separate memory pools for separate systems... */ + mem_state = get_memory_state(); + for (id=0; id<1; id++) { + th_id = omp_get_thread_num(); + functionODE_systems[id](data,th_id); + } + restore_memory_state(mem_state); + + return 0; +} +#include +const char *_omc_force_solver=_OMC_FORCE_SOLVER; +const int inline_work_states_ndims=_OMC_SOLVER_WORK_STATES_NDIMS; +int functionODE_inline(DATA* data, double stepSize) +{ + return 0; +} + +/* for continuous time variables */ +int functionAlgebraics(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_2(DATA *data) { + modelica_boolean tmp4; + modelica_boolean tmp5; + modelica_boolean tmp6; + /*#modelicaLine [FMUIntegerTest.mo:8:2-8:74]*/ + tmp4 = initial(); + SAVEZEROCROSS(tmp5, (modelica_integer)$Pi1, (modelica_integer) 0, -1,Less,<); + SAVEZEROCROSS(tmp6, (modelica_integer)$Pi1, (modelica_integer) 0, -1,GreaterEq,>=); + $Pvalve = (((tmp4 || tmp5) || tmp6)?((modelica_real)((modelica_integer)$Pi1 + (modelica_integer)$Pi2)):$P$PRE$Pvalve); + /*#endModelicaLine*/ +} + + +void eqFunction_3(DATA *data) { + /*#modelicaLine [FMUIntegerTest.mo:9:2-9:20]*/ + $P$DER$Pstock = $Pvalve; + /*#endModelicaLine*/ +} + +int functionDAE(DATA *data, int *needToIterate) +{ + state mem_state; + *needToIterate = 0; + + mem_state = get_memory_state(); + eqFunction_2(data); + eqFunction_3(data); + restore_memory_state(mem_state); + + return 0; +} + +int function_onlyZeroCrossings(DATA *data, double *gout,double *t) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int checkForDiscreteChanges(DATA *data) +{ + int needToIterate = 0; + + + return needToIterate; +} + +/* function to check assert after a step is done */ +int checkForAsserts(DATA *data) +{ + + + return 0; +} + + int initialAnalyticJacobianA(DATA* data){ + return 1; + } + + int initialAnalyticJacobianB(DATA* data){ + return 1; + } + + int initialAnalyticJacobianC(DATA* data){ + return 1; + } + + int initialAnalyticJacobianD(DATA* data){ + return 1; + } + int functionJacA(DATA* data, double* jac){ + return 0; + } + + int functionJacB(DATA* data, double* jac){ + return 0; + } + + int functionJacC(DATA* data, double* jac){ + return 0; + } + + int functionJacD(DATA* data, double* jac){ + return 0; + } + +const char *linear_model_frame = + "model linear_FMUIntegerTestModel\n parameter Integer n = 1; // states \n parameter Integer k = 0; // top-level inputs \n parameter Integer l = 0; // top-level outputs \n" + " parameter Real x0[1] = {%s};\n" + " parameter Real u0[0] = {%s};\n" + " parameter Real A[1,1] = [%s];\n" + " parameter Real B[1,0] = zeros(1,0);%s\n" + " parameter Real C[0,1] = zeros(0,1);%s\n" + " parameter Real D[0,0] = zeros(0,0);%s\n" + " Real x[1](start=x0);\n" + " input Real u[0];\n" + " output Real y[0];\n" + "\n Real x_Pstock = x[1];\n \n" + "equation\n der(x) = A * x + B * u;\n y = C * x + D * u;\nend linear_FMUIntegerTestModel;\n" +; + +#ifdef __cplusplus +} +#endif + +/* forward the main in the simulation runtime */ +extern int _main_SimulationRuntime(int argc, char**argv, DATA *data); + +/* call the simulation runtime main from our main! */ +int main(int argc, char**argv) +{ + DATA data; + setupDataStruc(&data); + return _main_SimulationRuntime(argc, argv, &data); +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.dll b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.dll new file mode 100644 index 00000000..ae281fc4 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.dll differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.fmu b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.fmu new file mode 100644 index 00000000..3e0d419f Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.fmu differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.lib b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.lib new file mode 100644 index 00000000..a9ef1e56 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel.lib differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_FMU.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_FMU.c new file mode 100644 index 00000000..d211cc71 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_FMU.c @@ -0,0 +1,159 @@ + +// define class name and unique id +#define MODEL_IDENTIFIER FMUIntegerTestModel +#define MODEL_GUID "{2d294e78-8670-49d1-89de-38199246249e}" + +// include fmu header files, typedefs and macros +#include +#include +#include +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "omc_error.h" +#include "fmiModelTypes.h" +#include "fmiModelFunctions.h" +#include "FMUIntegerTestModel_functions.h" +#include "initialization.h" +#include "events.h" +#include "fmu_model_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void setStartValues(ModelInstance *comp); +void setDefaultStartValues(ModelInstance *comp); +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo); +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value); +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value); +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value); +fmiString getString(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value); + +// define model size +#define NUMBER_OF_STATES 1 +#define NUMBER_OF_EVENT_INDICATORS 0 +#define NUMBER_OF_REALS 4 +#define NUMBER_OF_INTEGERS 2 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_EXTERNALFUNCTIONS 0 + +// define variable data for model +#define $Pstock_ 0 +#define $P$DER$Pstock_ 1 +#define $Pvalve_ 2 +#define time_ 3 +#define $Pi1_ 0 +#define $Pi2_ 1 + + +// define initial state vector as vector of value references +#define STATES { $Pstock_ } +#define STATESDERIVATIVES { $P$DER$Pstock_ } + + +// implementation of the Model Exchange functions +#include "fmu_model_interface.c" + +// Set values for all variables that define a start value +void setDefaultStartValues(ModelInstance *comp) { + +comp->fmuData->modelData.realVarsData[0].attribute.start = 0.0; +comp->fmuData->modelData.realParameterData[0].attribute.start = 0.0; +comp->fmuData->modelData.integerParameterData[0].attribute.start = 1; +comp->fmuData->modelData.integerParameterData[1].attribute.start = 1; +} +// Set values for all variables that define a start value +void setStartValues(ModelInstance *comp) { + + comp->fmuData->modelData.realVarsData[0].attribute.start = comp->fmuData->localData[0]->realVars[0]; + comp->fmuData->modelData.realVarsData[1].attribute.start = comp->fmuData->localData[0]->realVars[1]; + comp->fmuData->modelData.realVarsData[2].attribute.start = comp->fmuData->localData[0]->realVars[2]; +comp->fmuData->modelData.realParameterData[0].attribute.start = comp->fmuData->simulationInfo.realParameter[0]; +comp->fmuData->modelData.integerParameterData[0].attribute.start = comp->fmuData->simulationInfo.integerParameter[0]; +comp->fmuData->modelData.integerParameterData[1].attribute.start = comp->fmuData->simulationInfo.integerParameter[1]; +} +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $Pstock_ : return comp->fmuData->localData[0]->realVars[0]; break; + case $P$DER$Pstock_ : return comp->fmuData->localData[0]->realVars[1]; break; + case $Pvalve_ : return comp->fmuData->localData[0]->realVars[2]; break; + case time_ : return comp->fmuData->simulationInfo.realParameter[0]; break; + default: + return fmiError; + } +} + +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value) { + switch (vr) { + case $Pstock_ : comp->fmuData->localData[0]->realVars[0]=value; break; + case $P$DER$Pstock_ : comp->fmuData->localData[0]->realVars[1]=value; break; + case $Pvalve_ : comp->fmuData->localData[0]->realVars[2]=value; break; + case time_ : comp->fmuData->simulationInfo.realParameter[0]=value; break; + default: + return fmiError; + } + return fmiOK; +} + +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $Pi1_ : return comp->fmuData->simulationInfo.integerParameter[0]; break; + case $Pi2_ : return comp->fmuData->simulationInfo.integerParameter[1]; break; + default: + return 0; + } +} +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value) { + switch (vr) { + case $Pi1_ : comp->fmuData->simulationInfo.integerParameter[0]=value; break; + case $Pi2_ : comp->fmuData->simulationInfo.integerParameter[1]=value; break; + default: + return fmiError; + } + return fmiOK; +} +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} + +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value) { + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} + +fmiString getString(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} + +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value){ + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} + + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_functions.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_functions.c new file mode 100644 index 00000000..c03781fc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_functions.c @@ -0,0 +1,16 @@ +#include "FMUIntegerTestModel_functions.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define _OMC_LIT0_data "'p" +static const size_t _OMC_LIT0_strlen = 2; +static const char _OMC_LIT0[3] = _OMC_LIT0_data; +#define _OMC_LIT1_data "'p/s" +static const size_t _OMC_LIT1_strlen = 4; +static const char _OMC_LIT1[5] = _OMC_LIT1_data; + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_functions.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_functions.h new file mode 100644 index 00000000..c0eb9cd4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_functions.h @@ -0,0 +1,17 @@ +#ifndef FMUIntegerTestModel__H +#define FMUIntegerTestModel__H +#define omp_get_thread_num() 0 +#include "modelica.h" +#include +#include +#include +#include "simulation_runtime.h" +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_records.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_records.c new file mode 100644 index 00000000..10585d89 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/FMUIntegerTestModel_records.c @@ -0,0 +1,3 @@ +/* Additional record code for FMUIntegerTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#include "meta_modelica.h" + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/_FMUIntegerTestModel.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/_FMUIntegerTestModel.h new file mode 100644 index 00000000..10488186 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/_FMUIntegerTestModel.h @@ -0,0 +1,40 @@ +/* Simulation code for FMUIntegerTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#define time data->localData[0]->timeValue + +/* States */ +#define _$Pstock(i) data->localData[i]->realVars[0] +#define $Pstock _$Pstock(0) +#define $P$PRE$Pstock data->simulationInfo.realVarsPre[0] +#define $P$START$Pstock data->modelData.realVarsData[0].attribute.start +#define $Pstock__varInfo data->modelData.realVarsData[0].info +/* StatesDerivatives */ +#define _$P$DER$Pstock(i) data->localData[i]->realVars[1] +#define $P$DER$Pstock _$P$DER$Pstock(0) +#define $P$PRE$P$DER$Pstock data->simulationInfo.realVarsPre[1] +#define $P$START$P$DER$Pstock data->modelData.realVarsData[1].attribute.start +#define $P$DER$Pstock__varInfo data->modelData.realVarsData[1].info +/* Algebraic Vars */ +#define _$Pvalve(i) data->localData[i]->realVars[2] +#define $Pvalve _$Pvalve(0) +#define $P$PRE$Pvalve data->simulationInfo.realVarsPre[2] +#define $P$START$Pvalve data->modelData.realVarsData[2].attribute.start +#define $Pvalve__varInfo data->modelData.realVarsData[2].info +/* Algebraic Parameter */ +#define time data->simulationInfo.realParameter[0] +#define $P$STARTtime data->modelData.realParameterData[0].attribute.start +#define time__varInfo data->modelData.realParameterData[0].info +/* External Objects */ +/* Algebraic Integer Vars */ +/* Algebraic Integer Parameter */ +#define $Pi1 data->simulationInfo.integerParameter[0] +#define $P$START$Pi1 data->modelData.integerParameterData[0].attribute.start +#define $Pi1__varInfo data->modelData.integerParameterData[0].info +#define $Pi2 data->simulationInfo.integerParameter[1] +#define $P$START$Pi2 data->modelData.integerParameterData[1].attribute.start +#define $Pi2__varInfo data->modelData.integerParameterData[1].info +/* Algebraic Boolean Vars */ +/* Algebraic Boolean Parameters */ +/* Algebraic String Variables */ +/* Algebraic String Parameter */ +/* Jacobian Variables */ + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/modelDescription.xml b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/modelDescription.xml new file mode 100644 index 00000000..60ef85d1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUIntegerTest/modelDescription.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTest.mo b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTest.mo new file mode 100644 index 00000000..986ef255 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTest.mo @@ -0,0 +1,10 @@ +model FMURealTestModel + parameter Real r1 = 1.0; + parameter Real r2 = 1.0; + Real valve; + Real stock(start=0.0,fixed=true); + parameter Real time = 0; // Time parameter is set at each time step by simulator +equation + valve = if initial() or r1 < 0 or r1 >= 0 then (r1 + r2) else pre(valve); + der(stock) = valve; +end FMURealTestModel; \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTest.mos b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTest.mos new file mode 100644 index 00000000..e76e5783 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTest.mos @@ -0,0 +1,2 @@ +loadFile("FMURealTest.mo"); +translateModelFMU(FMURealTestModel) \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.c new file mode 100644 index 00000000..7c90624c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.c @@ -0,0 +1,364 @@ +/* Simulation code for FMURealTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ + +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "simulation_runtime.h" +#include "omc_error.h" + +#include +#include + +#include "FMURealTestModel_functions.h" + +#include "_FMURealTestModel.h" +#include "FMURealTestModel_functions.c" +/* dummy VARINFO and FILEINFO */ +const FILE_INFO dummyFILE_INFO = {"",-1,-1,-1,-1,1}; +const VAR_INFO dummyVAR_INFO = {-1,"","",(FILE_INFO){"",-1,-1,-1,-1,1}}; +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _OMC_MEASURE_TIME +int measure_time_flag = 1; +#else +int measure_time_flag = 0; +#endif + +void setupDataStruc(DATA *data) +{ + ASSERT(data,"Error while initialize Data"); + data->modelData.modelName = "FMURealTestModel"; + data->modelData.modelFilePrefix = "FMURealTestModel"; + data->modelData.modelDir = ""; + data->modelData.modelGUID = "{7cae105e-c592-4723-8ae7-041b2a1231d7}"; + + data->modelData.nStates = 1; + data->modelData.nVariablesReal = 2*1+1; + data->modelData.nVariablesInteger = 0; + data->modelData.nVariablesBoolean = 0; + data->modelData.nVariablesString = 0; + data->modelData.nParametersReal = 3; + data->modelData.nParametersInteger = 0; + data->modelData.nParametersBoolean = 0; + data->modelData.nParametersString = 0; + data->modelData.nInputVars = 0; + data->modelData.nOutputVars = 0; + data->modelData.nJacobians = 4; + data->modelData.nHelpVars = 0; + + data->modelData.nAliasReal = 0; + data->modelData.nAliasInteger = 0; + data->modelData.nAliasBoolean = 0; + data->modelData.nAliasString = 0; + + data->modelData.nZeroCrossings = 0; + data->modelData.nSamples = 0; + data->modelData.nInitEquations = 0; + data->modelData.nResiduals = 1; + data->modelData.nExtObjs = 0; + data->modelData.nFunctions = 0; + data->modelData.nEquations = 4; + + data->modelData.nDelayExpressions = 0; + +} + +void setupDataStruc2(DATA *data) +{ + const struct FUNCTION_INFO funcInfo[1] = {{-1,"",omc_dummyFileInfo}}; + memcpy(data->modelData.functionNames, &funcInfo, data->modelData.nFunctions*sizeof(FUNCTION_INFO)); + + const VAR_INFO** equationInfo_cref1 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref1[0] = &$Pvalve__varInfo; + const VAR_INFO** equationInfo_cref3 = (const VAR_INFO**)calloc(1,sizeof(VAR_INFO*)); + equationInfo_cref3[0] = &$P$DER$Pstock__varInfo; + const struct EQUATION_INFO equationInfo[4] = { + {1003,"SES_ALGORITHM 0", 0, NULL}, + {1004,"SES_SIMPLE_ASSIGN 1",1,equationInfo_cref1}, + {1005,"SES_ALGORITHM 2", 0, NULL}, + {1006,"SES_SIMPLE_ASSIGN 3",1,equationInfo_cref3} + }; + const int n_omc_equationInfo_reverse_prof_index = 0; + const int omc_equationInfo_reverse_prof_index[] = { + + }; + memcpy(data->modelData.equationInfo, &equationInfo, data->modelData.nEquations*sizeof(EQUATION_INFO)); + + data->modelData.nProfileBlocks = n_omc_equationInfo_reverse_prof_index; + data->modelData.equationInfo_reverse_prof_index = (int*) malloc(data->modelData.nProfileBlocks*sizeof(int)); + memcpy(data->modelData.equationInfo_reverse_prof_index, omc_equationInfo_reverse_prof_index, data->modelData.nProfileBlocks*sizeof(int)); +} + +/* Has to be performed after _init.xml file has been read */ +void callExternalObjectConstructors(DATA *data) +{ + state mem_state; + mem_state = get_memory_state(); + /* data->simulationInfo.extObjs = NULL; */ +} + +void callExternalObjectDestructors(DATA *data) +{ + if (data->simulationInfo.extObjs) { + free(data->simulationInfo.extObjs); + data->simulationInfo.extObjs = 0; + } +} + + +int input_function(DATA *data) +{ + return 0; +} + +int output_function(DATA *data) +{ + return 0; +} + +/* Initializes the raw time events of the simulation using the now + calcualted parameters. */ +void function_sampleInit(DATA *data) +{ +} + +int function_updateSample(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int function_storeDelayed(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundStartValues(DATA *data) +{ + + + DEBUG_INFO(LOG_INIT, "updating start-values:"); + + return 0; +} + +int initial_residual(DATA *data, double $P$_lambda, double* initialResiduals) +{ + int i = 0; + state mem_state; + + mem_state = get_memory_state(); + DEBUG_INFO(LOG_RES_INIT, "updating initial_residuals:"); + initialResiduals[i++] = ((1.0 - $P$_lambda) * ($Pstock - $P$START$Pstock)); + DEBUG_INFO_AL2(LOG_RES_INIT, " residual[%d] : (1.0 - $_lambda) * (stock - $_start(stock)) = %f", i, initialResiduals[i-1]); + restore_memory_state(mem_state); + + return 0; +} + +int updateBoundParameters(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_0(DATA *data) { + modelica_boolean tmp0; + modelica_boolean tmp1; + modelica_boolean tmp2; + /*#modelicaLine [FMURealTest.mo:8:2-8:74]*/ + tmp0 = initial(); + RELATIONTOZC(tmp1, $Pr1, 0.0, -1,Less,<); + RELATIONTOZC(tmp2, $Pr1, 0.0, -1,GreaterEq,>=); + $Pvalve = (((tmp0 || tmp1) || tmp2)?($Pr1 + $Pr2):$P$PRE$Pvalve); + /*#endModelicaLine*/ +} + + +void eqFunction_1(DATA *data) { + /*#modelicaLine [FMURealTest.mo:9:2-9:20]*/ + $P$DER$Pstock = $Pvalve; + /*#endModelicaLine*/ +} + +static void functionODE_system0(DATA *data,int omc_thread_number) +{ + eqFunction_0(data); + eqFunction_1(data); +} +static void (*functionODE_systems[1])(DATA *, int) = { + functionODE_system0 +}; + +void function_initMemoryState() +{ + push_memory_states(1); +} + +int functionODE(DATA *data) +{ + int id,th_id; + state mem_state; /* We need to have separate memory pools for separate systems... */ + mem_state = get_memory_state(); + for (id=0; id<1; id++) { + th_id = omp_get_thread_num(); + functionODE_systems[id](data,th_id); + } + restore_memory_state(mem_state); + + return 0; +} +#include +const char *_omc_force_solver=_OMC_FORCE_SOLVER; +const int inline_work_states_ndims=_OMC_SOLVER_WORK_STATES_NDIMS; +int functionODE_inline(DATA* data, double stepSize) +{ + return 0; +} + +/* for continuous time variables */ +int functionAlgebraics(DATA *data) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + + +void eqFunction_2(DATA *data) { + modelica_boolean tmp4; + modelica_boolean tmp5; + modelica_boolean tmp6; + /*#modelicaLine [FMURealTest.mo:8:2-8:74]*/ + tmp4 = initial(); + SAVEZEROCROSS(tmp5, $Pr1, 0.0, -1,Less,<); + SAVEZEROCROSS(tmp6, $Pr1, 0.0, -1,GreaterEq,>=); + $Pvalve = (((tmp4 || tmp5) || tmp6)?($Pr1 + $Pr2):$P$PRE$Pvalve); + /*#endModelicaLine*/ +} + + +void eqFunction_3(DATA *data) { + /*#modelicaLine [FMURealTest.mo:9:2-9:20]*/ + $P$DER$Pstock = $Pvalve; + /*#endModelicaLine*/ +} + +int functionDAE(DATA *data, int *needToIterate) +{ + state mem_state; + *needToIterate = 0; + + mem_state = get_memory_state(); + eqFunction_2(data); + eqFunction_3(data); + restore_memory_state(mem_state); + + return 0; +} + +int function_onlyZeroCrossings(DATA *data, double *gout,double *t) +{ + state mem_state; + + mem_state = get_memory_state(); + restore_memory_state(mem_state); + + return 0; +} + +int checkForDiscreteChanges(DATA *data) +{ + int needToIterate = 0; + + + return needToIterate; +} + +/* function to check assert after a step is done */ +int checkForAsserts(DATA *data) +{ + + + return 0; +} + + int initialAnalyticJacobianA(DATA* data){ + return 1; + } + + int initialAnalyticJacobianB(DATA* data){ + return 1; + } + + int initialAnalyticJacobianC(DATA* data){ + return 1; + } + + int initialAnalyticJacobianD(DATA* data){ + return 1; + } + int functionJacA(DATA* data, double* jac){ + return 0; + } + + int functionJacB(DATA* data, double* jac){ + return 0; + } + + int functionJacC(DATA* data, double* jac){ + return 0; + } + + int functionJacD(DATA* data, double* jac){ + return 0; + } + +const char *linear_model_frame = + "model linear_FMURealTestModel\n parameter Integer n = 1; // states \n parameter Integer k = 0; // top-level inputs \n parameter Integer l = 0; // top-level outputs \n" + " parameter Real x0[1] = {%s};\n" + " parameter Real u0[0] = {%s};\n" + " parameter Real A[1,1] = [%s];\n" + " parameter Real B[1,0] = zeros(1,0);%s\n" + " parameter Real C[0,1] = zeros(0,1);%s\n" + " parameter Real D[0,0] = zeros(0,0);%s\n" + " Real x[1](start=x0);\n" + " input Real u[0];\n" + " output Real y[0];\n" + "\n Real x_Pstock = x[1];\n \n" + "equation\n der(x) = A * x + B * u;\n y = C * x + D * u;\nend linear_FMURealTestModel;\n" +; + +#ifdef __cplusplus +} +#endif + +/* forward the main in the simulation runtime */ +extern int _main_SimulationRuntime(int argc, char**argv, DATA *data); + +/* call the simulation runtime main from our main! */ +int main(int argc, char**argv) +{ + DATA data; + setupDataStruc(&data); + return _main_SimulationRuntime(argc, argv, &data); +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.dll b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.dll new file mode 100644 index 00000000..26fbfce4 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.dll differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.fmu b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.fmu new file mode 100644 index 00000000..097ed6cd Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.fmu differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.lib b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.lib new file mode 100644 index 00000000..ae85129d Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel.lib differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_FMU.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_FMU.c new file mode 100644 index 00000000..facd7f64 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_FMU.c @@ -0,0 +1,159 @@ + +// define class name and unique id +#define MODEL_IDENTIFIER FMURealTestModel +#define MODEL_GUID "{7cae105e-c592-4723-8ae7-041b2a1231d7}" + +// include fmu header files, typedefs and macros +#include +#include +#include +#include "openmodelica.h" +#include "openmodelica_func.h" +#include "simulation_data.h" +#include "omc_error.h" +#include "fmiModelTypes.h" +#include "fmiModelFunctions.h" +#include "FMURealTestModel_functions.h" +#include "initialization.h" +#include "events.h" +#include "fmu_model_interface.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void setStartValues(ModelInstance *comp); +void setDefaultStartValues(ModelInstance *comp); +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo); +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value); +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value); +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value); +fmiString getString(ModelInstance* comp, const fmiValueReference vr); +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value); + +// define model size +#define NUMBER_OF_STATES 1 +#define NUMBER_OF_EVENT_INDICATORS 0 +#define NUMBER_OF_REALS 6 +#define NUMBER_OF_INTEGERS 0 +#define NUMBER_OF_STRINGS 0 +#define NUMBER_OF_BOOLEANS 0 +#define NUMBER_OF_EXTERNALFUNCTIONS 0 + +// define variable data for model +#define $Pstock_ 0 +#define $P$DER$Pstock_ 1 +#define $Pvalve_ 2 +#define $Pr1_ 3 +#define $Pr2_ 4 +#define time_ 5 + + +// define initial state vector as vector of value references +#define STATES { $Pstock_ } +#define STATESDERIVATIVES { $P$DER$Pstock_ } + + +// implementation of the Model Exchange functions +#include "fmu_model_interface.c" + +// Set values for all variables that define a start value +void setDefaultStartValues(ModelInstance *comp) { + +comp->fmuData->modelData.realVarsData[0].attribute.start = 0.0; +comp->fmuData->modelData.realParameterData[0].attribute.start = 1.0; +comp->fmuData->modelData.realParameterData[1].attribute.start = 1.0; +comp->fmuData->modelData.realParameterData[2].attribute.start = 0.0; +} +// Set values for all variables that define a start value +void setStartValues(ModelInstance *comp) { + + comp->fmuData->modelData.realVarsData[0].attribute.start = comp->fmuData->localData[0]->realVars[0]; + comp->fmuData->modelData.realVarsData[1].attribute.start = comp->fmuData->localData[0]->realVars[1]; + comp->fmuData->modelData.realVarsData[2].attribute.start = comp->fmuData->localData[0]->realVars[2]; +comp->fmuData->modelData.realParameterData[0].attribute.start = comp->fmuData->simulationInfo.realParameter[0]; +comp->fmuData->modelData.realParameterData[1].attribute.start = comp->fmuData->simulationInfo.realParameter[1]; +comp->fmuData->modelData.realParameterData[2].attribute.start = comp->fmuData->simulationInfo.realParameter[2]; +} +// Used to set the next time event, if any. +void eventUpdate(ModelInstance* comp, fmiEventInfo* eventInfo) { +} + +fmiReal getReal(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + case $Pstock_ : return comp->fmuData->localData[0]->realVars[0]; break; + case $P$DER$Pstock_ : return comp->fmuData->localData[0]->realVars[1]; break; + case $Pvalve_ : return comp->fmuData->localData[0]->realVars[2]; break; + case $Pr1_ : return comp->fmuData->simulationInfo.realParameter[0]; break; + case $Pr2_ : return comp->fmuData->simulationInfo.realParameter[1]; break; + case time_ : return comp->fmuData->simulationInfo.realParameter[2]; break; + default: + return fmiError; + } +} + +fmiStatus setReal(ModelInstance* comp, const fmiValueReference vr, const fmiReal value) { + switch (vr) { + case $Pstock_ : comp->fmuData->localData[0]->realVars[0]=value; break; + case $P$DER$Pstock_ : comp->fmuData->localData[0]->realVars[1]=value; break; + case $Pvalve_ : comp->fmuData->localData[0]->realVars[2]=value; break; + case $Pr1_ : comp->fmuData->simulationInfo.realParameter[0]=value; break; + case $Pr2_ : comp->fmuData->simulationInfo.realParameter[1]=value; break; + case time_ : comp->fmuData->simulationInfo.realParameter[2]=value; break; + default: + return fmiError; + } + return fmiOK; +} + +fmiInteger getInteger(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} +fmiStatus setInteger(ModelInstance* comp, const fmiValueReference vr, const fmiInteger value) { + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} +fmiBoolean getBoolean(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} + +fmiStatus setBoolean(ModelInstance* comp, const fmiValueReference vr, const fmiBoolean value) { + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} + +fmiString getString(ModelInstance* comp, const fmiValueReference vr) { + switch (vr) { + default: + return 0; + } +} + +fmiStatus setExternalFunction(ModelInstance* c, const fmiValueReference vr, const void* value){ + switch (vr) { + default: + return fmiError; + } + return fmiOK; +} + + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_functions.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_functions.c new file mode 100644 index 00000000..3f150b10 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_functions.c @@ -0,0 +1,16 @@ +#include "FMURealTestModel_functions.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define _OMC_LIT0_data "'p" +static const size_t _OMC_LIT0_strlen = 2; +static const char _OMC_LIT0[3] = _OMC_LIT0_data; +#define _OMC_LIT1_data "'p/s" +static const size_t _OMC_LIT1_strlen = 4; +static const char _OMC_LIT1[5] = _OMC_LIT1_data; + +#ifdef __cplusplus +} +#endif + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_functions.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_functions.h new file mode 100644 index 00000000..1dedb2ae --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_functions.h @@ -0,0 +1,17 @@ +#ifndef FMURealTestModel__H +#define FMURealTestModel__H +#define omp_get_thread_num() 0 +#include "modelica.h" +#include +#include +#include +#include "simulation_runtime.h" +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_records.c b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_records.c new file mode 100644 index 00000000..8cfdfcf5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/FMURealTestModel_records.c @@ -0,0 +1,3 @@ +/* Additional record code for FMURealTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#include "meta_modelica.h" + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/_FMURealTestModel.h b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/_FMURealTestModel.h new file mode 100644 index 00000000..ede4615f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/_FMURealTestModel.h @@ -0,0 +1,40 @@ +/* Simulation code for FMURealTestModel generated by the OpenModelica Compiler 1.8.1+ (r11690). */ +#define time data->localData[0]->timeValue + +/* States */ +#define _$Pstock(i) data->localData[i]->realVars[0] +#define $Pstock _$Pstock(0) +#define $P$PRE$Pstock data->simulationInfo.realVarsPre[0] +#define $P$START$Pstock data->modelData.realVarsData[0].attribute.start +#define $Pstock__varInfo data->modelData.realVarsData[0].info +/* StatesDerivatives */ +#define _$P$DER$Pstock(i) data->localData[i]->realVars[1] +#define $P$DER$Pstock _$P$DER$Pstock(0) +#define $P$PRE$P$DER$Pstock data->simulationInfo.realVarsPre[1] +#define $P$START$P$DER$Pstock data->modelData.realVarsData[1].attribute.start +#define $P$DER$Pstock__varInfo data->modelData.realVarsData[1].info +/* Algebraic Vars */ +#define _$Pvalve(i) data->localData[i]->realVars[2] +#define $Pvalve _$Pvalve(0) +#define $P$PRE$Pvalve data->simulationInfo.realVarsPre[2] +#define $P$START$Pvalve data->modelData.realVarsData[2].attribute.start +#define $Pvalve__varInfo data->modelData.realVarsData[2].info +/* Algebraic Parameter */ +#define $Pr1 data->simulationInfo.realParameter[0] +#define $P$START$Pr1 data->modelData.realParameterData[0].attribute.start +#define $Pr1__varInfo data->modelData.realParameterData[0].info +#define $Pr2 data->simulationInfo.realParameter[1] +#define $P$START$Pr2 data->modelData.realParameterData[1].attribute.start +#define $Pr2__varInfo data->modelData.realParameterData[1].info +#define time data->simulationInfo.realParameter[2] +#define $P$STARTtime data->modelData.realParameterData[2].attribute.start +#define time__varInfo data->modelData.realParameterData[2].info +/* External Objects */ +/* Algebraic Integer Vars */ +/* Algebraic Integer Parameter */ +/* Algebraic Boolean Vars */ +/* Algebraic Boolean Parameters */ +/* Algebraic String Variables */ +/* Algebraic String Parameter */ +/* Jacobian Variables */ + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/modelDescription.xml b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/modelDescription.xml new file mode 100644 index 00000000..93a288c7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMURealTest/modelDescription.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUUnitTestModel.fmu b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUUnitTestModel.fmu new file mode 100644 index 00000000..2b910656 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.tests/Models/FMUTests/FMUUnitTestModel.fmu differ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/build.properties b/dev-jkauttio/org.simantics.sysdyn.tests/build.properties new file mode 100644 index 00000000..098add78 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + Models/ diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/Activator.java b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/Activator.java new file mode 100644 index 00000000..aadaff3f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/Activator.java @@ -0,0 +1,30 @@ +package org.simantics.sysdyn.tests; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/CallFMUBeforeInitializationTests.java b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/CallFMUBeforeInitializationTests.java new file mode 100644 index 00000000..c3974d9e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/CallFMUBeforeInitializationTests.java @@ -0,0 +1,229 @@ +package org.simantics.sysdyn.tests.fmi; + +import static org.junit.Assert.fail; +import junit.framework.Assert; + +import org.junit.Test; +import org.simantics.modelica.fmi.FMUControlJNI; +import org.simantics.modelica.fmi.FMUJNIException; + +/** + * Tests calls to fmu control before model has been loaded or initialized. + * + * @author Teemu Lempinen + * + */ +public class CallFMUBeforeInitializationTests { + + /** + * Try fmu jni methods without loading an fmu. + * All but unload should throw an exception. + */ + @Test + public void testBeforeLoad() { + FMUControlJNI control = new FMUControlJNI(); + + try { + control.initializeSimulation(); + fail("Initialized a simulation before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: Tried to initialize simulation before loading it + } + + try { + control.getAllVariables(); + fail("getAllVariables returned something before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There is no model to get the variables from + } + + try { + control.filterVariables(".*"); + fail("filterVariables returned something before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There is no model to get the variables from + } + + try { + double d = control.getRealValue("dummy"); + fail("Got a Real value before loading fmu: " + d); + } catch (FMUJNIException e) { + // control should throw this exception: There are no variables + } + + try { + control.getSubscribedResults(new double[0]); + fail("Got subscribed results before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There is no model or subscription + } + + try { + control.setBooleanValue("dummy", true); + fail("Set a boolean value before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There are no variables + } + + try { + control.setRealValue("dummy", 1.0); + fail("Set a real value before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There are no variables + } + + try { + control.setIntegerValue("dummy", 1); + fail("Set an integer value before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There are no variables + } + + try { + control.setStepLength(0.1); + fail("Set step length before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There is no model for which to set the step length + } + + try { + control.simulateStep(); + fail("Simulated a step before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There is no model to simulate + } + + try { + control.subscribe(new String[] {"dummy"}); + fail("Subscribed variables before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There is no model to subscribe from + } + + + // succeeds + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + // control should NOT throw this exception: Unload only unloads if something has been loaded + fail(e.getMessage()); + } + + } + + /* + * Test: + * Load a valid fmu, but do not initialize it. Test that all + * methods work as they are supposed to. Some throw exceptions while + * others work. + */ + @Test + public void testBeforeInitialization() { + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMUAllTypesOfVariablesTest\\FMUAllTypesOfVariablesTestModel.fmu"; + + // Initialize a model + try { + + control.loadFMUFile(path); + } catch (FMUJNIException e) { + fail("FMU loading failed"); + } + + // Fails + + try { + double d = control.getRealValue("dummy"); + fail("Got a Real value before loading fmu: " + d); + } catch (FMUJNIException e) { + // control should throw this exception: There are no variables + } + + try { + control.setBooleanValue("dummy", true); + fail("Set a boolean value before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There are no variables + } + + try { + control.setRealValue("dummy", 1.0); + fail("Set a real value before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There are no variables + } + + try { + control.setIntegerValue("dummy", 1); + fail("Set an integer value before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There are no variables + } + + try { + control.simulateStep(); + fail("Simulated a step before loading fmu"); + } catch (FMUJNIException e) { + // control should throw this exception: There is no model to simulate + } + + + + // Succeeds + try { + control.setStepLength(0.1); + } catch (FMUJNIException e) { + // control should NOT throw this exception: simulation step length can be set + // beforehand for future simulations + fail(e.getMessage()); + } + + try { + control.getAllVariables(); + } catch (FMUJNIException e) { + // control should NOT throw this exception: Variables are found in loadFMU + fail(e.getMessage()); + } + + try { + control.filterVariables(".*"); + } catch (FMUJNIException e) { + // control should NOT throw this exception: Variables are found in loadFMU + fail(e.getMessage()); + } + + + try { + double[] array = new double[0]; + control.getSubscribedResults(array); + Assert.assertTrue("Returned a wrong kind of array", array.length == 0); + } catch (FMUJNIException e) { + // control should NOT throw this exception: Should return the given double + // array filled with subscribed values or 0.0 if there was some problem + fail(e.getMessage()); + } + + try { + control.subscribe(new String[] {"dummy"}); + } catch (FMUJNIException e) { + // control should NOT throw this exception: users can subscribe before initialization + fail(e.getMessage()); + } + + + try { + control.initializeSimulation(); + } catch (FMUJNIException e) { + fail(e.getMessage()); + // control should NOT throw this exception + } + + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + // control should NOT throw this exception + fail(e.getMessage()); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUBooleanTest.java b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUBooleanTest.java new file mode 100644 index 00000000..1ba94231 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUBooleanTest.java @@ -0,0 +1,194 @@ +package org.simantics.sysdyn.tests.fmi; + +import java.util.Arrays; +import java.util.List; + +import junit.framework.Assert; + +import org.junit.Test; +import org.simantics.modelica.fmi.FMUControlJNI; +import org.simantics.modelica.fmi.FMUJNIException; + +/** + * Tests that a boolean value can be changed, erroneous values and variables are detected + * and the change is propagated to the rest of the model. + * + * @author Teemu Lempinen + * + */ +public class FMUBooleanTest { + + @Test + public void testSetBoolean() { + + /* + Below is the model used for testing. + Model is located in Models\FMUTests\FMUBooleanTest + + model FMUBooleanTestModel + parameter Boolean b = true; + Real valve; + Real stock(start=0.0,fixed=true); + parameter Real time = 0; // Time parameter is set at each time step by simulator + equation + valve = if initial() or b or not b then (if b then 1 else -1) else pre(valve); + der(stock) = valve; + end FMUBooleanTestModel; + + + The condition for valve is automatically generated in sysdyn. It is a hack for getting + valve to notice a change in b. + */ + + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMUBooleanTest\\FMUBooleanTestModel.fmu"; + + + try { + + control.loadFMUFile(path); + + control.setStepLength(0.1); + + control.initializeSimulation(); + + + String[] s = control.getAllVariables(); + List nameList = Arrays.asList(s); + int valve = nameList.indexOf("valve"); + int stock = nameList.indexOf("stock"); + control.subscribe(s); + + /* + * Simulate the model for time 0 - 3 with b == true + * => stock == 3 when time == 3 + * + * Change b to false and simulate to time == 6 + * => stock == 0 when time == 6 + */ + double value; + double[] results = new double[s.length]; + for(int i = 0; i < 60; i++) { + results = control.getSubscribedResults(results); + + if(i == 30) { + value = results[stock]; + Assert.assertFalse("stock != 3 when time == 3. (stock == " + value + ")", value < 2.999 || value > 3.001); + control.setBooleanValue("b", false); + } + + value = results[valve]; + if(i > 30) { + Assert.assertFalse("valve != -1 after time == 3. (valve == " + value + ")", value > -0.999 || value < -1.001); + } else { + Assert.assertFalse("valve != 1 before time == 3. (valve == " + value + ")", value < 0.999 || value > 1.001); + + } + control.simulateStep(); + } + + results = control.getSubscribedResults(results); + value = results[stock]; + Assert.assertFalse("stock != 0 when time == 6. (stock == " + value + ")", value < -0.001 || value > 0.001); + + + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + } + + + @Test + public void testSetBooleanErrors() { + + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMUAllTypesOfVariablesTest\\FMUAllTypesOfVariablesTestModel.fmu"; + + // Initialize a model + try { + + control.loadFMUFile(path); + + control.loadFMUFile(path); + + control.setStepLength(0.1); + + control.initializeSimulation(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + + // Try to set value to a dummy variable + try { + control.setBooleanValue("dummy", true); + Assert.fail("Succeeded in setting a Boolean value to a dummy variable"); + } catch (FMUJNIException e) { + // Exception should be thrown: no such variable + } + + // Try to set value to a Real variable + try { + control.setBooleanValue("r", true); + Assert.fail("Succeeded in setting a Boolean value to a Real variable"); + } catch (FMUJNIException e) { + // Exception should be thrown + } + + // Try to set value to an Integer variable + try { + control.setBooleanValue("i", true); + Assert.fail("Succeeded in setting a Boolean value to an Integer variable"); + } catch (FMUJNIException e) { + // Exception should be thrown + } + + // Try to set value to a continuous Real variable + try { + control.setBooleanValue("continuousReal", true); + Assert.fail("Succeeded in setting a Boolean value to a continuous Real variable"); + } catch (FMUJNIException e) { + // Exception should be thrown + } + + // Try to set value to a discrete Integer variable + try { + control.setBooleanValue("discreteInteger", true); + Assert.fail("Succeeded in setting a Boolean value to a discrete Integer variable"); + } catch (FMUJNIException e) { + // Exception should be thrown + } + + + /*** SUCCEEDS ***/ + // For reference, set a boolean value + try { + control.setBooleanValue("b", true); + } catch (FMUJNIException e) { + Assert.fail("Could not set a boolean value to boolean variable"); + } + + // Set a value to a variable that is not a parameter. This is possible, but should no affect the simulation + try { + control.setBooleanValue("discreteBoolean", true); + } catch (FMUJNIException e) { + Assert.fail("Could not set a boolean value to discrete boolean variable"); + } + + // Unload model + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUControlTestSuite.java b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUControlTestSuite.java new file mode 100644 index 00000000..89b1e1cf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUControlTestSuite.java @@ -0,0 +1,25 @@ +package org.simantics.sysdyn.tests.fmi; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * Test suite for testing fmu functionalities. + * + * Tests are independent. + * + * @author Teemu Lempinen + * + */ +@RunWith(Suite.class) +@SuiteClasses({ + LoadFMUFileFailTests.class, + CallFMUBeforeInitializationTests.class, + FMUIntegerTest.class, + FMUBooleanTest.class, + FMURealTest.class, + FMUResultFilterTest.class}) +public class FMUControlTestSuite { + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUIntegerTest.java b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUIntegerTest.java new file mode 100644 index 00000000..70bad9f1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUIntegerTest.java @@ -0,0 +1,198 @@ +package org.simantics.sysdyn.tests.fmi; + +import java.util.Arrays; +import java.util.List; + +import junit.framework.Assert; + +import org.junit.Test; +import org.simantics.modelica.fmi.FMUControlJNI; +import org.simantics.modelica.fmi.FMUJNIException; + +/** + * Tests that an integer value can be changed and the change is propagated + * to the rest of the model. + * + * @author Teemu Lempinen + * + */ +public class FMUIntegerTest { + + + + @Test + public void test() { + + /* + Below is the model used for testing. + Model is located in Models\FMUTests\FMUIntegerTest + + model FMUIntegerTestModel + parameter Integer i1 = 1; + parameter Integer i2 = 1; + Real valve; + Real stock(start=0.0,fixed=true); + parameter Real time = 0; // Time parameter is set at each time step by simulator + equation + valve = if initial() or i1 < 0 or i1 >= 0 then (i1 + i2) else pre(valve); + der(stock) = valve; + end FMUIntegerTestModel; + + + The condition for valve is automatically generated in sysdyn. It is a hack for getting + valve to notice a change in i1 and i2. + */ + + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMUIntegerTest\\FMUIntegerTestModel.fmu"; + + + try { + + control.loadFMUFile(path); + + control.setStepLength(0.1); + + control.initializeSimulation(); + + + String[] s = control.getAllVariables(); + List nameList = Arrays.asList(s); + int valve = nameList.indexOf("valve"); + int stock = nameList.indexOf("stock"); + control.subscribe(s); + + /* + * Simulate the model for time 0 - 3 with i1==1 and i2==1 + * => stock == 6 when time == 3 + * + * Change i1 to 3 and simulate to time == 6 + * => stock == 18 when time == 6 + */ + double value; + double[] results = new double[s.length]; + for(int i = 0; i < 60; i++) { + results = control.getSubscribedResults(results); + + if(i == 30) { + value = results[stock]; + Assert.assertFalse("stock != 6 when time == 3. (stock == " + value + ")", value < 5.999 || value > 6.001); + control.setIntegerValue("i1", 3); + } + + value = results[valve]; + if(i > 30) { + Assert.assertFalse("valve != 4 after time == 3. (valve == " + value + ")", value < 3.999 || value > 4.001); + } else { + Assert.assertFalse("valve != 2 before time == 3. (valve == " + value + ")", value < 1.999 || value > 2.001); + + } + control.simulateStep(); + } + + results = control.getSubscribedResults(results); + value = results[stock]; + Assert.assertFalse("stock != 18 when time == 6. (stock == " + value + ")", value < 17.999 || value > 18.001); + + + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + } + + @Test + public void testSetIntegerErrors() { + + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMUAllTypesOfVariablesTest\\FMUAllTypesOfVariablesTestModel.fmu"; + + // Initialize a model + try { + + control.loadFMUFile(path); + + control.setStepLength(0.1); + + control.initializeSimulation(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + + // Try to set value to a dummy variable + try { + control.setIntegerValue("dummy", 1); + Assert.fail("Succeeded in setting an Integer value to a dummy variable"); + } catch (FMUJNIException e) { + // Exception should be thrown: no such variable + } + + // Try to set a Boolean value to an Integer variable + try { + control.setIntegerValue("b", 1); + Assert.fail("Succeeded in setting an Integer value to an Integer variable"); + } catch (FMUJNIException e) { + // Exception should be thrown + } + + // Try to set a Boolean value to a discrete Integer variable + try { + control.setIntegerValue("discreteBoolean", 1); + Assert.fail("Succeeded in setting an Integer value to a discrete Integer variable"); + } catch (FMUJNIException e) { + // Exception should be thrown + } + + // Try to set value to a Real variable + try { + control.setIntegerValue("r", 1); + Assert.fail("Succeeded in setting an Integer value to a Real variable"); + } catch (FMUJNIException e) { + // Exception should be thrown + } + + + + // Try to set value to a continuous Real variable + try { + control.setIntegerValue("continuousReal", 1); + Assert.fail("Succeeded in setting a Boolean value to a continuous Real variable"); + } catch (FMUJNIException e) { + // Exception should be thrown + } + + + + + /*** SUCCEEDS ***/ + + // For reference, set an integer value + try { + control.setIntegerValue("i", 1); + } catch (FMUJNIException e) { + Assert.fail("Could not set an integer value to integer variable"); + } + + // Set a value to a variable that is not a parameter. This is possible, but should no affect the simulation + try { + control.setIntegerValue("discreteInteger", 1); + } catch (FMUJNIException e) { + Assert.fail("Could not set an integer value to discrete integer variable"); + } + + // Unload model + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMURealTest.java b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMURealTest.java new file mode 100644 index 00000000..f996b7a9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMURealTest.java @@ -0,0 +1,109 @@ +package org.simantics.sysdyn.tests.fmi; + +import java.util.Arrays; +import java.util.List; + +import junit.framework.Assert; + +import org.junit.Test; +import org.simantics.modelica.fmi.FMUControlJNI; +import org.simantics.modelica.fmi.FMUJNIException; + +/** + * Tests that a real value can be changed and the change is propagated + * to the rest of the model. + * + * @author Teemu Lempinen + * + */ +public class FMURealTest { + + /* + Below is the model used for testing. + Model is located in Models\FMUTests\FMURealTest + + model FMURealTestModel + parameter Real r1 = 1.0; + parameter Real r2 = 1.0; + Real valve; + Real stock(start=0.0,fixed=true); + parameter Real time = 0; // Time parameter is set at each time step by simulator + equation + if initial() or r1 < 0 or r1 >= 0 then (r1 + r2) else pre(valve); + der(stock) = valve; + end FMURealTestModel; + + + The condition for valve is automatically generated in sysdyn. It is a hack for getting + valve to notice a change in i1 and i2. + */ + + @Test + public void test() { + + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMURealTest\\FMURealTestModel.fmu"; + + + try { + + control.loadFMUFile(path); + + control.setStepLength(0.1); + + control.initializeSimulation(); + + + String[] s = control.getAllVariables(); + List nameList = Arrays.asList(s); + int valve = nameList.indexOf("valve"); + int stock = nameList.indexOf("stock"); + control.subscribe(s); + + /* + * Simulate the model for time 0 - 3 with r1==1 and r2==1 + * => stock == 6 when time == 3 + * + * Change r1 to 3 and simulate to time == 6 + * => stock == 18 when time == 6 + */ + double value; + double[] results = new double[s.length]; + for(int i = 0; i < 60; i++) { + results = control.getSubscribedResults(results); + + if(i == 30) { + value = results[stock]; + Assert.assertFalse("stock != 6 when time == 3. (stock == " + value + ")", value < 5.999 || value > 6.001); + control.setRealValue("r1", 3); + } + + value = results[valve]; + if(i > 30) { + Assert.assertFalse("valve != 4 after time == 3. (valve == " + value + ")", value < 3.999 || value > 4.001); + } else { + Assert.assertFalse("valve != 2 before time == 3. (valve == " + value + ")", value < 1.999 || value > 2.001); + + } + control.simulateStep(); + } + + results = control.getSubscribedResults(results); + value = results[stock]; + Assert.assertFalse("stock != 18 when time == 6. (stock == " + value + ")", value < 17.999 || value > 18.001); + + + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUResultFilterTest.java b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUResultFilterTest.java new file mode 100644 index 00000000..0cbb9f5a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/FMUResultFilterTest.java @@ -0,0 +1,142 @@ +package org.simantics.sysdyn.tests.fmi; + +import java.util.Arrays; +import java.util.List; + +import junit.framework.Assert; + +import org.junit.Test; +import org.simantics.modelica.fmi.FMUControlJNI; +import org.simantics.modelica.fmi.FMUJNIException; + + +/** + * Tests result filtering + * @author Teemu Lempinen + * + */ +public class FMUResultFilterTest { + + /* + Below is the model used for testing. + Model is located in Models\FMUTests\FMURealTest + + model FMURealTestModel + parameter Real r1 = 1.0; + parameter Real r2 = 1.0; + Real valve; + Real stock(start=0.0,fixed=true); + parameter Real time = 0; // Time parameter is set at each time step by simulator + equation + if initial() or r1 < 0 or r1 >= 0 then (r1 + r2) else pre(valve); + der(stock) = valve; + end FMURealTestModel; + + + The condition for valve is automatically generated in sysdyn. It is a hack for getting + valve to notice a change in i1 and i2. + + Results always contain "time" for each modelica class, hence result size is +1 + */ + + @Test + public void testReturn3() { + + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMURealTest\\FMURealTestModel.fmu"; + + + try { + + + + control.loadFMUFile(path); + + String[] bothRealParameters = control.filterVariables("r(.*)"); + Assert.assertEquals("Filter \"r(.*)\" returned " + bothRealParameters.length + " results. Should have returned 3", bothRealParameters.length, 3); + List result = Arrays.asList(bothRealParameters); + Assert.assertTrue("Result did not contain r1", result.contains("r1")); + Assert.assertTrue("Result did not contain r2", result.contains("r2")); + Assert.assertTrue("Result did not contain time", result.contains("time")); + + control.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + } + + @Test + public void testReturn2() { + + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMURealTest\\FMURealTestModel.fmu"; + + + try { + + control.loadFMUFile(path); + + String[] stock = control.filterVariables("stock"); + Assert.assertEquals("Filter \"stock\" returned " + stock.length + " results. Should have returned 2", stock.length, 2); + List result = Arrays.asList(stock); + Assert.assertTrue("Result did not contain stock", result.contains("stock")); + Assert.assertTrue("Result did not contain time", result.contains("time")); + + control.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + } + + @Test + public void testReturn1() { + + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMURealTest\\FMURealTestModel.fmu"; + + + try { + control.loadFMUFile(path); + + String[] empty = control.filterVariables("empty"); + Assert.assertEquals("Filter \"empty\" returned " + empty.length + " results. Should have returned 1", empty.length, 1); + + List result = Arrays.asList(empty); + Assert.assertTrue("Result did not contain time", result.contains("time")); + + control.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + } + + @Test + public void testReturn1WhenNullFilter() { + + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\FMURealTest\\FMURealTestModel.fmu"; + + + try { + control.loadFMUFile(path); + + String[] NULL = control.filterVariables(null); + Assert.assertEquals("Filter null returned " + NULL.length + " results. Should have returned 1", NULL.length, 1); + + List result = Arrays.asList(NULL); + Assert.assertTrue("Result did not contain time", result.contains("time")); + + control.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + } + + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/LoadFMUFileFailTests.java b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/LoadFMUFileFailTests.java new file mode 100644 index 00000000..c6f9b6c0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/LoadFMUFileFailTests.java @@ -0,0 +1,82 @@ +package org.simantics.sysdyn.tests.fmi; + +import static org.junit.Assert.*; + + +import org.junit.Test; +import org.simantics.modelica.fmi.FMUControlJNI; +import org.simantics.modelica.fmi.FMUJNIException; + +/** + * Test possible error situations in loading an fmu file to the control + * + * @author Teemu Lempinen + * + */ +public class LoadFMUFileFailTests { + + + @Test + public void testLoadNonExistingFile() { + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\Non-Existing.fmu"; + + try { + control.loadFMUFile(path); + fail("Loaded a non-existing file without throwing an exception"); + } catch (FMUJNIException e) { + // control should throw this exception: Tried to load a non-existing file + System.out.println(e.getMessage()); + } + + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + fail("Unload failed"); + } + } + + @Test + public void testLoadNonFMUFile() { + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\DummyFile.txt"; + + try { + control.loadFMUFile(path); + fail("Loaded a non-FMU file without throwing an exception"); + } catch (FMUJNIException e) { + // control should throw this exception: Tried to load an incorrect file + System.out.println(e.getMessage()); + } + + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + fail("Unload failed"); + } + } + + @Test + public void testLoadNonFMUFile2() { + FMUControlJNI control = new FMUControlJNI(); + + String path = ".\\Models\\FMUTests\\DummyFile.fmu"; // <- an empty text file with fmu-extension. not a valid fmu file + + try { + control.loadFMUFile(path); + fail("Loaded a non-FMU file without throwing an exception"); + } catch (FMUJNIException e) { + // control should throw this exception: Tried to load an incorrect file + } + + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + fail("Unload failed"); + } + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/MultipleSimultaneousFMUSimulationsTest.java b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/MultipleSimultaneousFMUSimulationsTest.java new file mode 100644 index 00000000..6a4d7aff --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/fmi/MultipleSimultaneousFMUSimulationsTest.java @@ -0,0 +1,159 @@ +package org.simantics.sysdyn.tests.fmi; + +import java.util.Arrays; +import java.util.List; + +import junit.framework.Assert; + +import org.junit.Test; +import org.simantics.modelica.fmi.FMUControlJNI; +import org.simantics.modelica.fmi.FMUJNIException; + +public class MultipleSimultaneousFMUSimulationsTest { + + + /** + * This test runs simultaneously {@link FMURealTest}, {@link FMUIntegerTest} and {@link FMUBooleanTest} to + * see that they do not conflict with each other. + */ + + @Test + public void testMultipleSimulations() { + + FMUControlJNI control1 = new FMUControlJNI(); + FMUControlJNI control2 = new FMUControlJNI(); + FMUControlJNI control3 = new FMUControlJNI(); + + String path1 = ".\\Models\\FMUTests\\FMURealTest\\FMURealTestModel.fmu"; + String path2 = ".\\Models\\FMUTests\\FMUIntegerTest\\FMUIntegerTestModel.fmu"; + String path3 = ".\\Models\\FMUTests\\FMUBooleanTest\\FMUBooleanTestModel.fmu"; + + try { + control1.loadFMUFile(path1); + control2.loadFMUFile(path2); + control3.loadFMUFile(path3); + + control1.setStepLength(0.1); + control2.setStepLength(0.1); + control3.setStepLength(0.1); + + control1.initializeSimulation(); + control2.initializeSimulation(); + control3.initializeSimulation(); + + + String[] s1 = control1.getAllVariables(); + String[] s2 = control2.getAllVariables(); + String[] s3 = control3.getAllVariables(); + + + List nameList1 = Arrays.asList(s1); + List nameList2 = Arrays.asList(s2); + List nameList3 = Arrays.asList(s3); + int valve1 = nameList1.indexOf("valve"); + int valve2 = nameList2.indexOf("valve"); + int valve3 = nameList3.indexOf("valve"); + + int stock1 = nameList1.indexOf("stock"); + int stock2 = nameList2.indexOf("stock"); + int stock3 = nameList3.indexOf("stock"); + + control1.subscribe(s1); + control2.subscribe(s2); + control3.subscribe(s3); + + + double value; + double[] results1 = new double[s1.length]; + double[] results2 = new double[s2.length]; + double[] results3 = new double[s3.length]; + + for(int i = 0; i < 60; i++) { + + // Real + results1 = control1.getSubscribedResults(results1); + + if(i == 30) { + value = results1[stock1]; + Assert.assertFalse("stock != 6 when time == 3. (stock == " + value + ")", value < 5.999 || value > 6.001); + control1.setRealValue("r1", 3); + } + + value = results1[valve1]; + if(i > 30) { + Assert.assertFalse("valve != 4 after time == 3. (valve == " + value + ")", value < 3.999 || value > 4.001); + } else { + Assert.assertFalse("valve != 2 before time == 3. (valve == " + value + ")", value < 1.999 || value > 2.001); + + } + control1.simulateStep(); + + // Integer + results2 = control2.getSubscribedResults(results2); + + if(i == 30) { + value = results2[stock2]; + Assert.assertFalse("stock != 6 when time == 3. (stock == " + value + ")", value < 5.999 || value > 6.001); + control2.setIntegerValue("i1", 3); + } + + value = results2[valve2]; + if(i > 30) { + Assert.assertFalse("valve != 4 after time == 3. (valve == " + value + ")", value < 3.999 || value > 4.001); + } else { + Assert.assertFalse("valve != 2 before time == 3. (valve == " + value + ")", value < 1.999 || value > 2.001); + + } + control2.simulateStep(); + + // Boolean + results3 = control3.getSubscribedResults(results3); + + if(i == 30) { + value = results3[stock3]; + Assert.assertFalse("stock != 3 when time == 3. (stock == " + value + ")", value < 2.999 || value > 3.001); + control3.setBooleanValue("b", false); + } + + value = results3[valve3]; + if(i > 30) { + Assert.assertFalse("valve != -1 after time == 3. (valve == " + value + ")", value > -0.999 || value < -1.001); + } else { + Assert.assertFalse("valve != 1 before time == 3. (valve == " + value + ")", value < 0.999 || value > 1.001); + + } + control3.simulateStep(); + + } + + // Real + results1 = control1.getSubscribedResults(results1); + value = results1[stock1]; + Assert.assertFalse("stock != 18 when time == 6. (stock == " + value + ")", value < 17.999 || value > 18.001); + + // Integer + results2 = control2.getSubscribedResults(results2); + value = results2[stock2]; + Assert.assertFalse("stock != 18 when time == 6. (stock == " + value + ")", value < 17.999 || value > 18.001); + + // Boolean + results3 = control3.getSubscribedResults(results3); + value = results3[stock3]; + Assert.assertFalse("stock != 0 when time == 6. (stock == " + value + ")", value < -0.001 || value > 0.001); + + + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + + try { + control1.unloadFMU(); + control2.unloadFMU(); + control3.unloadFMU(); + } catch (FMUJNIException e) { + Assert.fail("Exception in native fmu code: " + e.getMessage()); + } + + } +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/.classpath b/dev-jkauttio/org.simantics.sysdyn.ui.old/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/.project b/dev-jkauttio/org.simantics.sysdyn.ui.old/.project new file mode 100644 index 00000000..2ebd5691 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/.project @@ -0,0 +1,28 @@ + + + org.simantics.sysdyn.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.sysdyn.ui.old/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..6d816954 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Thu Nov 05 12:45:23 EET 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.sysdyn.ui.old/META-INF/MANIFEST.MF new file mode 100644 index 00000000..33131cad --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Ui +Bundle-SymbolicName: org.simantics.sysdyn.ui;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.sysdyn.ui.Activator +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.simantics.ui;bundle-version="1.0.0", + org.simantics.diagram;bundle-version="1.0.0", + org.simantics.db;bundle-version="0.6.2", + org.simantics.db.common;bundle-version="0.6.2", + org.simantics.db.layer0;bundle-version="0.7.0", + org.simantics.g2d;bundle-version="1.0.0", + org.simantics.scenegraph;bundle-version="1.0.0", + org.simantics.layer0.utils;bundle-version="0.6.2" +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/adapters.xml b/dev-jkauttio/org.simantics.sysdyn.ui.old/adapters.xml new file mode 100644 index 00000000..86c2aa36 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/adapters.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/build.properties b/dev-jkauttio/org.simantics.sysdyn.ui.old/build.properties new file mode 100644 index 00000000..6f20375d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/plugin.xml b/dev-jkauttio/org.simantics.sysdyn.ui.old/plugin.xml new file mode 100644 index 00000000..cac6482e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/plugin.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/Activator.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/Activator.java new file mode 100644 index 00000000..21342378 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/Activator.java @@ -0,0 +1,50 @@ +package org.simantics.sysdyn.ui; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.simantics.sysdyn.ui"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/SysdynResource.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/SysdynResource.java new file mode 100644 index 00000000..426b3220 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/SysdynResource.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2007- VTT Technical Research Centre of Finland. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui; + + +import org.simantics.db.Resource; +import org.simantics.db.ReadGraph; +import org.simantics.db.Session; +import org.simantics.db.exception.DatabaseException; + +public class SysdynResource { + + public final Resource HasX; + public final Resource HasY; + public final Resource SysdynModel; + public final Resource SysdynModelManager; + public final Resource SysdynModellingDomain; + public final Resource TestDiagram; + public final Resource Variable; + public final Resource VariableElement; + + public static class URIs { + public static final String HasX = "http://www.simantics.org/Sysdyn#HasX"; + public static final String HasY = "http://www.simantics.org/Sysdyn#HasY"; + public static final String SysdynModel = "http://www.simantics.org/Sysdyn#SysdynModel"; + public static final String SysdynModelManager = "http://www.simantics.org/Sysdyn#SysdynModelManager"; + public static final String SysdynModellingDomain = "http://www.simantics.org/Sysdyn#SysdynModellingDomain"; + public static final String TestDiagram = "http://www.simantics.org/Sysdyn#TestDiagram"; + public static final String Variable = "http://www.simantics.org/Sysdyn#Variable"; + public static final String VariableElement = "http://www.simantics.org/Sysdyn#VariableElement"; + } + + public static Resource getResourceOrNull(ReadGraph graph, String uri) { + try { + return graph.getResourceByURI(uri); + } catch(DatabaseException e) { + System.err.println(e.getMessage()); + return null; + } + } + + public SysdynResource(ReadGraph graph) { + HasX = getResourceOrNull(graph, URIs.HasX); + HasY = getResourceOrNull(graph, URIs.HasY); + SysdynModel = getResourceOrNull(graph, URIs.SysdynModel); + SysdynModelManager = getResourceOrNull(graph, URIs.SysdynModelManager); + SysdynModellingDomain = getResourceOrNull(graph, URIs.SysdynModellingDomain); + TestDiagram = getResourceOrNull(graph, URIs.TestDiagram); + Variable = getResourceOrNull(graph, URIs.Variable); + VariableElement = getResourceOrNull(graph, URIs.VariableElement); + } + + public static SysdynResource getInstance(ReadGraph graph) { + Session session = graph.getSession(); + SysdynResource ret = session.getService(SysdynResource.class); + if(ret == null) { + ret = new SysdynResource(graph); + session.registerService(SysdynResource.class, ret); + } + return ret; + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/adapters/VariableClassFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/adapters/VariableClassFactory.java new file mode 100644 index 00000000..e45047f4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/adapters/VariableClassFactory.java @@ -0,0 +1,46 @@ +package org.simantics.sysdyn.ui.adapters; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.adapter.ElementQuerySupport; +import org.simantics.diagram.adapter.GraphElementClassFactory; +import org.simantics.diagram.adapter.GraphElementFactory; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.impl.Element; +import org.simantics.sysdyn.ui.SysdynResource; +import org.simantics.sysdyn.ui.diagram.DrawableElementClass; +import org.simantics.sysdyn.ui.elements.TestDrawable; + +public class VariableClassFactory implements GraphElementFactory, GraphElementClassFactory { + + @Override + public IElement spawn(ReadGraph g, Resource resource, + ElementQuerySupport support, IDiagram diagram) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + + ElementClass elementClass = + DrawableElementClass.createElementClass(sr.VariableElement); + IElement element = Element.spawnNew(elementClass); + + TestDrawable drawable = new TestDrawable(); + drawable.moveTo( + (Double)g.getRelatedValue(resource, sr.HasX), + (Double)g.getRelatedValue(resource, sr.HasY) + ); + element.setHint(DrawableElementClass.KEY_CONTENT, drawable); + + //diagram.addElement(element); + return element; + } + + @Override + public ElementClass create(ReadGraph g, Resource elementType, + ElementQuerySupport support) throws DatabaseException { + return DrawableElementClass.createElementClass(elementType); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/adapters/VariableElementWriter.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/adapters/VariableElementWriter.java new file mode 100644 index 00000000..a671b6ba --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/adapters/VariableElementWriter.java @@ -0,0 +1,23 @@ +package org.simantics.sysdyn.ui.adapters; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.synchronization.graph.ElementWriter; +import org.simantics.g2d.element.IElement; + +public class VariableElementWriter implements ElementWriter { + + @Override + public void addToGraph(WriteGraph graph, IElement element, + Resource elementResource) throws DatabaseException { + System.out.println("addToGraph"); + } + + @Override + public void removeFromGraph(WriteGraph graph, Resource elementResource) + throws DatabaseException { + System.out.println("removeFromGraph"); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/diagram/DiagramEditorFacade.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/diagram/DiagramEditorFacade.java new file mode 100644 index 00000000..daf35821 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/diagram/DiagramEditorFacade.java @@ -0,0 +1,124 @@ +package org.simantics.sysdyn.ui.diagram; + +import java.awt.Color; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.simantics.db.ReadGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.adapter.GraphToDiagramSynchronizer; +import org.simantics.diagram.adapter.IDiagramLoader; +import org.simantics.diagram.participant.SGFocusParticipant; +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.impl.CanvasContext; +import org.simantics.g2d.chassis.SWTChassis; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.participant.CanvasBoundsParticipant; +import org.simantics.g2d.diagram.participant.DiagramParticipant; +import org.simantics.g2d.diagram.participant.ElementInteractor; +import org.simantics.g2d.diagram.participant.ElementPainter; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor; +import org.simantics.g2d.element.ElementClassProviders; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.impl.Element; +import org.simantics.g2d.participant.CanvasGrab; +import org.simantics.g2d.participant.KeyUtil; +import org.simantics.g2d.participant.MousePanZoomInteractor; +import org.simantics.g2d.participant.MouseUtil; +import org.simantics.g2d.participant.Notifications; +import org.simantics.g2d.participant.PanZoomRotateHandler; +import org.simantics.g2d.participant.PointerPainter; +import org.simantics.g2d.participant.RulerPainter; +import org.simantics.g2d.participant.SGTransformUtil; +import org.simantics.g2d.snap.GridSnapAdvisor; +import org.simantics.layer0.utils.ResourceArray; +import org.simantics.sysdyn.ui.elements.IDrawable; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.workbench.ResourceEditorPart; +import org.simantics.utils.datastructures.hints.IHintContext; +import org.simantics.utils.threads.AWTThread; + +public abstract class DiagramEditorFacade extends ResourceEditorPart { + + SWTChassis chassis; + IDiagram diagram; + IDiagramLoader loader; + + public DiagramEditorFacade() { + super(); + } + + @Override + public void reload(ReadGraph g) throws DatabaseException { + // TODO Auto-generated method stub + } + + @Override + public void createPartControl(Composite parent) { + chassis = new SWTChassis(parent, SWT.NONE); + chassis.syncPopulate(); + + final ICanvasContext context = new CanvasContext( + AWTThread.getThreadAccess()); + chassis.setCanvasContext(context); + + context.add(new SGTransformUtil()); + context.add(new MouseUtil()); + context.add(new KeyUtil()); + context.add(new PanZoomRotateHandler()); + context.add(new MousePanZoomInteractor()); + context.add(new RulerPainter()); + context.add(new CanvasGrab()); + context.add(new CanvasBoundsParticipant()); + context.add(new Notifications()); + context.add(new SGFocusParticipant(chassis)); + context.add(new DiagramParticipant()); + context.add(new ElementPainter()); + context.add(new PointerInteractor(true, true, true, false, true, false, null)); + context.add(new ElementInteractor()); + context.add(new Selection()); + + IHintContext h = context.getDefaultHintContext(); + h.setHint(PointerPainter.KEY_PAINT_POINTER, true); + + h.setHint(ElementPainter.KEY_SELECTION_FRAME_COLOR, Color.MAGENTA); + h.setHint(Hints.KEY_TOOL, Hints.POINTERTOOL); + + h.setHint(PanZoomRotateHandler.KEY_ZOOM_IN_LIMIT, 100000.0); + h.setHint(PanZoomRotateHandler.KEY_ZOOM_OUT_LIMIT, 10.0); + + h.setHint(DiagramHints.SNAP_ADVISOR, + new GridSnapAdvisor(10.0)); + + try { + SimanticsUI.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + loader = new GraphToDiagramSynchronizer(graph, context, + ElementClassProviders.staticProvider(null)); + + diagram = loader.loadDiagram(graph, + getResourceInput().getResource(), + ResourceArray.EMPTY, + null); + } + + }); + h.setHint(DiagramHints.KEY_DIAGRAM, diagram); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + @Override + public void setFocus() { + chassis.setFocus(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/diagram/DrawableElementClass.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/diagram/DrawableElementClass.java new file mode 100644 index 00000000..2851dccd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/diagram/DrawableElementClass.java @@ -0,0 +1,137 @@ +package org.simantics.sysdyn.ui.diagram; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.db.Resource; +import org.simantics.diagram.adapter.handler.ResourceAdapter; +import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.Move; +import org.simantics.g2d.element.handler.Outline; +import org.simantics.g2d.element.handler.Pick2; +import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.g2d.element.handler.Transform; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.sysdyn.ui.elements.IDrawable; +import org.simantics.sysdyn.ui.elements.ITransformable; +import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; + +public class DrawableElementClass { + private DrawableElementClass() {} + + public static KeyOf KEY_CONTENT = new KeyOf(IDrawable.class, "CONTENT"); + public static AffineTransform IDENTITY_TRANSFORM = new AffineTransform(); + + public static WidgetHandler WIDGET_HANDLER_INSTANCE = new WidgetHandler(); + + private static class WidgetHandler implements Transform, SceneGraph, InternalSize, Move, Outline, Pick2 { + + private static final long serialVersionUID = 1722978969083481038L; + + @Override + public void setTransform(IElement e, AffineTransform at) { + IDrawable drawable = (IDrawable)e.getHint(KEY_CONTENT); + if(drawable instanceof ITransformable) { + drawable = ((ITransformable)drawable).setTransform(at); + e.setHint(KEY_CONTENT, drawable); + drawable.updateSG(); + } + } + + @Override + public AffineTransform getTransform(IElement e) { + IDrawable drawable = (IDrawable)e.getHint(KEY_CONTENT); + if(drawable instanceof ITransformable) + return ((ITransformable)drawable).getTransform(); + else + return IDENTITY_TRANSFORM; + } + + @Override + public void cleanup(IElement e) { + ((IDrawable)e.getHint(KEY_CONTENT)).cleanupSG(); + } + + @Override + public void init(IElement e, G2DParentNode parent) { + ((IDrawable)e.getHint(KEY_CONTENT)).initSG(parent); + } + + @Override + public Rectangle2D getBounds(IElement e, Rectangle2D size) { + if(size == null) + size = new Rectangle2D.Double(); + ((IDrawable)e.getHint(KEY_CONTENT)).getBounds(size); + return size; + } + + @Override + public Point2D getPosition(IElement e) { + IDrawable drawable = (IDrawable)e.getHint(KEY_CONTENT); + if(drawable instanceof ITransformable) + return ((ITransformable)drawable).getPosition(); + else + return new Point2D.Double(0.0, 0.0); + } + + @Override + public void moveTo(IElement e, double x, double y) { + IDrawable drawable = (IDrawable)e.getHint(KEY_CONTENT); + if(drawable instanceof ITransformable) { + drawable = ((ITransformable)drawable).moveTo(x, y); + e.setHint(KEY_CONTENT, drawable); + drawable.updateSG(); + } + } + + @Override + public Shape getElementShape(IElement e) { + return getBounds(e, null); + } + + @Override + public int pick(IElement e, Shape s, PickPolicy policy, + Collection result) { + if(pickTest(e, s, policy)) { + result.add(e); + return 1; + } + else + return 0; + } + + @Override + public boolean pickTest(IElement e, Shape s, PickPolicy policy) { + IDrawable drawable = (IDrawable)e.getHint(KEY_CONTENT); + switch(policy) { + case PICK_CONTAINED_OBJECTS: + return drawable.pickContained(s); + case PICK_INTERSECTING_OBJECTS: + return drawable.pickIntersecting(s); + default: + return false; + } + } + + } + + public static ElementClass createElementClass(final Resource resource) { + return ElementClass.compile( + WIDGET_HANDLER_INSTANCE, + new ResourceAdapter() { + + @Override + public Resource getResource() { + return resource; + } + + } + ); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/diagram/SysdynDiagramEditor.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/diagram/SysdynDiagramEditor.java new file mode 100644 index 00000000..614a4374 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/diagram/SysdynDiagramEditor.java @@ -0,0 +1,12 @@ +package org.simantics.sysdyn.ui.diagram; + +import org.simantics.sysdyn.ui.elements.TestDrawable; + + +public class SysdynDiagramEditor extends DiagramEditorFacade { + + public SysdynDiagramEditor() { + super(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/Drawable.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/Drawable.java new file mode 100644 index 00000000..90ab9cd5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/Drawable.java @@ -0,0 +1,34 @@ +package org.simantics.sysdyn.ui.elements; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; + +import org.simantics.scenegraph.g2d.G2DParentNode; + +public abstract class Drawable implements IDrawable { + + public static final AffineTransform IDENTITY = new AffineTransform(); + + @Override + public void initSG(G2DParentNode parent) { + } + + @Override + public void cleanupSG() { + } + + @Override + public void updateSG() { + } + + @Override + public boolean pickContained(Shape s) { + return false; + } + + @Override + public boolean pickIntersecting(Shape s) { + return false; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/IDrawable.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/IDrawable.java new file mode 100644 index 00000000..d48a3c90 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/IDrawable.java @@ -0,0 +1,15 @@ +package org.simantics.sysdyn.ui.elements; + +import java.awt.Shape; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DParentNode; + +public interface IDrawable { + void getBounds(Rectangle2D size); + void initSG(G2DParentNode parent); + void updateSG(); + void cleanupSG(); + boolean pickIntersecting(Shape s); + boolean pickContained(Shape s); +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/ITransformable.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/ITransformable.java new file mode 100644 index 00000000..266b8b5c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/ITransformable.java @@ -0,0 +1,11 @@ +package org.simantics.sysdyn.ui.elements; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; + +public interface ITransformable extends IDrawable { + ITransformable setTransform(AffineTransform at); + AffineTransform getTransform(); + public ITransformable moveTo(double x, double y); + Point2D getPosition(); +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/PositionableDrawable.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/PositionableDrawable.java new file mode 100644 index 00000000..58d697e3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/PositionableDrawable.java @@ -0,0 +1,40 @@ +package org.simantics.sysdyn.ui.elements; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; + +public abstract class PositionableDrawable extends Drawable implements ITransformable, Cloneable { + protected double posX; + protected double posY; + + @Override + public Point2D getPosition() { + return new Point2D.Double(posX, posY); + } + @Override + public AffineTransform getTransform() { + return new AffineTransform(1.0, 0.0, 0.0, 1.0, posX, posY); + } + @Override + public ITransformable moveTo(double x, double y) { + try { + PositionableDrawable d = (PositionableDrawable)clone(); + d.posX = x; + d.posY = y; + return d; + } catch(CloneNotSupportedException e) { + throw new Error(e); + } + } + @Override + public ITransformable setTransform(AffineTransform at) { + try { + PositionableDrawable d = (PositionableDrawable)clone(); + d.posX = at.getTranslateX(); + d.posY = at.getTranslateY(); + return d; + } catch(CloneNotSupportedException e) { + throw new Error(e); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/TestDrawable.java b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/TestDrawable.java new file mode 100644 index 00000000..5d35c5ec --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui.old/src/org/simantics/sysdyn/ui/elements/TestDrawable.java @@ -0,0 +1,36 @@ +package org.simantics.sysdyn.ui.elements; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.nodes.ShapeNode; + + +public class TestDrawable extends PositionableDrawable { + + @Override + public void getBounds(Rectangle2D size) { + size.setFrame(-10.0, -10.0, 20.0, 20.0); + } + + ShapeNode node; + + @Override + public void initSG(G2DParentNode parent) { + node = parent.addNode(ShapeNode.class); + node.setShape(new Rectangle2D.Double(-10.0, -10.0, 20.0, 20.0)); + } + + @Override + public boolean pickContained(Shape s) { + return s.contains(-10.0, -10.0, 20.0, 20.0); + } + + @Override + public boolean pickIntersecting(Shape s) { + return s.intersects(-10.0, -10.0, 20.0, 20.0); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/.classpath b/dev-jkauttio/org.simantics.sysdyn.ui/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/.hgignore b/dev-jkauttio/org.simantics.sysdyn.ui/.hgignore new file mode 100644 index 00000000..73df90f6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/.hgignore @@ -0,0 +1,5 @@ +syntax: regexp +^bin/ + +syntax: glob +*.svn/* \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/.project b/dev-jkauttio/org.simantics.sysdyn.ui/.project new file mode 100644 index 00000000..2ebd5691 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/.project @@ -0,0 +1,28 @@ + + + org.simantics.sysdyn.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.sysdyn.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..f287d53c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.sysdyn.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000..119c139f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/META-INF/MANIFEST.MF @@ -0,0 +1,69 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Simantics System Dynamics UI +Bundle-SymbolicName: org.simantics.sysdyn.ui;singleton:=true +Bundle-Version: 1.7.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Require-Bundle: org.simantics.layer0.utils;bundle-version="0.6.2", + org.simantics.scenegraph;bundle-version="0.9.0", + org.junit4;bundle-version="4.5.0";resolution:=optional, + org.simantics.ui;bundle-version="1.0.0", + org.eclipse.ui;bundle-version="3.5.0", + org.eclipse.core.runtime;bundle-version="3.5.0", + org.simantics.objmap;bundle-version="0.1.0", + org.simantics.sysdyn;bundle-version="1.0.0", + org.simantics.project;bundle-version="1.0.0", + org.eclipse.jface.text;bundle-version="3.5.0", + org.eclipse.ui.editors;bundle-version="3.5.0", + org.jfree.jcommon;bundle-version="1.0.16", + org.jfree.jchart;bundle-version="1.0.13", + org.simantics.modelica;bundle-version="1.0.0", + org.apache.log4j;bundle-version="1.2.15", + org.eclipse.ui.console;bundle-version="3.4.0", + org.simantics.browsing.ui.graph;bundle-version="1.1.0", + org.simantics.browsing.ui.swt;bundle-version="1.1.0", + org.simantics.modeling.ui;bundle-version="1.0.0", + org.eclipse.ui.cheatsheets, + org.simantics.graphviz.ui;bundle-version="1.0.0", + org.simantics.graphviz;bundle-version="1.0.0", + org.simantics.diagram;bundle-version="0.9.4", + org.simantics.modeling;bundle-version="1.0.0", + org.simantics.mapping;bundle-version="1.0.0", + org.simantics.structural.ontology;bundle-version="1.0.0", + gnu.trove2;bundle-version="2.0.4", + org.simantics.simulation;bundle-version="1.0.0", + org.simantics.message;bundle-version="0.9.0", + org.simantics.structural2;bundle-version="1.0.0", + org.simantics.layer0;bundle-version="1.0.0", + org.simantics.diagram.ontology;bundle-version="1.0.0", + org.simantics.graph;bundle-version="1.0.2", + org.simantics.graph.db;bundle-version="1.0.0", + org.simantics.structural.ui;bundle-version="1.1.1", + org.simantics.browsing.ui.model;bundle-version="1.0.0", + org.simantics.spreadsheet.ui;bundle-version="1.1.0", + org.simantics.views.swt;bundle-version="1.0.0", + org.simantics.selectionview;bundle-version="1.0.0", + org.simantics.issues;bundle-version="1.1.0", + org.simantics.issues.ui;bundle-version="1.1.0", + org.simantics.issues.common;bundle-version="1.1.0", + org.simantics.scenegraph.profile;bundle-version="1.0.0", + org.simantics.trend;bundle-version="1.0.0", + org.simantics.history;bundle-version="1.0.0", + org.simantics.utils.thread.swt;bundle-version="1.1.0", + org.simantics.jfreechart.ontology;bundle-version="0.1.0", + org.eclipse.ui.forms;bundle-version="3.5.2", + org.simantics.scenegraph.swing;bundle-version="1.0.0", + org.eclipse.nebula.widgets.tablecombo;bundle-version="1.0.0", + org.simantics.fmu;bundle-version="1.0.0", + org.simantics.jfreechart;bundle-version="1.0.0", + org.simantics.db.indexing;bundle-version="1.1.0", + org.simantics.workbench +Bundle-Activator: org.simantics.sysdyn.ui.Activator +Bundle-ActivationPolicy: lazy +Export-Package: org.simantics.sysdyn.ui.browser.nodes +Bundle-Vendor: VTT Technical Reserarch Centre of Finland +Bundle-Localization: plugin +Import-Package: freemarker.template, + org.simantics.workbench, + org.simantics.workbench.ontology, + org.simantics.workbench.search diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/Splash.xcf b/dev-jkauttio/org.simantics.sysdyn.ui/Splash.xcf new file mode 100644 index 00000000..388267fc Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/Splash.xcf differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/adapters.xml b/dev-jkauttio/org.simantics.sysdyn.ui/adapters.xml new file mode 100644 index 00000000..517bc7e2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/adapters.xml @@ -0,0 +1,14 @@ + + + none 0 fill 1 + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/build.properties b/dev-jkauttio/org.simantics.sysdyn.ui/build.properties new file mode 100644 index 00000000..258de40b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/build.properties @@ -0,0 +1,21 @@ +############################################################################### +# Copyright (c) 2010 Association for Decentralized Information Management in +# Industry THTH ry. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# VTT Technical Research Centre of Finland - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + adapters.xml,\ + icons/,\ + splash.bmp,\ + plugin.properties,\ + plugin_customization.ini diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/brick.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/brick.png new file mode 100644 index 00000000..7851cf34 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/brick.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/brick_link.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/brick_link.png new file mode 100644 index 00000000..9ebf013a Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/brick_link.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/bricks.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/bricks.png new file mode 100644 index 00000000..0905f933 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/bricks.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/bullet_gray.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/bullet_gray.png new file mode 100644 index 00000000..6f58b930 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/bullet_gray.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/bullet_green.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/bullet_green.png new file mode 100644 index 00000000..1b5409f3 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/bullet_green.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar.png new file mode 100644 index 00000000..9051fbc6 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_3.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_3.png new file mode 100644 index 00000000..15b7cae3 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_3.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_3_blackAndWhite.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_3_blackAndWhite.png new file mode 100644 index 00000000..0e23ab38 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_3_blackAndWhite.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_blackAndWhite.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_blackAndWhite.png new file mode 100644 index 00000000..087f88c0 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_blackAndWhite.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_light.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_light.png new file mode 100644 index 00000000..6069b5c9 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_bar_light.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_line.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_line.png new file mode 100644 index 00000000..85020f32 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_line.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_line_light.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_line_light.png new file mode 100644 index 00000000..2a77b242 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_line_light.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_organisation.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_organisation.png new file mode 100644 index 00000000..c32d25c1 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_organisation.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_pie.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_pie.png new file mode 100644 index 00000000..fe00fa05 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_pie.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_pie_light.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_pie_light.png new file mode 100644 index 00000000..fa553c29 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/chart_pie_light.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/close.gif b/dev-jkauttio/org.simantics.sysdyn.ui/icons/close.gif new file mode 100644 index 00000000..1aca259d Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/close.gif differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_fastforward.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_fastforward.png new file mode 100644 index 00000000..31f7fd3a Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_fastforward.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_fastforward_blue.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_fastforward_blue.png new file mode 100644 index 00000000..4a2f9d4e Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_fastforward_blue.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_pause.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_pause.png new file mode 100644 index 00000000..2d9ce9c4 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_pause.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_pause_blue.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_pause_blue.png new file mode 100644 index 00000000..ec61099b Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_pause_blue.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_play.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_play.png new file mode 100644 index 00000000..0846555d Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_play.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_play_blue.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_play_blue.png new file mode 100644 index 00000000..f8c8ec68 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_play_blue.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_step.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_step.png new file mode 100644 index 00000000..820b020d Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_step.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_step_blue.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_step_blue.png new file mode 100644 index 00000000..98071cc0 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/control_step_blue.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/cursor.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/cursor.png new file mode 100644 index 00000000..532f532d Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/cursor.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/dependency.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/dependency.png new file mode 100644 index 00000000..768b55f7 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/dependency.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/dependency_old.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/dependency_old.png new file mode 100644 index 00000000..6a604a30 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/dependency_old.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/error.svg b/dev-jkauttio/org.simantics.sysdyn.ui/icons/error.svg new file mode 100644 index 00000000..e4eb0ab1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/icons/error.svg @@ -0,0 +1,151 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/error_decoration.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/error_decoration.png new file mode 100644 index 00000000..688ad22a Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/error_decoration.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/fatal.svg b/dev-jkauttio/org.simantics.sysdyn.ui/icons/fatal.svg new file mode 100644 index 00000000..5ee48164 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/icons/fatal.svg @@ -0,0 +1,612 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/fatal_decoration.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/fatal_decoration.png new file mode 100644 index 00000000..f2e1f4c4 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/fatal_decoration.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/flow.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/flow.png new file mode 100644 index 00000000..e90b3d28 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/flow.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/flow_old.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/flow_old.png new file mode 100644 index 00000000..b1a18192 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/flow_old.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/folder.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/folder.png new file mode 100644 index 00000000..784e8fa4 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/folder.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/folder_link.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/folder_link.png new file mode 100644 index 00000000..b9b75f6c Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/folder_link.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/function.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/function.png new file mode 100644 index 00000000..d6778473 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/function.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/functionLink.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/functionLink.png new file mode 100644 index 00000000..70ae6796 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/functionLink.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/maximize.gif b/dev-jkauttio/org.simantics.sysdyn.ui/icons/maximize.gif new file mode 100644 index 00000000..5e5999be Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/maximize.gif differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/minimize.gif b/dev-jkauttio/org.simantics.sysdyn.ui/icons/minimize.gif new file mode 100644 index 00000000..7402dc9f Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/minimize.gif differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/modelicaArrayFunction.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/modelicaArrayFunction.png new file mode 100644 index 00000000..878469fc Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/modelicaArrayFunction.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/modelicaFunction.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/modelicaFunction.png new file mode 100644 index 00000000..30ee96f4 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/modelicaFunction.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/page_white_text.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/page_white_text.png new file mode 100644 index 00000000..813f712f Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/page_white_text.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/page_white_text_width.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/page_white_text_width.png new file mode 100644 index 00000000..d9cf1325 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/page_white_text_width.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/rainbow.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/rainbow.png new file mode 100644 index 00000000..5ede989a Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/rainbow.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/save_as.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/save_as.png new file mode 100644 index 00000000..033bd354 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/save_as.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/sysdyn.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/sysdyn.png new file mode 100644 index 00000000..35710420 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/sysdyn.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/sysdyn32.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/sysdyn32.png new file mode 100644 index 00000000..01398b25 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/sysdyn32.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/sysdynFunction.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/sysdynFunction.png new file mode 100644 index 00000000..ddc929d5 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/sysdynFunction.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/table.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/table.png new file mode 100644 index 00000000..abcd9368 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/table.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/table_multiple.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/table_multiple.png new file mode 100644 index 00000000..d76448e3 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/table_multiple.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/table_multiple_pinned.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/table_multiple_pinned.png new file mode 100644 index 00000000..5f4e487d Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/table_multiple_pinned.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/time.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/time.png new file mode 100644 index 00000000..911da3f1 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/time.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/time_go.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/time_go.png new file mode 100644 index 00000000..d451ee06 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/time_go.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/time_rainbow.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/time_rainbow.png new file mode 100644 index 00000000..579887f0 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/time_rainbow.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/timeline_marker.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/timeline_marker.png new file mode 100644 index 00000000..a3fbddf8 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/timeline_marker.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/variable.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/variable.png new file mode 100644 index 00000000..0299de3d Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/variable.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/variableGray.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/variableGray.png new file mode 100644 index 00000000..a3ed59b5 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/variableGray.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/vensimFunction.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/vensimFunction.png new file mode 100644 index 00000000..f0070962 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/vensimFunction.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/warning.svg b/dev-jkauttio/org.simantics.sysdyn.ui/icons/warning.svg new file mode 100644 index 00000000..1dd13ec6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/icons/warning.svg @@ -0,0 +1,173 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/icons/warning_decoration.png b/dev-jkauttio/org.simantics.sysdyn.ui/icons/warning_decoration.png new file mode 100644 index 00000000..c80f14d3 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/icons/warning_decoration.png differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/plugin.properties b/dev-jkauttio/org.simantics.sysdyn.ui/plugin.properties new file mode 100644 index 00000000..dd1e0656 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/plugin.properties @@ -0,0 +1,9 @@ +about.text = Simantics System Dynamics\n\ +\n\ +Version 1.7.0\n\ +\n\ +Copyright (c) 2013 Association for Decentralized Information Management in Industry THTH ry.\n\ +\n\ +Contributors:\n\ +VTT Technical Research Centre of Finland\n\ +Semantum Oy \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/plugin.xml b/dev-jkauttio/org.simantics.sysdyn.ui/plugin.xml new file mode 100644 index 00000000..e90bae08 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/plugin.xml @@ -0,0 +1,2813 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Structural model browser view for Sysdyn. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/plugin_customization.ini b/dev-jkauttio/org.simantics.sysdyn.ui/plugin_customization.ini new file mode 100644 index 00000000..92e8ed0c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/plugin_customization.ini @@ -0,0 +1,2 @@ +org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP = false +org.eclipse.ui/DOCK_PERSPECTIVE_BAR=right \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/splash.bmp b/dev-jkauttio/org.simantics.sysdyn.ui/splash.bmp new file mode 100644 index 00000000..faea2d91 Binary files /dev/null and b/dev-jkauttio/org.simantics.sysdyn.ui/splash.bmp differ diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/Activator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/Activator.java new file mode 100644 index 00000000..5e1333d7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/Activator.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui; + +import java.net.URL; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.ConsoleAppender; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.apache.log4j.SimpleLayout; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.simantics.issues.Severity; +import org.simantics.utils.FileUtils; + +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.simantics.sysdyn.ui"; + + // The shared instance + private static Activator plugin; + + private static LocalResourceManager resourceManager; + + public static String FATAL_SVG_TEXT; + public static String ERROR_SVG_TEXT; + public static String WARNING_SVG_TEXT; + public static ImageDescriptor FATAL_DECORATION_ICON; + public static ImageDescriptor ERROR_DECORATION_ICON; + public static ImageDescriptor WARNING_DECORATION_ICON; + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + ConsoleAppender appender = + new ConsoleAppender(new SimpleLayout()); + BasicConfigurator.configure(appender); + Logger.getRootLogger().setLevel(Level.WARN); + plugin = this; + + + Bundle bundle = context.getBundle(); + + FATAL_SVG_TEXT = FileUtils.getContents(bundle.getResource("icons/fatal.svg")); + ERROR_SVG_TEXT = FileUtils.getContents(bundle.getResource("icons/error.svg")); + WARNING_SVG_TEXT = FileUtils.getContents(bundle.getResource("icons/warning.svg")); + FATAL_DECORATION_ICON = ImageDescriptor.createFromURL(bundle.getResource("icons/fatal_decoration.png")); + ERROR_DECORATION_ICON = ImageDescriptor.createFromURL(bundle.getResource("icons/error_decoration.png")); + WARNING_DECORATION_ICON = ImageDescriptor.createFromURL(bundle.getResource("icons/warning_decoration.png")); + } + + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + public static Activator getDefault() { + return plugin; + } + + @Override + protected ImageRegistry createImageRegistry() { + return super.createImageRegistry(); + } + + @Override + protected void initializeImageRegistry(ImageRegistry reg) { + reg.put(Severity.FATAL.toString(), FATAL_DECORATION_ICON); + reg.put(Severity.ERROR.toString(), ERROR_DECORATION_ICON); + reg.put(Severity.WARNING.toString(), WARNING_DECORATION_ICON); + } + + public static ResourceManager initializeResourceManager(Display display) { + if (resourceManager == null) { + resourceManager = new LocalResourceManager(JFaceResources.getResources(display)); + } + return resourceManager; + } + + public static ResourceManager getResources() { + if (resourceManager == null) + throw new IllegalStateException("ResourceManager of bundle '" + PLUGIN_ID + "' is not initialized."); + return resourceManager; + } + + public static URL getDefaultResource(String name) { + Activator plugin = getDefault(); + if(plugin == null) throw new IllegalStateException("The plugin is not active."); + return plugin.getBundle().getResource(name); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ActivateExperimentAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ActivateExperimentAction.java new file mode 100644 index 00000000..4e00ace6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ActivateExperimentAction.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.actions; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.project.IProject; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.ui.handlers.SysdynExperimentActivator; +import org.simantics.ui.DoubleClickEvent; +import org.simantics.ui.IDoubleClickAction; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.action.PriorityAction; + +public class ActivateExperimentAction implements IDoubleClickAction { + + @Override + public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException { + ReadGraph g = e.getGraph(); + final Resource experiment = ResourceAdaptionUtils.toSingleResource(e.getResource()); + if (experiment == null) + return; + + if (g.isInstanceOf(experiment, SimulationResource.getInstance(g).Experiment)) { + final IProject project = SimanticsUI.getProject(); + if (project == null) + return; + + final IExperimentManager experimentManager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + if (experimentManager == null) { + ErrorLogger.defaultLogWarning("Experiment manager not available.", new Exception()); + return; + } + + e.add(new PriorityAction(PriorityAction.HIGH+20) { + @Override + public void run() { + SysdynExperimentActivator.scheduleActivation(SimanticsUI.getSession(), project, experimentManager, experiment); + } + }); + e.consume(); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConsumeUnnecessaryEntersAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConsumeUnnecessaryEntersAction.java new file mode 100644 index 00000000..b5a284dd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConsumeUnnecessaryEntersAction.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.actions; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.DoubleClickEvent; +import org.simantics.ui.IDoubleClickAction; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ui.action.PriorityAction; + +public class ConsumeUnnecessaryEntersAction implements IDoubleClickAction { + + @Override + public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException { + ReadGraph g = e.getGraph(); + Layer0X L0X = Layer0X.getInstance(g); + final Resource resource = ResourceAdaptionUtils.toSingleResource(e.getResource()); + if(resource == null) + return; + SysdynResource sr = SysdynResource.getInstance(g); + + if(g.isInheritedFrom(resource, sr.SysdynModel) + || (g.isInstanceOf(resource, sr.Variable) + && !g.isInstanceOf(resource, sr.IndependentVariable) + && !g.isInstanceOf(resource, sr.Input) + )) { + consume(e); + } else if(g.hasStatement(resource, L0X.Represents)){ + Resource represents = g.getSingleObject(resource, L0X.Represents); + if (g.isInstanceOf(represents, sr.Variable) + && !g.isInstanceOf(resource, sr.IndependentVariable) + && !g.isInstanceOf(resource, sr.Input)) { + consume(e); + } + } + } + + private void consume(DoubleClickEvent e) { + e.add(new PriorityAction(PriorityAction.HIGH) { + @Override + public void run() { + + } + }); + e.consume(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ShowInstantiatedModuleAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ShowInstantiatedModuleAction.java new file mode 100644 index 00000000..830b2c51 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ShowInstantiatedModuleAction.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.actions; + +import java.util.Set; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.PartInitException; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.BrowserSelection; +import org.simantics.sysdyn.ui.browser.nodes.ModuleNode; +import org.simantics.sysdyn.ui.editor.SysdynEditorInput; +import org.simantics.ui.DoubleClickEvent; +import org.simantics.ui.IDoubleClickAction; +import org.simantics.ui.workbench.ResourceEditorInput2; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.ui.ISelectionUtils; +import org.simantics.utils.ui.action.PriorityAction; +import org.simantics.utils.ui.workbench.WorkbenchUtils; + +/** + * Open an editor for a module instance. + * @author Teemu Lempinen + * + */ +public class ShowInstantiatedModuleAction implements IDoubleClickAction { + + private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer"; + + @Override + public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException { + + ReadGraph g = e.getGraph(); + Layer0 l0 = Layer0.getInstance(g); + StructuralResource2 sr2 = StructuralResource2.getInstance(g); + + // Open instance for a module instance, if the resource is adaptable to variable + Variable variable = AdaptionUtils.adaptToSingle(e.getResource(), Variable.class); + if(variable != null) { + Resource represents = variable.getRepresents(g); + Resource instanceOf = g.getPossibleObject(represents, l0.InstanceOf); + Resource configuration = g.getPossibleObject(instanceOf, sr2.IsDefinedBy); + if(configuration != null) { + String rvi = Variables.getRVI(g, variable); + if(!rvi.isEmpty()) + rvi = rvi.substring(1); + Resource model = Variables.getModel(g, variable); + addShowModuleAction(e, getResourceEditorInput(g, model, configuration, rvi)); + return; + } + } + + if(e.getResource() instanceof IStructuredSelection) { + Set bss = ISelectionUtils.filterSetSelection(e.getResource(), BrowserSelection.class); + + if(!bss.isEmpty()) { + // Find varaible from BrowserSelection. (Will be replaced with the Variable adaption above) + for(BrowserSelection bs : bss) { + Resource configuration = (Resource)bs.getAdapter(Resource.class); + Resource instanceOf = g.getSingleObject(configuration, l0.InstanceOf); + + SysdynResource sr = SysdynResource.getInstance(g); + if(g.isInheritedFrom(instanceOf, sr.Module)) { + configuration = g.getSingleObject(instanceOf, sr2.IsDefinedBy); + variable = (Variable) bs.getAdapter(Variable.class); + String rvi = Variables.getRVI(g, variable).substring(1); + Resource model = Variables.getModel(g, variable); + addShowModuleAction(e, getResourceEditorInput(g, model, configuration, rvi)); + } + } + } else { + ModuleNode moduleNode = ISelectionUtils.filterSingleSelection(e.getResource(), ModuleNode.class); + if(moduleNode != null) { + Resource model; + String rvi; + if(moduleNode.getVariable() != null) { + model = Variables.getModel(g, moduleNode.getVariable()); + Variable var = moduleNode.getVariable(); + rvi = Variables.getRVI(g, var).substring(1); + } else { + rvi = (String)g.getRelatedValue(moduleNode.data, Layer0.getInstance(g).HasName); + model = g.getSingleObject(moduleNode.data, l0.PartOf); + } + + Resource instanceOf = g.getSingleObject(moduleNode.data, l0.InstanceOf); + Resource conf = g.getSingleObject(instanceOf, sr2.IsDefinedBy); + + addShowModuleAction(e, getResourceEditorInput(g, model, conf, rvi)); + } + } + } + } + + private ResourceEditorInput2 getResourceEditorInput(ReadGraph g, Resource model, Resource configuration, String rvi) throws DatabaseException { + + if(model == null) { + model = g.syncRequest(new PossibleModel(model)); + rvi = null; + } + + Resource diagram = g.getSingleObject(configuration, ModelingResources.getInstance(g).CompositeToDiagram); + return new SysdynEditorInput(EDITOR_ID, diagram, model, rvi == null ? "" : "/" + rvi); + } + + private void addShowModuleAction(DoubleClickEvent e, final ResourceEditorInput2 editorInput) { + e.add(new PriorityAction(PriorityAction.HIGH) { + @Override + public void run() { + try { + WorkbenchUtils.openEditor(EDITOR_ID, editorInput); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + }); + e.consume(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/SysdynVariableRemover.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/SysdynVariableRemover.java new file mode 100644 index 00000000..7e6b0eb4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/SysdynVariableRemover.java @@ -0,0 +1,111 @@ +package org.simantics.sysdyn.ui.actions; + +import java.util.Map; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithSupertype; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.Instances; +import org.simantics.db.layer0.adapter.Remover; +import org.simantics.db.layer0.adapter.impl.EntityRemover; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.project.ontology.ProjectResource; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; + +/** + * Remover for sysdyn variables. The main purpose is to take care that input and output references + * are removed + * @author Teemu Lempinen + * + */ +public class SysdynVariableRemover implements Remover { + + private Resource resource; + + public SysdynVariableRemover(Resource resource) { + this.resource = resource; + } + + @Override + public String canRemove(ReadGraph graph, Map aux) throws DatabaseException { + return null; + } + + @Override + public void remove(WriteGraph graph) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + + // Take care of inputs and outputs + if(graph.hasStatement(resource, SR.IsOutput) || graph.isInstanceOf(resource, SR.Input)) { + Layer0 L0 = Layer0.getInstance(graph); + ProjectResource PROJ = ProjectResource.getInstance(graph); + Resource configuration = graph.getPossibleObject(resource, L0.PartOf); + if(configuration != null) { + Resource moduleType = graph.getPossibleObject(configuration, L0.PartOf); + if(graph.isInheritedFrom(moduleType, SR.Module)) { + Resource project = moduleType; + do { + project = graph.getPossibleObject(project, L0.PartOf); + } while (project != null && !graph.isInstanceOf(project, PROJ.Project)); + + if(project != null) { + for(Resource model : graph.syncRequest(new ObjectsWithType(project, L0.ConsistsOf, SR.SysdynModel))) { + removeOutputReferencesFromModel(graph, model, resource, moduleType); + } + } + + } + } + } + + // Remove possible shadow varia bles + for(Resource shadow : graph.getObjects(resource, SR.Shadow_original_Inverse)) { + Resource element = graph.getPossibleObject(shadow, ModelingResources.getInstance(graph).ComponentToElement); + RemoverUtil.remove(graph, element); + } + + EntityRemover.remove(graph, resource); + + } + + private void removeOutputReferencesFromModel(WriteGraph graph, Resource model, Resource reference, Resource moduleType) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + StructuralResource2 SR2 = StructuralResource2.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + + Instances moduleInstanceFinder = graph.adapt(moduleType, Instances.class); + + denyReferences(graph, moduleInstanceFinder, graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration), reference); + + for(Resource type : graph.syncRequest(new ObjectsWithSupertype(model, L0.ConsistsOf, SR.Module))) { + Resource configuration = graph.getPossibleObject(type, SR2.IsDefinedBy); + denyReferences(graph, moduleInstanceFinder, configuration, reference); + + } + + } + + private void denyReferences(WriteGraph graph, Instances moduleInstanceFinder, Resource indexRoot, Resource reference) throws DatabaseException { + StructuralResource2 SR2 = StructuralResource2.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + + for(Resource module : moduleInstanceFinder.find(graph, indexRoot)) { + for(Statement stm : graph.getStatements(module, SR2.IsConnectedTo)) { + Resource connection = stm.getObject(); + Resource ref = graph.getPossibleObject(connection, SR.Dependency_refersTo); + if(ref != null && ref.equals(reference)) { + graph.deny(connection, SR.Dependency_refersTo); + } + } + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.java new file mode 100644 index 00000000..cfd31c81 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.ISelection; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.db.Resource; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.sysdyn.ui.browser.nodes.VariableNode; + +public class BrowserSelection implements IAdaptable, ISelection { + private Resource resource; + private Object originalInput; + private Variable variable; + + public BrowserSelection(Object originalInput, VariableNode vn) { + this.originalInput = originalInput; + this.resource = vn.data; + Variable variable = vn.getVariable(); + if(variable != null) { + this.variable = variable; + } + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if (adapter == Resource.class) + return resource; + if (adapter == Variable.class) + return variable; + if (NodeContext.class.equals(adapter)) + return originalInput; + if (originalInput instanceof IAdaptable) { + IAdaptable input = (IAdaptable)originalInput; + return input.getAdapter(adapter); + } + return null; + } + + @Override + public boolean isEmpty() { + if(originalInput == null) + return true; + return false; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java new file mode 100644 index 00000000..8cda4726 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.GraphExplorer; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.platform.GraphExplorerView; +import org.simantics.browsing.ui.swt.AdaptableHintContext; +import org.simantics.browsing.ui.swt.ContextMenuInitializer; +import org.simantics.browsing.ui.swt.DefaultSelectionDataResolver; +import org.simantics.browsing.ui.swt.GraphExplorerFactory; +import org.simantics.browsing.ui.swt.IContextMenuInitializer; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.SelectionHints; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.browser.nodes.VariableNode; +import org.simantics.sysdyn.ui.properties.SysdynPropertyPage; +import org.simantics.ui.selection.AnyResource; +import org.simantics.ui.selection.AnyVariable; +import org.simantics.ui.selection.WorkbenchSelectionContentType; +import org.simantics.ui.workbench.IPropertyPage; +import org.simantics.utils.datastructures.BinaryFunction; +import org.simantics.utils.datastructures.hints.IHintContext; + + +public class SysdynBrowser extends GraphExplorerView { + + private static final Set browseContexts = new HashSet(Arrays.asList( + "http://www.simantics.org/Sysdyn-1.1/Browser", + "http://www.semantum.fi/SimupediaWorkbench-1.0/OldBrowser", + "http://www.simantics.org/Image-1.1/Browser")); + + private BinaryFunction selectionTransformation = new BinaryFunction() { + + + /* + private Key[] KEYS = new Key[] { SelectionHints.KEY_MAIN }; + + @Override + public Object[] call(GraphExplorer explorer, Object[] objects) { + Object[] result = new Object[objects.length]; + for (int i = 0; i < objects.length; i++) { + SelectionElement context = new SelectionElement(KEYS, objects[i]); + context.setHint(SelectionHints.KEY_MAIN, objects[i]); + result[i] = context; + } + return result; + } + */ + + class SelectionElement extends AdaptableHintContext { + + private Variable variable; + private Resource resource; + + public SelectionElement(Variable variable, Resource resource, Key... keys) { + super(keys); + this.variable = variable; + this.resource = resource; + } + + @SuppressWarnings("unchecked") + @Override + public T getContent(WorkbenchSelectionContentType contentType) { + if(contentType instanceof AnyResource) return (T)resource; + else if(contentType instanceof AnyVariable) { + AnyVariable type = (AnyVariable)contentType; + try { + + if(variable != null) return (T)variable; + + if(resource == null) return null; + + return (T) type.processor.sync(new ResourceRead(resource) { + @Override + public Variable perform(ReadGraph graph) throws DatabaseException { + return Variables.getPossibleVariable(graph, resource); + } + + }); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + } + return null; + } + + } + + @Override + public Object[] call(GraphExplorer explorer, Object[] objects) { + Object[] result = new Object[objects.length]; + for (int i = 0; i < objects.length; i++) { + + NodeContext ctx = (NodeContext)objects[i]; + @SuppressWarnings("unchecked") + VariableNode vn = (VariableNode) ctx.getAdapter(VariableNode.class); + IHintContext context; + if(vn != null && vn.getVariable() != null) { + context = new SelectionElement(vn.getVariable(),vn.data, SelectionHints.KEY_MAIN, SelectionHints.KEY_SELECTION_PROPERTY); + context.setHint(SelectionHints.KEY_MAIN, new BrowserSelection(objects[i], vn)); + context.setHint(SelectionHints.KEY_SELECTION_PROPERTY, vn.getVariable()); + } else { + Object resource = ctx.getAdapter(Resource.class); + context = new SelectionElement(null, resource == null ? null : (Resource)resource, SelectionHints.KEY_MAIN); + context.setHint(SelectionHints.KEY_MAIN, objects[i]); + } + result[i] = context; + } + return result; + } + + }; + + protected GraphExplorer createExplorerControl(Composite parent) { + return GraphExplorerFactory.getInstance() + .selectionDataResolver(new DefaultSelectionDataResolver()) + .selectionTransformation(selectionTransformation) + .create(parent, getStyle()); + } + + @Override + protected IContextMenuInitializer getContextMenuInitializer() { + return new ContextMenuInitializer("#SysdynBrowserPopup"); + } + + @Override + protected Set getBrowseContexts() { + return browseContexts; + } + + @Override + protected void createControls(Composite parent) { + // Make sure the resource manager of this plug-in is initialized + // properly before using it in this browser. + Activator.initializeResourceManager(parent.getDisplay()); + + super.createControls(parent); + //IToolBarManager toolBar = getViewSite().getActionBars().getToolBarManager(); + //toolBar.add(new HomeAction()); + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if (adapter == IPropertyPage.class) + return new SysdynPropertyPage(getSite(), Collections.singleton(SysdynResource.URIs.Browser)); + return super.getAdapter(adapter); + } + + public SysdynBrowser() { + hideComparatorSelector = true; + hideViewpointSelector = true; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynModelBrowser.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynModelBrowser.java new file mode 100644 index 00000000..b2e0e0e2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynModelBrowser.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.simantics.structural.ui.modelBrowser.ModelBrowser2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.SysdynPropertyPage; +import org.simantics.ui.workbench.IPropertyPage; + +/** + * Model browser for sysdyn models. Content configured in SysdynModelingViewpoint.pgraph + * @author Teemu Lempinen + * + */ +public class SysdynModelBrowser extends ModelBrowser2 { + + final private Set browseContexts = new HashSet(Arrays.asList(SysdynResource.URIs.ModelingBrowseContext, "http://www.simantics.org/Operating-1.1/Browser", "http://www.simantics.org/Image-1.1/Browser")); + + @Override + protected IPropertyPage getPropertyPage() { + return new SysdynPropertyPage(getSite(), Collections.singleton(SysdynResource.URIs.ModelingBrowseContext)); + } + + @Override + protected Set getBrowseContexts() { + return browseContexts; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultDatasetAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultDatasetAction.java new file mode 100644 index 00000000..8c7e6fbf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultDatasetAction.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.DoubleClickEvent; +import org.simantics.ui.IDoubleClickAction; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +/** + * Activates a result dataset to be shown in charts and other result visualizations + * + * @author Teemu Lempinen + * + */ +public class ActivateResultDatasetAction implements IDoubleClickAction { + + @Override + public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException { + final Resource result = ResourceAdaptionUtils.toSingleResource(e.getResource()); + if (result == null) + return; + + ReadGraph graph = e.getGraph(); + + if(graph.isInstanceOf(result, SysdynResource.getInstance(graph).Result)) { + + graph.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.isInstanceOf(result, sr.Result)) { + if (graph.hasStatement(result, sr.Result_showResult)) { + graph.denyStatement(result, sr.Result_showResult, result); + } else { + graph.claim(result, sr.Result_showResult, result); + } + } + } + }); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultSetDatasetAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultSetDatasetAction.java new file mode 100644 index 00000000..3ad688e1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultSetDatasetAction.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions; + +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.DoubleClickEvent; +import org.simantics.ui.IDoubleClickAction; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +/** + * Activates the result datasets of a result set to be shown in charts and other result visualizations + * + * @author Tuomas Miettinen + * + */ +public class ActivateResultSetDatasetAction implements IDoubleClickAction { + + @Override + public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException { + final Resource resultSet = ResourceAdaptionUtils.toSingleResource(e.getResource()); + if (resultSet == null) + return; + + ReadGraph graph = e.getGraph(); + + if(graph.isInstanceOf(resultSet, SysdynResource.getInstance(graph).ResultSet)) { + + graph.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.isInstanceOf(resultSet, sr.ResultSet)) { + // If there is at least one result which shown, clear them all. + // If not one result is shown, show them all. + boolean resultShown = false; + Collection results = graph.getObjects(resultSet, sr.Experiment_result); + for (Resource result : results) { + if (graph.hasStatement(result, sr.Result_showResult)) { + resultShown = true; + break; + } + } + for (Resource result : results) { + if (resultShown) { + graph.denyStatement(result, sr.Result_showResult, result); + } else { + graph.claim(result, sr.Result_showResult, result); + } + } + } + } + }); + e.consume(); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/OpenSheetAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/OpenSheetAction.java new file mode 100644 index 00000000..91e560ef --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/OpenSheetAction.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions; + +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.RVI; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.spreadsheet.resource.SpreadsheetResource; +import org.simantics.ui.DoubleClickEvent; +import org.simantics.ui.IDoubleClickAction; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.ui.workbench.ResourceEditorInput2; +import org.simantics.utils.ui.workbench.WorkbenchUtils; + +/** + * Opens the selected spreadsheet in a spreadsheet editor + * @author Teemu Lempinen + * + */ +public class OpenSheetAction implements IDoubleClickAction { + + @Override + public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException { + Resource result = ResourceAdaptionUtils.toSingleResource(e.getResource()); + if (result == null) + return; + + ReadGraph graph = e.getGraph(); + SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph); + + final Resource sheet = result; + + if(graph.isInstanceOf(sheet, SHEET.Spreadsheet)) { + + Variable variable = graph.adapt(sheet, Variable.class); + final Resource model = Variables.getModel(graph, variable); + final RVI rvi = variable.getRVI(graph); + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + private static final String EDITOR_ID = "org.simantics.spreadsheet.ui.editor2"; + + @Override + public void run() { + try { + WorkbenchUtils.openEditor(EDITOR_ID, new ResourceEditorInput2(EDITOR_ID, sheet, model, rvi)); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + }); + + } + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/ChartDropAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/ChartDropAction.java new file mode 100644 index 00000000..27c0272c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/ChartDropAction.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.drop; + +import java.util.Iterator; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.SingleObjectWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.DropActionFactory; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Action for droppin variables to charts + * @author Teemu Lempinen + * + */ +public class ChartDropAction implements DropActionFactory { + + @Override + public Runnable create(ReadGraph g, Object target, Object source) throws DatabaseException { + + final Resource targetChart = AdaptionUtils.adaptToSingle(target, Resource.class); + if(targetChart == null || source == null || !(source instanceof IStructuredSelection)) + return null; + + final IStructuredSelection selection = (IStructuredSelection) source; + + return new Runnable() { + + @Override + public void run() { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + JFreeChartResource JFREE = JFreeChartResource.getInstance(graph); + + Iterator iterator = selection.iterator(); + + // Run through all selections and add all IndependentVariables and Inputs to the target chart + while(iterator.hasNext()) { + + Variable variable = AdaptionUtils.adaptToSingle(iterator.next(), Variable.class); + if(variable == null) + continue; + + Resource represents = (Resource)variable.getPropertyValue(graph, Variables.REPRESENTS); + if(represents == null || + !(graph.isInstanceOf(represents, sr.IndependentVariable) || + graph.isInstanceOf(represents, sr.Input))) + continue; + + Resource plot = graph.syncRequest(new PossibleObjectWithType(targetChart, L0.ConsistsOf, JFREE.Plot)); + if(plot != null) { + if(graph.isInstanceOf(plot, JFREE.XYPlot)) { + dropToLineChart(graph, targetChart, variable); + } else if(graph.isInstanceOf(plot, JFREE.CategoryPlot)) { + dropToBarChart(graph, targetChart, variable); + } else if(graph.isInstanceOf(plot, JFREE.PiePlot)) { + dropToPieChart(graph, targetChart, variable); + } + } + } + + } + }); + } + }; + } + + + /** + * Drop variable to a pie chart + * @param graph ReadGraph + * @param pieChart Pie chart resource + * @param variable Dropped variable + * @throws DatabaseException + */ + private void dropToPieChart(WriteGraph graph, Resource pieChart, Variable variable) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + Resource plot = graph.syncRequest(new SingleObjectWithType(pieChart, l0.ConsistsOf, jfree.Plot)); + if(plot == null) + return; + + Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + + if(dataset == null) + return; + + // Create the series and attach it to the dataset + String rvi = Variables.getRVI(graph, variable); + Resource series = ChartUtils.createSeries(graph, dataset, rvi); + graph.claimLiteral(series, jfree.Series_exploded, false); + } + + /** + * Drop variable to a bar chart + * @param graph ReadGraph + * @param barChart Bar chart resource + * @param variable Dropped variable + * @throws DatabaseException + */ + private void dropToBarChart(WriteGraph graph, Resource barChart, Variable variable) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + Resource plot = graph.syncRequest(new SingleObjectWithType(barChart, l0.ConsistsOf, jfree.Plot)); + if(plot == null) + return; + + Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + + if(dataset == null) + return; + + // Create the series and attach it to the dataset + String rvi = Variables.getRVI(graph, variable); + ChartUtils.createSeries(graph, dataset, rvi); + } + + /** + * Drop variable to a line chart + * @param graph ReadGraph + * @param lineChart Line chart resource + * @param variable Dropped variable + * @throws DatabaseException + */ + private void dropToLineChart(WriteGraph graph, Resource lineChart, Variable variable) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + Resource plot = graph.syncRequest(new SingleObjectWithType(lineChart, l0.ConsistsOf, jfree.Plot)); + if(plot == null) + return; + + Resource rangeAxis = null; + Resource dataset = null; + Resource rangeAxisList = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList); + if(rangeAxisList == null || ListUtils.toList(graph, rangeAxisList).isEmpty()) { + // No range axis -> Create a new one + rangeAxis = ChartUtils.createNumberRangeAxis(graph, plot); + Resource domainAxis = graph.getPossibleObject(plot, jfree.Plot_domainAxis); + dataset = ChartUtils.createXYDataset(graph, plot, domainAxis, rangeAxis); + } else { + rangeAxis = ListUtils.toList(graph, rangeAxisList).get(0); + dataset = graph.getPossibleObject(rangeAxis, jfree.Dataset_mapToRangeAxis_Inverse); + } + + // Create the series and attach it to the dataset + String rvi = Variables.getRVI(graph, variable); + ChartUtils.createSeries(graph, dataset, rvi); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/FunctionDropAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/FunctionDropAction.java new file mode 100644 index 00000000..354f25b3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/FunctionDropAction.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.drop; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.DropActionFactory; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Action for moving functions and function libraries in model browser + * @author Teemu Lempinen + * + */ +public class FunctionDropAction implements DropActionFactory { + + @Override + public Runnable create(ReadGraph g, Object target, Object source) throws DatabaseException { + Resource t = AdaptionUtils.adaptToSingle(target, Resource.class); + Resource s = AdaptionUtils.adaptToSingle(source, Resource.class); + + if(t == null || s == null) + return null; + + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 L0 = Layer0.getInstance(g); + + // If target is a function, find functions parent to be the drop target + if(g.isInstanceOf(t, sr.SysdynModelicaFunction)) + t = g.getSingleObject(t, L0.PartOf); + + final Resource library = t; + final Resource tobemoved = s; + + // Libraries and model accept drops + if(!(g.isInstanceOf(library, sr.SysdynModelicaFunctionLibrary) || + g.isInstanceOf(library, sr.SysdynModel) || + g.isInstanceOf(library, sr.SharedFunctionOntology))) + return null; + + // Functions and function libraries can be dropped + if(!(g.isInstanceOf(tobemoved, sr.SysdynModelicaFunction) || + g.isInstanceOf(tobemoved, sr.SysdynModelicaFunctionLibrary))) + return null; + + + return new Runnable() { + + @Override + public void run() { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource oldLib = graph.getSingleObject(tobemoved, L0.PartOf); + + // Remove dragged entity from its parent and add it to the new parent + graph.claim(tobemoved, L0.PartOf, library); + graph.deny(tobemoved, L0.PartOf, oldLib); + } + + }); + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewBarChartAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewBarChartAction.java new file mode 100644 index 00000000..2e16bcec --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewBarChartAction.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import java.util.Collections; +import java.util.UUID; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; + +/** + * Creates a new bar chart to a model + * @author Teemu Lempinen + * + */ +public class NewBarChartAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource model = (Resource)target; + + return new Runnable() { + @Override + public void run() { + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + G2DResource g2d = G2DResource.getInstance(graph); + + // Chart + Resource jfreechart = GraphUtils.create2(graph, jfree.Chart, + l0.HasName, "BarChart" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(graph, "Bar Chart", model), + l0.PartOf, model, + jfree.Chart_visibleBorder, true, + jfree.Chart_borderWidth, 3, + jfree.Chart_visibleLegend, false + ); + + // Border color + graph.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1}); + + // Title + GraphUtils.create2(graph, jfree.TextTitle, + l0.HasName, "TextTitle" + UUID.randomUUID().toString(), + l0.HasLabel, "Bar Chart Title", + jfree.Title_position, jfree.Top, + l0.PartOf, jfreechart); + + // X-axis + Resource domainAxis = GraphUtils.create2(graph, jfree.CategoryAxis, + l0.HasName, "CategoryAxis" + UUID.randomUUID().toString()); + + // Y-axis + Resource rangeAxis = GraphUtils.create2(graph, jfree.NumberAxis, + l0.HasName, "NumberAxis" + UUID.randomUUID().toString()); + + // Renderer + Resource renderer = GraphUtils.create2(graph, jfree.BarRenderer); + + // Dataset + Resource dataset = GraphUtils.create2(graph, jfree.CategoryDataset, + l0.HasName, "CategoryDataset" + UUID.randomUUID().toString(), + jfree.Dataset_mapToDomainAxis, domainAxis, + jfree.Dataset_mapToRangeAxis, rangeAxis, + jfree.Dataset_seriesList, ListUtils.create(graph, Collections.emptyList()), + jfree.Dataset_renderer, renderer); + + // Plot + GraphUtils.create2(graph, jfree.CategoryPlot, + l0.HasName, "Category plot" + UUID.randomUUID().toString(), + l0.PartOf, jfreechart, + jfree.Plot_domainAxis, domainAxis, + jfree.Plot_rangeAxis, rangeAxis, + jfree.Plot_rangeAxisList, ListUtils.create(graph, Collections.singletonList(rangeAxis)), + l0.ConsistsOf, dataset, + l0.ConsistsOf, domainAxis, + l0.ConsistsOf, rangeAxis); + } + + }); + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewEnumerationAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewEnumerationAction.java new file mode 100644 index 00000000..ffc74ba1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewEnumerationAction.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import java.util.Collections; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +/** + * Creates a new enumeration to a model or module + * @author Teemu Lempinen + * + */ +public class NewEnumerationAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource resource = (Resource)target; + + return new Runnable() { + @Override + public void run() { + + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + + // Find the configuration from... + Resource configuration = null; + if(g.isInstanceOf(resource, sr.Configuration)) { + configuration = resource; + } else if(g.isInheritedFrom(resource, sr.ModuleSymbol)) { + // Module symbol + Resource module = g.getPossibleObject(resource,ModelingResources.getInstance(g).SymbolToComponentType); + configuration = g.getPossibleObject(module, StructuralResource2.getInstance(g).IsDefinedBy); + } else { + // Module instance + Resource instanceOf = g.getSingleObject(resource, l0.InstanceOf); + if(g.isInheritedFrom(instanceOf, sr.Module)) { + configuration = g.getPossibleObject(instanceOf, StructuralResource2.getInstance(g).IsDefinedBy); + } else { + return; + } + } + + // Find unique name + String name = NameUtils.findFreshName(g, "Enum", configuration, l0.ConsistsOf, "%s%d"); + + // Create enumeration + GraphUtils.create2(g, + sr.Enumeration, + l0.HasName, name, + sr.Enumeration_enumerationIndexList, ListUtils.create(g, Collections.emptyList()), + l0.PartOf, configuration); + } + }); + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewExperimentAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewExperimentAction.java new file mode 100644 index 00000000..05f79146 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewExperimentAction.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +/** + * Creates a new basic experiment + * @author Teemu Lempinen + * + */ +public class NewExperimentAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource model = (Resource)target; + + return new Runnable() { + @Override + public void run() { + + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + String name = NameUtils.findFreshName(graph, getNameSuggestion(), model, l0.ConsistsOf, "%s%d"); + + Resource experiment = GraphUtils.create2(graph, getExperimentType(graph), + l0.HasName, name, + l0.HasLabel, name, + l0.PartOf, model); + + configureExperiment(graph, experiment); + } + }); + } + }; + } + + /** + * Override to do experiment-specific alterations + */ + protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException { + + } + + /** + * Get the type of this experiment. + * + * @param g ReadGraph + * @return The type resource of this experiment + */ + protected Resource getExperimentType(ReadGraph g) { + return SysdynResource.getInstance(g).BasicExperiment; + } + + /** + * Returns the suggested name for this experiment. + * If the name has already been taken, appropriate prefix needs to be added. + * + * @return Suggested name for this experiment. + */ + protected String getNameSuggestion() { + return "Experiment"; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionAction.java new file mode 100644 index 00000000..a76b5c17 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionAction.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +/** + * Creates a new modelica function to a model, function library or shared function library. + * @author Teemu Lempinen + * + */ +public class NewFunctionAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource resource = (Resource)target; + + return new Runnable() { + @Override + public void run() { + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + SysdynResource sr = SysdynResource.getInstance(g); + + Resource library = null; + if(g.isInstanceOf(resource, sr.SysdynModel) || g.isInstanceOf(resource, l0.Library)) + library = resource; + else if (g.isInstanceOf(resource, sr.SysdynModelicaFunction)) + library = g.getPossibleObject(resource, l0.PartOf); + + if(library == null) + return; + + + String name = NameUtils.findFreshName(g, "Function", library, l0.ConsistsOf, "%s%d"); + + GraphUtils.create2(g, sr.SysdynModelicaFunction, + l0.HasName, name, + l0.HasDescription, "", + sr.SysdynModelicaFunction_modelicaFunctionCode, "", + l0.PartOf, library); + } + }); + + } + }; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionLibraryAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionLibraryAction.java new file mode 100644 index 00000000..031e37e9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionLibraryAction.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +/** + * Creates a new function library + * @author Teemu Lempinen + * + */ +public class NewFunctionLibraryAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource resource = (Resource)target; + + return new Runnable() { + @Override + public void run() { + createLibrary(resource, false); + } + }; + } + + /** + * Create a new Library to the selected root or to SharedOntologies + * + * @param libraryLocation Resource of the model or other + * library where the new library will be added. + * @param shared is the library a shared library + */ + protected static void createLibrary(final Resource libraryLocation, final boolean shared) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + SysdynResource sr = SysdynResource.getInstance(g); + + // Libraries can be created to model, function library and shared function library + if(!(g.isInstanceOf(libraryLocation, sr.SysdynModel) || + g.isInstanceOf(libraryLocation, sr.SysdynModelicaFunctionLibrary) || + g.isInstanceOf(libraryLocation, sr.SharedFunctionOntology))) + return; + + Resource root = libraryLocation; + + String name = "FunctionLibrary"; + Resource libraryType = sr.SysdynModelicaFunctionLibrary; + + if(shared) { + + try { + root = g.getResource("http://SharedOntologies"); + } catch (ResourceNotFoundException e) { + root = g.getResource("http:/"); + root = GraphUtils.create2(g, l0.Library, + l0.HasName, "SharedOntologies", + l0.PartOf, root); + } + + name = "Shared" + name; + libraryType = sr.SharedFunctionOntology; + } + + name = NameUtils.findFreshName(g, name, root, l0.ConsistsOf, "%s%d"); + + Resource functionLibrary = GraphUtils.create2(g, libraryType, + l0.HasName, name, + l0.HasDescription, "", + l0.PartOf, root); + + if(shared) + g.claim(libraryLocation, l0.IsLinkedTo, functionLibrary); + } + }); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewHistoryDataAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewHistoryDataAction.java new file mode 100644 index 00000000..43f0ffac --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewHistoryDataAction.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import java.util.UUID; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +/** + * Create a new history data + * + * @author Teemu Lempinen + * + */ +public class NewHistoryDataAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource experiment = (Resource)target; + + return new Runnable() { + @Override + public void run() { + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + if(!graph.isInstanceOf(experiment, sr.Experiment)) + return; // Not called from an experiment + + Resource model = graph.getPossibleObject(experiment, l0.PartOf); + // Create the history dataset + GraphUtils.create2(graph, + sr.HistoryDataset, + l0.HasName, "HistoryDataset" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(graph, "History Dataset", experiment), + sr.Experiment_result_Inverse, experiment, + sr.HistoryDataset_columns, Boolean.TRUE, + l0.PartOf, model); + } + }); + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewLineChartAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewLineChartAction.java new file mode 100644 index 00000000..b21e7fcf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewLineChartAction.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.UUID; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; + +/** + * Creates a new line chart + * @author Teemu Lempinen + * + */ +public class NewLineChartAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource model = (Resource)target; + + return new Runnable() { + @Override + public void run() { + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + G2DResource g2d = G2DResource.getInstance(graph); + + // Chart + Resource jfreechart = GraphUtils.create2(graph, jfree.Chart, + l0.HasName, "Chart" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(graph, "Chart", model), + l0.PartOf, model, + jfree.Chart_visibleBorder, true, + jfree.Chart_borderWidth, 3); + graph.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1}); + + // Title + GraphUtils.create2(graph, jfree.TextTitle, + l0.HasName, "TextTitle" + UUID.randomUUID().toString(), + l0.HasLabel, "Chart Title", + jfree.Title_position, jfree.Top, + l0.PartOf, jfreechart); + + // X-axis + Resource domainAxis = GraphUtils.create2(graph, jfree.NumberAxis, + l0.HasName, "NumberAxis" + UUID.randomUUID().toString()); + + // Y-axis + Resource rangeAxis = GraphUtils.create2(graph, jfree.NumberAxis, + l0.HasName, "NumberAxis" + UUID.randomUUID().toString(), + l0.HasLabel, "Y-axis"); + + // Renderer + Resource renderer = GraphUtils.create2(graph, jfree.XYLineRenderer); + + // Dataset + Resource dataset = GraphUtils.create2(graph, jfree.XYDataset, + l0.HasName, "XYDataset" + UUID.randomUUID().toString(), + jfree.Dataset_mapToDomainAxis, domainAxis, + jfree.Dataset_mapToRangeAxis, rangeAxis, + jfree.Dataset_seriesList, ListUtils.create(graph, new ArrayList()), + jfree.Dataset_renderer, renderer); + + // Plot + GraphUtils.create2(graph, jfree.XYPlot, + l0.HasName, "XYPlot" + UUID.randomUUID().toString(), + l0.PartOf, jfreechart, + jfree.Plot_domainAxis, domainAxis, + jfree.Plot_rangeAxis, rangeAxis, + jfree.Plot_rangeAxisList, ListUtils.create(graph, Collections.singletonList(rangeAxis)), + l0.ConsistsOf, dataset, + l0.ConsistsOf, domainAxis, + l0.ConsistsOf, rangeAxis); + } + + }); + } + }; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewModuleTypeAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewModuleTypeAction.java new file mode 100644 index 00000000..1d503d02 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewModuleTypeAction.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.db.layer0.adapter.Template; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.operation.Layer0X; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; + +/** + * Creates a new module type + * @author Teemu Lempinen + * + */ +public class NewModuleTypeAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource model = (Resource)target; + + return new Runnable() { + @Override + public void run() { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + Layer0X L0X = Layer0X.getInstance(g); + ModelingResources mr = ModelingResources.getInstance(g); + StructuralResource2 sr2 = StructuralResource2.getInstance(g); + + String name = NameUtils.findFreshName(g, "ModuleType", model, l0.ConsistsOf, "%s%d"); + + Resource moduleType = g.newResource(); + g.claimLiteral(moduleType, l0.HasName, name); + g.claim(moduleType, l0.Inherits, sr.Module); + g.claim(moduleType, l0.PartOf, model); + + + + Resource configuration = GraphUtils.create2(g, + sr.Configuration, + l0.HasName, name + "Configuration", + l0.PartOf, moduleType); + + g.claim(moduleType, sr2.IsDefinedBy , configuration); + + Resource diagram = g.newResource(); + g.adapt(sr.ConfigurationDiagramTemplate, Template.class).apply(g, + ArrayMap + .keys("", "diagram", "name") + .values(configuration, diagram, "Diagrammi") + ); + + + // Remove default mapping and add sysdyn mapping + for(Resource trigger : g.getObjects(diagram, L0X.HasTrigger)) { + if(g.isInstanceOf(trigger, mr.DiagramToCompositeMapping)) { + g.deny(diagram, L0X.HasTrigger, trigger); + } + } + + Resource mapping = g.newResource(); + g.claim(mapping, l0.InstanceOf, null, sr.DiagramToCompositeMapping); + g.claim(diagram, L0X.HasTrigger, mapping); + + Resource moduleSymbol = g.newResource(); + g.claimLiteral(moduleSymbol, l0.HasName, name + " Symbol"); + g.claimLiteral(moduleSymbol, l0.HasLabel, name + " Symbol"); + g.claim(moduleSymbol, l0.Inherits, sr.ModuleSymbol); + g.claim(moduleSymbol, mr.SymbolToComponentType, moduleType); + g.claim(moduleSymbol, l0.PartOf, moduleType); + + Resource terminal = g.newResource(); + g.claim(terminal, l0.InstanceOf, sr.SysdynTerminal); + Resource relation = createTerminalRelation(g, moduleSymbol, sr.IsHeadOfTerminal, sr.Variable_isHeadOf); + DiagramGraphUtil.addConnectionPoint(g, moduleSymbol, terminal, relation); + + Resource terminal2 = g.newResource(); + g.claim(terminal2, l0.InstanceOf, sr.SysdynTerminal); + relation = createTerminalRelation(g, moduleSymbol, sr.IsTailOfTerminal, sr.Variable_isTailOf); + DiagramGraphUtil.addConnectionPoint(g, moduleSymbol, terminal2, relation); + + g.claim(moduleSymbol, sr2.IsDefinedBy, OrderedSetUtils.create(g, sr2.Composite, terminal, terminal2)); + + + + } + }); + } + }; + } + + public static Resource createTerminalRelation(WriteGraph graph, Resource symbol, Resource connectionRelation, Resource configurationRelation) throws DatabaseException { + StructuralResource2 STR = StructuralResource2.getInstance(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + + + Resource terminalRelation = null; + terminalRelation = GraphUtils.create(graph, + MOD.DiagramConnectionRelationToConnectionRelation, configurationRelation, + L0.PartOf, symbol, + L0.HasName, NameUtils.getSafeName(graph, connectionRelation) + ); + + graph.claim(terminalRelation, L0.SubrelationOf, null, connectionRelation); + Resource inverse = GraphUtils.create(graph, + L0.PartOf, terminalRelation, + L0.HasName, "Inverse"); + + graph.claim(inverse, L0.SubrelationOf, null, STR.Connects); + graph.claim(terminalRelation, L0.InverseOf, inverse); + + return terminalRelation; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewPieChartAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewPieChartAction.java new file mode 100644 index 00000000..1ae83a6a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewPieChartAction.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import java.util.Collections; +import java.util.UUID; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; + +/** + * Creates a new pie chart + * @author Teemu Lempinen + * + */ +public class NewPieChartAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource model = (Resource)target; + + return new Runnable() { + @Override + public void run() { + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + G2DResource g2d = G2DResource.getInstance(graph); + + // Chart + Resource jfreechart = GraphUtils.create2(graph, jfree.Chart, + l0.HasName, "PieChart" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(graph, "Pie Chart", model), + l0.PartOf, model, + jfree.Chart_visibleBorder, true, + jfree.Chart_borderWidth, 3); + graph.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1}); + + // Title + GraphUtils.create2(graph, jfree.TextTitle, + l0.HasName, "TextTitle" + UUID.randomUUID().toString(), + l0.HasLabel, "Pie Chart Title", + jfree.Title_position, jfree.Top, + l0.PartOf, jfreechart); + + // Dataset + Resource dataset = GraphUtils.create2(graph, jfree.PieDataset, + l0.HasName, "CategoryDataset" + UUID.randomUUID().toString(), + jfree.Dataset_seriesList, ListUtils.create(graph, Collections.emptyList()) + ); + + // Plot + GraphUtils.create2(graph, jfree.PiePlot, + l0.HasName, "PiePlot" + UUID.randomUUID().toString(), + l0.PartOf, jfreechart, + l0.ConsistsOf, dataset + ); + } + + }); + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSharedFunctionLibraryAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSharedFunctionLibraryAction.java new file mode 100644 index 00000000..98efd114 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSharedFunctionLibraryAction.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import org.simantics.db.Resource; + +/** + * Creates a new shared function library + * @author Teemu Lempinen + * + */ +public class NewSharedFunctionLibraryAction extends NewFunctionLibraryAction { + + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource resource = (Resource)target; + + return new Runnable() { + @Override + public void run() { + createLibrary(resource, true); + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSheetAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSheetAction.java new file mode 100644 index 00000000..e579df6c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSheetAction.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ActionFactory; +import org.simantics.sysdyn.utils.SheetUtils; +import org.simantics.ui.SimanticsUI; + +/** + * Creates a new spreadsheet to a book + * @author Teemu Lempinen + * + */ +public class NewSheetAction implements ActionFactory{ + + @Override + public Runnable create(Object target) { + if(!(target instanceof Resource)) + return null; + final Resource book = (Resource)target; + + return new Runnable() { + @Override + public void run() { + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SheetUtils.createSheet(graph, book, null, new String[] {}, new int[] {50}); + } + + }); + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSimulationPlaybackExperimentAction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSimulationPlaybackExperimentAction.java new file mode 100644 index 00000000..b0363b95 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSimulationPlaybackExperimentAction.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.newActions; + +import java.awt.Color; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; + +/** + * Creates a new simulation playback experiment + * @author Teemu Lempinen + * + */ +public class NewSimulationPlaybackExperimentAction extends NewExperimentAction { + + protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException { + G2DResource g2d = G2DResource.getInstance(graph); + Resource defaultGradient = GraphUtils.create2(graph, g2d.ColorGradient); + graph.claim(experiment, g2d.HasColorGradient, defaultGradient); + + Resource placement = GraphUtils.create2(graph, g2d.ColorPlacement, + g2d.HasGradientPosition, 0.0); + graph.claimLiteral(placement, g2d.HasColor, g2d.Color, new Color(0, 62, 133).getColorComponents(new float[4])); + graph.claim(defaultGradient, g2d.HasColorPlacement, placement); + + placement = GraphUtils.create2(graph, g2d.ColorPlacement, + g2d.HasGradientPosition, 1.0); + graph.claimLiteral(placement, g2d.HasColor, g2d.Color, new Color(255, 230, 0).getColorComponents(new float[4])); + graph.claim(defaultGradient, g2d.HasColorPlacement, placement); + } + + protected Resource getExperimentType(ReadGraph g) { + return SysdynResource.getInstance(g).PlaybackExperiment; + } + + protected String getNameSuggestion() { + return "Playback Experiment"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/remove/ModuleTypeRemover.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/remove/ModuleTypeRemover.java new file mode 100644 index 00000000..e21bd811 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/remove/ModuleTypeRemover.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.actions.remove; + +import java.util.Map; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.Remover; +import org.simantics.modeling.ui.modelBrowser.handlers.DeleteNodeHandler; + +/** + * Remover for module type nodes. Not functioning - {@link DeleteNodeHandler} prevents deleting other than entityNodes + * + * @author Teemu Lempinen + * + */ +public class ModuleTypeRemover implements Remover { + + private Resource resource; + + public ModuleTypeRemover(ReadGraph graph, Resource resource) { + this.resource = resource; + } + + @Override + public String canRemove(ReadGraph graph, Map aux) throws DatabaseException { + return null; + } + + @Override + public void remove(WriteGraph graph) throws DatabaseException { + System.out.println("Delete resource " + resource); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleContentChildRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleContentChildRule.java new file mode 100644 index 00000000..df545e7f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleContentChildRule.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.childrules; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; + +/** + * Child rule for displaying children of module types in Modules folder + * @author Teemu Lempinen + * + */ +public class ModuleContentChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) throws DatabaseException { + ArrayList children = new ArrayList(); + + if(!(parent instanceof Resource)) { + return children; + } + + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 str = StructuralResource2.getInstance(graph); + + Resource symbol = (Resource)parent; + + // Find module component + Resource component = graph.getPossibleObject(symbol,ModelingResources.getInstance(graph).SymbolToComponentType); + + if(component == null) + return children; + + // Find component configuration + Resource configuration = graph.getSingleObject(component, str.IsDefinedBy); + + if(configuration == null) + return children; + + // Add all components + children.addAll(graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, str.Component))); + + return children; + } + + @Override + public Collection getParents(ReadGraph graph, Object child) + throws DatabaseException { + return new ArrayList(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleTypeChildRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleTypeChildRule.java new file mode 100644 index 00000000..111d12c3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleTypeChildRule.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.childrules; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; + +/** + * Child rule for finding module types defined in a model + * @author Teemu Lempinen + * + */ +public class ModuleTypeChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) + throws DatabaseException { + + ArrayList children = new ArrayList(); + + if(!(parent instanceof Resource)) { + return children; + } + + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 st = StructuralResource2.getInstance(graph); + + Resource model = (Resource)parent; + if(!graph.isInstanceOf(model, SysdynResource.getInstance(graph).SysdynModel)) + return children; + + // Find all component types that are inherited from SYSDYN.Module + for(Resource r : graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, st.ComponentType))) { + if(graph.isInheritedFrom(r, SysdynResource.getInstance(graph).Module)) { + Resource symbol = graph.getPossibleObject(r,ModelingResources.getInstance(graph).ComponentTypeToSymbol); + children.add(symbol); + } + } + + return children; + } + + @Override + public Collection getParents(ReadGraph graph, Object child) + throws DatabaseException { + return new ArrayList(); + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/VariableChildRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/VariableChildRule.java new file mode 100644 index 00000000..aaecd2d0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/VariableChildRule.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.childrules; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.sysdyn.SysdynResource; + +/** + * Child rule for building model configuration out of Variable nodes + * @author Teemu Lempinen + * + */ +public class VariableChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Variable.class) || contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) throws DatabaseException { + + ArrayList result = new ArrayList(); + + if (parent == null) { + return result; + } + + Variable variable = null; + + if(parent instanceof Variable) { + variable = (Variable) parent; + } else if(parent instanceof Resource) { + variable = Variables.getVariable(graph, (Resource)parent); + } + + if(variable == null) + return result; + + SysdynResource sr = SysdynResource.getInstance(graph); + + ArrayList variables = new ArrayList(); + + for(Variable child : variable.browseChildren(graph)) { + Resource represents = (Resource)child.getPropertyValue(graph, Variables.REPRESENTS); + if(graph.isInstanceOf(represents, sr.IndependentVariable)) { + variables.add(child); + } else if (graph.isInstanceOf(represents, sr.Input)) { + variables.add(child); + } else if (graph.isInstanceOf(represents, sr.Module)) { + variables.add(child); + } else if (graph.isInstanceOf(represents, sr.Enumeration)) { + variables.add(child); + } + } + + for (Variable v : variables) { + result.add(v); + } + + return result; + } + + @Override + public Collection getParents(ReadGraph graph, Object child) throws DatabaseException { + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeImager.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeImager.java new file mode 100644 index 00000000..802a846a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeImager.java @@ -0,0 +1,236 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.Collection; +import java.util.HashSet; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IDecoration; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.swt.ImagerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.issues.Severity; +import org.simantics.issues.common.MaxIssueSeverityRecursive; +import org.simantics.issues.ontology.IssueResource; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.browser.nodes.BookNode; +import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder; +import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode; +import org.simantics.sysdyn.ui.browser.nodes.FunctionNode; +import org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder; +import org.simantics.sysdyn.ui.browser.nodes.InputNode; +import org.simantics.sysdyn.ui.browser.nodes.ModelNode; +import org.simantics.sysdyn.ui.browser.nodes.ModuleNode; +import org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode; +import org.simantics.sysdyn.ui.browser.nodes.ModulesNode; +import org.simantics.sysdyn.ui.browser.nodes.SCLModule; +import org.simantics.sysdyn.ui.browser.nodes.SCLModulesFolder; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder; +import org.simantics.sysdyn.ui.browser.nodes.SheetNode; +import org.simantics.sysdyn.ui.browser.nodes.VariableNode; +import org.simantics.utils.ui.gfx.DecorationOverlayIcon; + +/** + * Imager for nodes in old sysdyn model browser + * @author Teemu Lempinen + * + */ +public class AbstractNodeImager extends ImagerContributor> { + + @Override + public ImageDescriptor getDescriptor(ReadGraph graph, AbstractNode node) throws DatabaseException { + + String image = null; + if (node instanceof SharedFunctionsFolder) + image = "icons/folder_link.png"; + else if (node instanceof ExperimentsFolder || + node instanceof ModulesNode || + node instanceof FunctionsFolder || + node instanceof FunctionLibraryNode || + node instanceof SCLModulesFolder || + node instanceof SharedFunctionLibraryNode) + image = "icons/folder.png"; + else if (node instanceof ModuleTypeNode || node instanceof ModuleNode || node instanceof ConfigurationNode) + image = "icons/bricks.png"; + else if (node instanceof SCLModule) + image = "icons/bullet_gray.png"; + else if (node instanceof ExperimentNode) { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.isInstanceOf(node.data, sr.PlaybackExperiment)) + image = "icons/timeline_marker.png"; + else if(graph.isInstanceOf(node.data, sr.GameExperiment)) + image = "icons/time_go.png"; + else if(graph.isInstanceOf(node.data, sr.SensitivityAnalysisExperiment)) + image = "icons/time_rainbow.png"; + else + image = "icons/time.png"; + } else if (node instanceof InputNode) + image = "icons/brick_link.png"; + else if (node instanceof ModelNode) + image = "icons/chart_organisation.png"; + else if (node instanceof FunctionNode) { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + if (graph.hasStatement(node.data, l0.PartOf, sr.Built$in_Functions)) { + // Sysdyn functions + image = "icons/sysdynFunction.png"; + } else if (graph.hasStatement(node.data, l0.PartOf, sr.Built$in_Functions_Modelica_Functions)) { + image = "icons/modelicaFunction.png"; + } else if (graph.hasStatement(node.data, l0.PartOf, sr.Built$in_Functions_Modelica_Array_Functions)) { + image = "icons/modelicaArrayFunction.png"; + } else if (graph.hasStatement(node.data, l0.PartOf, sr.Built$in_Functions_Vensim_Functions)) { + image = "icons/vensimFunction.png"; + } else { + Resource r = graph.getPossibleObject(node.data, l0.PartOf); + if (r != null) { + boolean shared = false; + do { + shared = graph.isInstanceOf(r, sr.SharedFunctionOntology); + r = graph.getPossibleObject(r, l0.PartOf); + } while (!shared && (r != null)); + if (shared) { + image = "icons/functionLink.png"; + } else { + image = "icons/function.png"; + } + } + } + } else if (node instanceof VariableNode) + // Must be queried after FunctionNode + image = "icons/brick.png"; + else if (node instanceof BookNode) + image = "icons/table_multiple.png"; + else if (node instanceof SheetNode) + image = "icons/table.png"; + + if (image != null) { + + ImageDescriptor id = ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(image)); + + Severity maxSeverity = getMaxSeverity(graph, node); + + if (maxSeverity == null) + return id; + else + return getDecoration(id, maxSeverity); + } + return null; + } + + /** + * + * @param graph + * @param node + * @return + * @throws DatabaseException + */ + private Severity getMaxSeverity(ReadGraph graph, AbstractNode node) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + IssueResource.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + + HashSet issueTypes = new HashSet(); + issueTypes.add(SR.Variable); + issueTypes.add(SR.Configuration); + issueTypes.add(SR.Module); + + Resource data = node.data; + if(node instanceof ModuleTypeNode) { + Resource symbol = node.data; + Resource moduleType = graph.getPossibleObject(symbol, L0.PartOf); + data = graph.getPossibleObject(moduleType, StructuralResource2.getInstance(graph).IsDefinedBy); + } else if(node instanceof ModuleNode) { + Resource moduleType = graph.getPossibleObject(node.data, L0.InstanceOf); + data = graph.getPossibleObject(moduleType, StructuralResource2.getInstance(graph).IsDefinedBy); + } else if(node instanceof ModelNode) { + data = graph.getPossibleObject(node.data, SimulationResource.getInstance(graph).HasConfiguration); + } + + Severity maxSeverity = getMaxSeverityStructural(graph, data, issueTypes, null); + return maxSeverity; + } + + /** + * Recursive function for obtaining maximum severity of a configuration and its module + * children + * + * @param graph readGraph + * @param resource Resource from which issues are searched for. If the resource is configuraiton, issues are searched also from its module children. + * @param issueTypes Issue type resources + * @param severity Maximum current severity + * @return + * @throws DatabaseException + */ + private Severity getMaxSeverityStructural(ReadGraph graph, Resource resource, HashSet issueTypes, Severity severity) throws DatabaseException { + if(resource == null) + return severity; + + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + + Resource data = resource; + Severity maxSeverity = graph.syncRequest(new MaxIssueSeverityRecursive(data, L0.ConsistsOf, issueTypes)); + + // Try structural + if(graph.isInstanceOf(data, SR.Configuration)) { + Collection moduleChildren = graph.syncRequest(new ModuleChildren(data)); + for(Resource r : moduleChildren) { + Resource moduleType = graph.getPossibleObject(r, L0.InstanceOf); + Resource configuration = graph.getPossibleObject(moduleType, StructuralResource2.getInstance(graph).IsDefinedBy); + if(configuration != null) + maxSeverity = getMaxSeverityStructural(graph, configuration, issueTypes, maxSeverity); + } + } + + return Severity.moreSevere(maxSeverity, severity); + } + + /** + * Request for obtaining all module children of a configuration + * @author Teemu Lempinen + * + */ + private class ModuleChildren implements Read> { + + Resource configuration; + + public ModuleChildren(Resource configuration) { + this.configuration = configuration; + } + + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + return graph.syncRequest(new ObjectsWithType(configuration, Layer0.getInstance(graph).ConsistsOf, SysdynResource.getInstance(graph).Module)); + } + } + + private ImageDescriptor getDecoration(ImageDescriptor original, Severity severity) { + ImageDescriptor img = Activator.getDefault().getImageRegistry().getDescriptor(severity.toString()); + if (original == null || original.getImageData() == null) + return img; + else + return new DecorationOverlayIcon(original, img, IDecoration.BOTTOM_LEFT); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeLabeler.java new file mode 100644 index 00000000..6fd403f2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeLabeler.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; + +public class AbstractNodeLabeler extends LabelerContributor> { + + @Override + public String getLabel(ReadGraph graph, AbstractNode node) throws DatabaseException { + if (!graph.hasStatement(node.data)) + return ""; + return graph.adapt(node.data, String.class); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Book.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Book.java new file mode 100644 index 00000000..8bd950fc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Book.java @@ -0,0 +1,29 @@ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.spreadsheet.resource.SpreadsheetResource; +import org.simantics.sysdyn.ui.browser.nodes.BookNode; +import org.simantics.sysdyn.ui.browser.nodes.SheetNode; + +public class Book extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, BookNode book) throws DatabaseException { + ArrayList> result = new ArrayList>(); + Layer0 l0 = Layer0.getInstance(graph); + for(Resource r : graph.syncRequest(new ObjectsWithType(book.data, l0.ConsistsOf, SpreadsheetResource.getInstance(graph).Spreadsheet))) { + result.add(new SheetNode(r)); + } + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/BookLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/BookLabeler.java new file mode 100644 index 00000000..88d28501 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/BookLabeler.java @@ -0,0 +1,20 @@ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.BookNode; + +public class BookLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, BookNode input) throws DatabaseException { + return "SpreadSheets"; + } + + @Override + public int getCategory(ReadGraph graph, BookNode input) throws DatabaseException { + return -1; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartImager.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartImager.java new file mode 100644 index 00000000..11bb85eb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartImager.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.swt.ImagerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.browser.nodes.AbstractChartNode; +import org.simantics.sysdyn.ui.browser.nodes.BarChartNode; +import org.simantics.sysdyn.ui.browser.nodes.LineChartNode; +import org.simantics.sysdyn.ui.browser.nodes.PieChartNode; +import org.simantics.sysdyn.ui.browser.nodes.SensitivityChartNode; + +/** + * Provides image for {@link LineChartNode} in model browser + * @author Teemu Lempinen + * + */ +public class ChartImager extends ImagerContributor> { + + @Override + public ImageDescriptor getDescriptor(ReadGraph graph, AbstractChartNode input) throws DatabaseException { + if(input instanceof SensitivityChartNode) + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/rainbow.png")); + else if(input instanceof BarChartNode) + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar.png")); + else if(input instanceof PieChartNode) + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_pie.png")); + else + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_line.png")); + + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartLabeler.java new file mode 100644 index 00000000..1301ab5f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartLabeler.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.browser.nodes.AbstractChartNode; +import org.simantics.sysdyn.ui.browser.nodes.LineChartNode; + +/** + * Provides label for {@link LineChartNode} in model browser + * @author Teemu Lempinen + * + */ +public class ChartLabeler extends LabelerContributor> { + + @Override + public String getLabel(ReadGraph graph, AbstractChartNode chart) throws DatabaseException { + String name = graph.getPossibleRelatedValue(chart.data, Layer0.getInstance(graph).HasLabel); + return name == null ? "Chart (no label)" : name; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Charts.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Charts.java new file mode 100644 index 00000000..5abab1e8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Charts.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.BarChartNode; +import org.simantics.sysdyn.ui.browser.nodes.LineChartNode; +import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; +import org.simantics.sysdyn.ui.browser.nodes.PieChartNode; +import org.simantics.sysdyn.ui.browser.nodes.SensitivityChartNode; + +/** + * Class for creating chart nodes for model browser + * @author Teemu Lempinen + * + */ +public class Charts extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, ChartsFolder folder) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + JFreeChartResource JFREE = JFreeChartResource.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + + ArrayList> result = new ArrayList>(); + for(Resource chart : graph.syncRequest( + new ObjectsWithType(folder.data, + L0.ConsistsOf, + JFREE.Chart))) { + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, L0.ConsistsOf, JFREE.Plot)); + if(plot != null) { + if(graph.isInstanceOf(plot, SR.Charts_SensitivityPlot)) { + result.add(new SensitivityChartNode(chart)); + } else if(graph.isInstanceOf(plot, JFREE.XYPlot)) { + result.add(new LineChartNode(chart)); + } else if(graph.isInstanceOf(plot, JFREE.CategoryPlot)) { + result.add(new BarChartNode(chart)); + } else if(graph.isInstanceOf(plot, JFREE.PiePlot)) { + result.add(new PieChartNode(chart)); + } + } + } + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsImager.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsImager.java new file mode 100644 index 00000000..e51b8e74 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsImager.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.swt.ImagerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; + +/** + * Provides image for {@link ChartsFolder} in model browser + * @author Teemu Lempinen + * + */ +public class ChartsImager extends ImagerContributor { + + @Override + public ImageDescriptor getDescriptor(ReadGraph graph, ChartsFolder chartNode) throws DatabaseException { + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/folder.png")); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsLabeler.java new file mode 100644 index 00000000..ff4dc7aa --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsLabeler.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; + +/** + * Provides label for {@link ChartsFolder} in model browser + * @author Teemu Lempinen + * + */ +public class ChartsLabeler extends LabelerContributor { + + @Override + public String getLabel(ReadGraph graph, ChartsFolder input) throws DatabaseException { + return "Charts"; + } + + @Override + public int getCategory(ReadGraph graph, ChartsFolder input) throws DatabaseException { + return -3; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java new file mode 100644 index 00000000..d50bfbc2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.TreeMap; + +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.spreadsheet.resource.SpreadsheetResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.BookNode; +import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode; +import org.simantics.sysdyn.ui.browser.nodes.EnumerationNode; +import org.simantics.sysdyn.ui.browser.nodes.InputNode; +import org.simantics.sysdyn.ui.browser.nodes.ModuleNode; +import org.simantics.sysdyn.ui.browser.nodes.VariableNode; +import org.simantics.utils.strings.AlphanumComparator; + +public class Configuration extends ViewpointContributor> { + + @Override + public Collection getContribution(ReadGraph graph, ConfigurationNode configuration) throws DatabaseException { + ArrayList result = new ArrayList(); + Variable variable = configuration.getVariable(); + + if (variable == null) { + return result; + } + + SysdynResource sr = SysdynResource.getInstance(graph); + TreeMap variables = new TreeMap(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR); + TreeMap inputs = new TreeMap(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR); + TreeMap modules = new TreeMap(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR); + TreeMap enumerations = new TreeMap(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR); + + + for(Variable child : variable.browseChildren(graph)) { + Resource represents = (Resource)child.getPropertyValue(graph, Variables.REPRESENTS); + if(graph.isInstanceOf(represents, sr.IndependentVariable)) { + variables.put(child.getName(graph), child); + } else if (graph.isInstanceOf(represents, sr.Input)) { + inputs.put(child.getName(graph), child); + } else if (graph.isInstanceOf(represents, sr.Module)) { + modules.put(child.getName(graph), child); + } else if (graph.isInstanceOf(represents, sr.Enumeration)) { + enumerations.put(child.getName(graph), child); + } + } + + for (String s : variables.keySet()) { + Variable v = variables.get(s); + Resource represents = (Resource)v.getPropertyValue(graph, Variables.REPRESENTS); + result.add(new VariableNode(v, represents)); + } + + for (String s : inputs.keySet()) { + Variable v = inputs.get(s); + Resource represents = (Resource)v.getPropertyValue(graph, Variables.REPRESENTS); + result.add(new InputNode(v, represents)); + } + + for (String s : modules.keySet()) { + Variable v = modules.get(s); + Resource represents = (Resource)v.getPropertyValue(graph, Variables.REPRESENTS); + result.add(new ModuleNode(v, represents)); + } + + for (String s : enumerations.keySet()) { + Variable v = enumerations.get(s); + Resource represents = (Resource)v.getPropertyValue(graph, Variables.REPRESENTS); + result.add(new EnumerationNode(v, represents)); + } + + for(Resource r : graph.syncRequest(new ObjectsWithType( + configuration.data, + Layer0.getInstance(graph).ConsistsOf, + SpreadsheetResource.getInstance(graph).Book))) { + result.add(new BookNode(r)); + } + + return result; + } + + @Override + public String getViewpointId() { + return "Standard"; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ConfigurationLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ConfigurationLabeler.java new file mode 100644 index 00000000..c3039e4a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ConfigurationLabeler.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode; + +public class ConfigurationLabeler extends LabelerContributor>{ + + @Override + public String getLabel(ReadGraph graph, ConfigurationNode conf) throws DatabaseException { + return "Configuration"; + } + + @Override + public int getCategory(ReadGraph graph, ConfigurationNode input) throws DatabaseException { + return -7; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Experiment.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Experiment.java new file mode 100644 index 00000000..9e7aff06 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Experiment.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder; + +public class Experiment extends ViewpointContributor { + + @SuppressWarnings("unchecked") + @Override + public Collection getContribution(ReadGraph graph, ExperimentsFolder experimentsFolder) throws DatabaseException { + ArrayList> result = new ArrayList>(); + Layer0 l0 = Layer0.getInstance(graph); + for(Resource r : graph.syncRequest(new ObjectsWithType(experimentsFolder.data, l0.ConsistsOf, SimulationResource.getInstance(graph).Experiment))) { + try { + result.add(graph.adapt(r, AbstractNode.class)); + } catch(DatabaseException e) { + e.printStackTrace(); + } + } + return result; + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabelDecorator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabelDecorator.java new file mode 100644 index 00000000..d86672d5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabelDecorator.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.swt.SWT; +import org.simantics.browsing.ui.content.LabelDecorator; +import org.simantics.browsing.ui.graph.contributor.labeler.LabelDecoratorContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode; + +public class ExperimentLabelDecorator extends LabelDecoratorContributor { + + @Override + public LabelDecorator getDecorator(ReadGraph graph, ExperimentNode experimentNode) throws DatabaseException { + if (graph.hasStatement(experimentNode.data, SimulationResource.getInstance(graph).IsActive)) { + return new LabelDecorator.Stub() { + @Override + public String decorateLabel(String label, String column, int itemIndex) { + return label + " [ACTIVE]"; + } + + @SuppressWarnings("unchecked") + @Override + public F decorateFont(F font, String column, int itemIndex) { + return (F) ((FontDescriptor) font).withStyle(SWT.BOLD); + } + }; + } + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabeler.java new file mode 100644 index 00000000..865638d5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabeler.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ + +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode; + +public class ExperimentLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, ExperimentNode experiment) throws DatabaseException { + String name = graph.getPossibleRelatedValue(experiment.data, Layer0.getInstance(graph).HasLabel); + return name == null ? "Experiment (no name)" : name; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentsLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentsLabeler.java new file mode 100644 index 00000000..98f5f332 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentsLabeler.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ + +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder; + +public class ExperimentsLabeler extends LabelerContributor { + + @Override + public String getLabel(ReadGraph graph, ExperimentsFolder experiments) throws DatabaseException { + return "Experiments"; + } + + @Override + public int getCategory(ReadGraph graph, ExperimentsFolder input) throws DatabaseException { + return -6; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraries.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraries.java new file mode 100644 index 00000000..5cd6bbee --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraries.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.TreeMap; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode; +import org.simantics.sysdyn.ui.browser.nodes.FunctionNode; +import org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder; +import org.simantics.utils.strings.AlphanumComparator; + +public class FunctionLibraries extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, FunctionsFolder functionsFolder) + throws DatabaseException { + + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + ArrayList> result = new ArrayList>(); + + TreeMap sortResult = new TreeMap(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR); + // Find and sort model functions + for(Resource function : graph.syncRequest(new ObjectsWithType(functionsFolder.data, l0.ConsistsOf, sr.SysdynModelicaFunction))) { + sortResult.put(NameUtils.getSafeName(graph, function), function); + } + for(Resource function : sortResult.values()) + result.add(new FunctionNode(function)); + + // Find and sort model function libraries + sortResult.clear(); + for(Resource functionLibrary : graph.syncRequest(new ObjectsWithType(functionsFolder.data, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))) { + sortResult.put(NameUtils.getSafeName(graph, functionLibrary), functionLibrary); + } + for(Resource functionLibrary : sortResult.values()) + result.add(new FunctionLibraryNode(functionLibrary)); + + // Find built-in functions + Resource sysdyn = graph.getPossibleResource("http://www.simantics.org/Sysdyn-1.1"); + if(sysdyn != null) { + for(Resource library : graph.syncRequest(new ObjectsWithType(sysdyn, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))) { + result.add(new FunctionLibraryNode(library)); + } + } + + + result.add(new SharedFunctionsFolder(functionsFolder.data)); + + return result; + + } + + @Override + public String getViewpointId() { + return "Standard"; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraryLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraryLabeler.java new file mode 100644 index 00000000..96ef1f96 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraryLabeler.java @@ -0,0 +1,24 @@ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode; + +public class FunctionLibraryLabeler extends LabelerContributor>{ + + @Override + public String getLabel(ReadGraph graph, FunctionLibraryNode input) + throws DatabaseException { + String name = NameUtils.getSafeName(graph, input.data); + return name; + } + + @Override + public int getCategory(ReadGraph graph, FunctionLibraryNode input) throws DatabaseException { + return -1; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionsLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionsLabeler.java new file mode 100644 index 00000000..421c9e6a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionsLabeler.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder; + +public class FunctionsLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, FunctionsFolder input) throws DatabaseException { + return "Functions"; + } + + @Override + public int getCategory(ReadGraph graph, FunctionsFolder input) throws DatabaseException { + return -4; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InputLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InputLabeler.java new file mode 100644 index 00000000..7d34ce2c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InputLabeler.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.ui.browser.nodes.InputNode; + +public class InputLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, InputNode var) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + Resource varres = var.data; + StringBuilder sb = new StringBuilder(); + for(Resource r : graph.getObjects(varres, l0.HasName)) + sb.append(graph.getValue(r)); + if(graph.isInstanceOf(varres, L0X.Realization)) { + varres = graph.getPossibleObject(varres, L0X.Represents); + if(varres == null) return sb.toString(); + } + sb.append(" : "); + for(Resource t : graph.getObjects(varres, l0.InstanceOf)) + for(Resource r : graph.getObjects(t, l0.HasName)) + sb.append(graph.getValue(r)); + return sb.toString(); + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryFunctions.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryFunctions.java new file mode 100644 index 00000000..6e3a1a1f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryFunctions.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.TreeMap; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode; +import org.simantics.sysdyn.ui.browser.nodes.FunctionNode; +import org.simantics.utils.strings.AlphanumComparator; + +public class LibraryFunctions extends ViewpointContributor> { + + @Override + public Collection getContribution(ReadGraph graph, + FunctionLibraryNode library) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + ArrayList> result = new ArrayList>(); + + TreeMap sortResult = new TreeMap(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR); + + // Find and sort functions in library + for(Resource function : graph.syncRequest(new ObjectsWithType(library.data, l0.ConsistsOf, SysdynResource.getInstance(graph).SysdynModelicaFunction))) { + sortResult.put(NameUtils.getSafeName(graph, function), function); + } + for(Resource function : sortResult.values()) + result.add(new FunctionNode(function)); + + // Find and sort libraries in library + sortResult.clear(); + for(Resource functionLibrary : graph.syncRequest(new ObjectsWithType(library.data, l0.ConsistsOf, SysdynResource.getInstance(graph).SysdynModelicaFunctionLibrary))) { + sortResult.put(NameUtils.getSafeName(graph, functionLibrary), functionLibrary); + } + for(Resource functionLibrary : sortResult.values()) + result.add(new FunctionLibraryNode(functionLibrary)); + + return result; + + } + + @Override + public String getViewpointId() { + return "Standard"; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Model.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Model.java new file mode 100644 index 00000000..90079b11 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Model.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.primitiverequest.PossibleObject; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; +import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder; +import org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder; +import org.simantics.sysdyn.ui.browser.nodes.ModelNode; +import org.simantics.sysdyn.ui.browser.nodes.ModulesNode; +import org.simantics.sysdyn.ui.browser.nodes.SCLModulesFolder; + +/** + * Provides children for a model in model browser + * @author Teemu Lempinen + * + */ +public class Model extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, ModelNode model) + throws DatabaseException { + ArrayList> result = new ArrayList>(); + + Layer0X L0X = Layer0X.getInstance(graph); + Resource baseRealization = graph.syncRequest(new PossibleObject(model.data, L0X.HasBaseRealization)); + if (baseRealization != null) { + try { + String URI = graph.getURI(baseRealization); + Variable variable = Variables.getVariable(graph, URI); + result.add(new ConfigurationNode(variable, baseRealization)); + } catch (DatabaseException e) { + } + } + result.add(new ExperimentsFolder(model.data)); + result.add(new ModulesNode(model.data)); + result.add(new FunctionsFolder(model.data)); + result.add(new ChartsFolder(model.data)); +// result.add(new SCLModulesFolder(model.data)); + return result; + } + + @Override + public String getViewpointId() { + return "Standard"; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModelLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModelLabeler.java new file mode 100644 index 00000000..16798d8c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModelLabeler.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.browser.nodes.ModelNode; + +public class ModelLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, ModelNode model) throws DatabaseException { + String label = graph.getPossibleRelatedValue(model.data, Layer0.getInstance(graph).HasLabel); + return label == null ? "Model (no name)" : label; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleLabeler.java new file mode 100644 index 00000000..6c268098 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleLabeler.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.ui.browser.nodes.ModuleNode; + +public class ModuleLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, ModuleNode module) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + Resource resource = module.data; + StringBuilder sb = new StringBuilder(); + for(Resource r : graph.getObjects(resource, l0.HasName)) + sb.append(graph.getValue(r)); + if(graph.isInstanceOf(resource, L0X.Realization)) { + resource = graph.getPossibleObject(resource, L0X.Represents); + if(resource == null) return sb.toString(); + } + sb.append(" : "); + for(Resource t : graph.getObjects(resource, l0.InstanceOf)) + for(Resource r : graph.getObjects(t, l0.HasName)) + sb.append(graph.getValue(r)); + return sb.toString(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleType.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleType.java new file mode 100644 index 00000000..4ebe335e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleType.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.TreeMap; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.EnumerationNode; +import org.simantics.sysdyn.ui.browser.nodes.InputNode; +import org.simantics.sysdyn.ui.browser.nodes.ModuleNode; +import org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode; +import org.simantics.sysdyn.ui.browser.nodes.VariableNode; +import org.simantics.utils.strings.AlphanumComparator; + +public class ModuleType extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, ModuleTypeNode module) throws DatabaseException { + ArrayList> result = new ArrayList>(); + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 str = StructuralResource2.getInstance(graph); + + ModelingResources mr = ModelingResources.getInstance(graph); + Resource instance = graph.getPossibleObject(module.data, mr.SymbolToComponentType); + + if(instance == null) return result; + Resource conf = graph.getSingleObject(instance, str.IsDefinedBy); + + // Independent variables + TreeMap variables = new TreeMap(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR); + for(Resource r : graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, sr.IndependentVariable))) { + variables.put((String)graph.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING), r); + } + for(String key : variables.keySet()) + result.add(new VariableNode(variables.get(key))); + + // Inputs + variables.clear(); + for(Resource r : graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, sr.Input))) { + variables.put((String)graph.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING), r); + } + for(String key : variables.keySet()) + result.add(new InputNode(variables.get(key))); + + // Modules + variables.clear(); + for(Resource r : graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, sr.Module))) { + variables.put((String)graph.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING), r); + } + for(String key : variables.keySet()) + result.add(new ModuleNode(variables.get(key))); + + // Enumerations + variables.clear(); + for(Resource r : graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, sr.Enumeration))) { + variables.put((String)graph.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING), r); + } + for(String key : variables.keySet()) + result.add(new EnumerationNode(variables.get(key))); + + return result; + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleTypeLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleTypeLabeler.java new file mode 100644 index 00000000..32654013 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleTypeLabeler.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode; + +public class ModuleTypeLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, ModuleTypeNode moduleType) throws DatabaseException { + ModelingResources mr = ModelingResources.getInstance(graph); + Resource typeResource = graph.getPossibleObject(moduleType.data, mr.SymbolToComponentType); + String label = null; + if(typeResource != null) + label = graph.getPossibleRelatedValue(typeResource, Layer0.getInstance(graph).HasName); + return label == null ? "ModuleType (no name)" : label; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Modules.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Modules.java new file mode 100644 index 00000000..41bf4e96 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Modules.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode; +import org.simantics.sysdyn.ui.browser.nodes.ModulesNode; + +public class Modules extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, ModulesNode model) + throws DatabaseException { + + ArrayList> result = new ArrayList>(); + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 st = StructuralResource2.getInstance(graph); + for(Resource r : graph.syncRequest(new ObjectsWithType(model.data, l0.ConsistsOf, st.ComponentType))) { + if(graph.isInheritedFrom(r, SysdynResource.getInstance(graph).Module)) { + Resource symbol = graph.getPossibleObject(r,ModelingResources.getInstance(graph).ComponentTypeToSymbol); + result.add(new ModuleTypeNode(symbol)); + } + } + return result; + + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModulesLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModulesLabeler.java new file mode 100644 index 00000000..c271365a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModulesLabeler.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ + +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder; +import org.simantics.sysdyn.ui.browser.nodes.ModulesNode; + +public class ModulesLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, ModulesNode input) throws DatabaseException { + return "Modules"; + } + + @Override + public int getCategory(ReadGraph graph, ModulesNode input) throws DatabaseException { + return -5; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/OperatingInterfacesLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/OperatingInterfacesLabeler.java new file mode 100644 index 00000000..8c7a8c6c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/OperatingInterfacesLabeler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.OperatingInterfacesFolder; + +public class OperatingInterfacesLabeler extends LabelerContributor { + + @Override + public String getLabel(ReadGraph graph, OperatingInterfacesFolder input) throws DatabaseException { + return "Operating interfaces"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Project.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Project.java new file mode 100644 index 00000000..5506660f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Project.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; + +public class Project extends ViewpointContributor { + + @SuppressWarnings("unchecked") + @Override + public Collection getContribution(ReadGraph graph, Resource project) + throws DatabaseException { + + ArrayList> result = new ArrayList>(); + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource r : graph.syncRequest(new ObjectsWithType(project, l0.ConsistsOf, sr.SysdynModel))) { + try { + result.add(graph.adapt(r, AbstractNode.class)); + } catch(DatabaseException e) { + e.printStackTrace(); + } + } + return result; + + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModuleLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModuleLabeler.java new file mode 100644 index 00000000..97cdb9b5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModuleLabeler.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.SCLModule; + +public class SCLModuleLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, SCLModule input) throws DatabaseException { + return NameUtils.getSafeName(graph, input.data); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModules.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModules.java new file mode 100644 index 00000000..edd997fe --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModules.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.browser.nodes.SCLModule; +import org.simantics.sysdyn.ui.browser.nodes.SCLModulesFolder; + +public class SCLModules extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, SCLModulesFolder model) + throws DatabaseException { + + ArrayList> result = new ArrayList>(); + Layer0 l0 = Layer0.getInstance(graph); + + for(Resource r : graph.syncRequest(new ObjectsWithType(model.data, l0.ConsistsOf, L0.SCLModule))) { + result.add(new SCLModule(r)); + } + return result; + + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModulesLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModulesLabeler.java new file mode 100644 index 00000000..b2910177 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModulesLabeler.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.SCLModulesFolder; + +public class SCLModulesLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, SCLModulesFolder input) throws DatabaseException { + return "SCL Modules"; + } + + @Override + public int getCategory(ReadGraph graph, SCLModulesFolder input) throws DatabaseException { + return -2; + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionLibraries.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionLibraries.java new file mode 100644 index 00000000..7d5c736a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionLibraries.java @@ -0,0 +1,36 @@ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder; + +public class SharedFunctionLibraries extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, + SharedFunctionsFolder sharedFunctionsFolder) throws DatabaseException { + + ArrayList> result = new ArrayList>(); + + + for(Resource sharedLibrary : graph.syncRequest(new ObjectsWithType( + sharedFunctionsFolder.data, + Layer0.getInstance(graph).IsLinkedTo, + SysdynResource.getInstance(graph).SharedFunctionOntology))) + { + result.add(new SharedFunctionLibraryNode(sharedLibrary)); + } + + return result; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionsLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionsLabeler.java new file mode 100644 index 00000000..c1c8c0a8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionsLabeler.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder; + +public class SharedFunctionsLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, SharedFunctionsFolder input) throws DatabaseException { + return "Shared Functions"; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SheetLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SheetLabeler.java new file mode 100644 index 00000000..ff4bd59f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SheetLabeler.java @@ -0,0 +1,15 @@ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.browser.nodes.SheetNode; + +public class SheetLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, SheetNode sheet) throws DatabaseException { + return graph.getPossibleRelatedValue(sheet.data, Layer0.getInstance(graph).HasName); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResult.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResult.java new file mode 100644 index 00000000..f7bd86f0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResult.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode; +import org.simantics.sysdyn.ui.browser.nodes.HistoryDataNode; +import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode; +import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode; + +public class SimulationResult extends ViewpointContributor> { + + @Override + public Collection getContribution(ReadGraph graph, AbstractNode node) throws DatabaseException { + ArrayList> result = new ArrayList>(); + SysdynResource sr = SysdynResource.getInstance(graph); + if (!(node instanceof ExperimentNode || node instanceof SimulationResultSetNode)) + return result; + for(final Resource r : graph.syncRequest(new ObjectsWithType(node.data, sr.Experiment_result, sr.Result))) { + if(graph.isInstanceOf(r, sr.HistoryDataset)) { + result.add(new HistoryDataNode(r)); + } else { + result.add(new SimulationResultNode(r)); + + String resultPath = (String)graph.getPossibleRelatedValue(r, sr.Result_resultFile); + File file = new File(resultPath); + if(!file.exists()) { + graph.asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + String resultPath = (String)graph.getPossibleRelatedValue(r, SysdynResource.getInstance(graph).Result_resultFile); + File file = new File(resultPath); + if(!file.exists()) { + Layer0 l0 = Layer0.getInstance(graph); + graph.deny(r, l0.PartOf); + graph.deny(r, graph.getInverse(SysdynResource.getInstance(graph).Experiment_result)); + } + } + }); + } + } + } + return result; + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultDecorator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultDecorator.java new file mode 100644 index 00000000..3676eba1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultDecorator.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.swt.SWT; +import org.simantics.browsing.ui.content.LabelDecorator; +import org.simantics.browsing.ui.graph.contributor.labeler.LabelDecoratorContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode; + +public class SimulationResultDecorator extends LabelDecoratorContributor>{ + + @Override + public LabelDecorator getDecorator(ReadGraph graph, SimulationResultNode result) throws DatabaseException { + if (graph.hasStatement(result.data, SysdynResource.getInstance(graph).Result_showResult)) { + return new LabelDecorator.Stub() { + + @SuppressWarnings("unchecked") + @Override + public F decorateFont(F font, String column, int itemIndex) { + return (F) ((FontDescriptor) font).withStyle(SWT.BOLD); + } + }; + } + return new LabelDecorator.Stub() { + + @SuppressWarnings("unchecked") + @Override + public F decorateFont(F font, String column, int itemIndex) { + return (F) ((FontDescriptor) font).withStyle(SWT.NORMAL); + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultImager.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultImager.java new file mode 100644 index 00000000..3dc688d5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultImager.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.swt.ImagerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode; + +public class SimulationResultImager extends ImagerContributor>{ + + @Override + public ImageDescriptor getDescriptor(ReadGraph graph, SimulationResultNode result) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.isInstanceOf(result.data, sr.HistoryDataset)) + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/table.png")); + if(graph.hasStatement(result.data, sr.Result_showResult)) + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar.png")); + else + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar_blackAndWhite.png")); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultLabeler.java new file mode 100644 index 00000000..f0e968ed --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultLabeler.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode; + +public class SimulationResultLabeler extends LabelerContributor>{ + + @Override + public String getLabel(ReadGraph graph, SimulationResultNode result) throws DatabaseException { + String name = graph.getPossibleRelatedValue(result.data, Layer0.getInstance(graph).HasLabel); + return name == null ? "Experiment (no name)" : name; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSet.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSet.java new file mode 100644 index 00000000..dfbe8811 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSet.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode; +import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode; + +public class SimulationResultSet extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, ExperimentNode experiment) throws DatabaseException { + ArrayList results = new ArrayList(); + SysdynResource sr = SysdynResource.getInstance(graph); + for(final Resource r : graph.syncRequest(new ObjectsWithType(experiment.data, sr.Experiment_resultSet, sr.ResultSet))) { + results.add(new SimulationResultSetNode(r)); + } + return results; + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetDecorator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetDecorator.java new file mode 100644 index 00000000..2491ee51 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetDecorator.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.swt.SWT; +import org.simantics.browsing.ui.content.LabelDecorator; +import org.simantics.browsing.ui.graph.contributor.labeler.LabelDecoratorContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode; + +public class SimulationResultSetDecorator extends LabelDecoratorContributor{ + + @Override + public LabelDecorator getDecorator(ReadGraph graph, SimulationResultSetNode resultSet) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for (Resource result : graph.getObjects(resultSet.data, sr.Experiment_result)) { + if (graph.hasStatement(result, sr.Result_showResult)) { + return new LabelDecorator.Stub() { + + @SuppressWarnings("unchecked") + @Override + public F decorateFont(F font, String column, int itemIndex) { + return (F) ((FontDescriptor) font).withStyle(SWT.BOLD); + } + }; + } + } + return new LabelDecorator.Stub() { + + @SuppressWarnings("unchecked") + @Override + public F decorateFont(F font, String column, int itemIndex) { + return (F) ((FontDescriptor) font).withStyle(SWT.NORMAL); + } + }; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetImager.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetImager.java new file mode 100644 index 00000000..88c73806 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetImager.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.swt.ImagerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode; + +public class SimulationResultSetImager extends ImagerContributor{ + + @Override + public ImageDescriptor getDescriptor(ReadGraph graph, SimulationResultSetNode resultSet) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for (Resource result : graph.getObjects(resultSet.data, sr.Experiment_result)) { + if (graph.hasStatement(result, sr.Result_showResult)) { + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar_3.png")); + } + } + return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar_3_blackAndWhite.png")); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetLabeler.java new file mode 100644 index 00000000..16c42593 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetLabeler.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode; + +public class SimulationResultSetLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, SimulationResultSetNode resultSet) throws DatabaseException { + String name = graph.getPossibleRelatedValue(resultSet.data, Layer0.getInstance(graph).HasLabel); + return name == null ? "Experiment (no name)" : name; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SysdynProject.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SysdynProject.java new file mode 100644 index 00000000..91c46b6a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SysdynProject.java @@ -0,0 +1,39 @@ +package org.simantics.sysdyn.ui.browser.contributions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.structural.ui.modelBrowser.nodes.AbstractNode; +import org.simantics.sysdyn.SysdynResource; + +public class SysdynProject extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, Resource project) + throws DatabaseException { + + ArrayList result = new ArrayList(); + Layer0 L0 = Layer0.getInstance(graph); + for(Resource r : graph.syncRequest(new ObjectsWithType(project, L0.ConsistsOf, SysdynResource.getInstance(graph).SysdynModel))) { + try { + result.add(graph.adapt(r, AbstractNode.class)); + } catch(DatabaseException e) { + e.printStackTrace(); + } + } + return result; + + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/VariableLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/VariableLabeler.java new file mode 100644 index 00000000..6302ad0d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/VariableLabeler.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.contributions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.ui.browser.nodes.VariableNode; + +public class VariableLabeler extends LabelerContributor>{ + + @Override + public String getLabel(ReadGraph graph, VariableNode var) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + Resource varres = var.data; + StringBuilder sb = new StringBuilder(); + for(Resource r : graph.getObjects(varres, l0.HasName)) + sb.append(graph.getValue(r)); + if(graph.isInstanceOf(varres, L0X.Realization)) { + varres = graph.getPossibleObject(varres, L0X.Represents); + if(varres == null) return sb.toString(); + } + sb.append(" : "); + for(Resource t : graph.getObjects(varres, l0.InstanceOf)) + for(Resource r : graph.getObjects(t, l0.HasName)) + sb.append(graph.getValue(r)); + return sb.toString(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ChartImageRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ChartImageRule.java new file mode 100644 index 00000000..044d9bc0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ChartImageRule.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.imagerules; + +import java.util.Collections; +import java.util.Map; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.images.ImageRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.Activator; + +public class ChartImageRule implements ImageRule { + + @Override + public boolean isCompatible(Class contentType) { + return Resource.class.equals(contentType); + } + + @Override + public Map getImage(ReadGraph graph, Object content) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + String image = "icons/chart_line.png"; + + Resource chart = (Resource) content; + + Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.Plot)); + if(plot != null) { + if(graph.isInstanceOf(plot, jfree.CategoryPlot)) { + image = "icons/chart_bar.png"; + } else if(graph.isInstanceOf(plot, jfree.PiePlot)) { + image = "icons/chart_pie.png"; + } + } + + return Collections.singletonMap(ColumnKeys.SINGLE, + ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(image)) + ); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ResultImageRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ResultImageRule.java new file mode 100644 index 00000000..ed7024ed --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ResultImageRule.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.imagerules; + +import java.util.Collections; +import java.util.Map; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.images.ImageRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; + +public class ResultImageRule implements ImageRule { + + @Override + public boolean isCompatible(Class contentType) { + return Resource.class.equals(contentType); + } + + @Override + public Map getImage(ReadGraph graph, Object content) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource data = (Resource) content; + + String image = "icons/chart_bar_blackAndWhite.png"; + if(graph.hasStatement(data, sr.Result_showResult)) + image ="icons/chart_bar.png"; + + return Collections.singletonMap(ColumnKeys.SINGLE, + ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(image)) + ); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/VariableImageRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/VariableImageRule.java new file mode 100644 index 00000000..ba780a64 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/VariableImageRule.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.imagerules; + +import java.util.Collections; +import java.util.Map; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.images.ImageRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.utils.ui.AdaptionUtils; + +public class VariableImageRule implements ImageRule { + + @Override + public boolean isCompatible(Class contentType) { + return Variable.class.equals(contentType); + } + + @Override + public Map getImage(ReadGraph graph, Object content) throws DatabaseException { + Variable var = AdaptionUtils.adaptToSingle(content, Variable.class); + + String image = "icons/brick.png"; + + Resource r = (Resource)var.getPropertyValue(graph, Variables.REPRESENTS); + if(r != null) { + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Resource type = graph.getSingleObject(r, L0.InstanceOf); + if(graph.isInheritedFrom(type, sr.Module)) { + image = "icons/bricks.png"; + } + } + + return Collections.singletonMap(ColumnKeys.SINGLE, + ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(image)) + ); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/ModuleTypeLabelRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/ModuleTypeLabelRule.java new file mode 100644 index 00000000..90d72345 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/ModuleTypeLabelRule.java @@ -0,0 +1,32 @@ +package org.simantics.sysdyn.ui.browser.labelrules; + +import java.util.Collections; +import java.util.Map; + +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.labels.LabelRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.modeling.ModelingResources; + +public class ModuleTypeLabelRule implements LabelRule { + public static final ModuleTypeLabelRule INSTANCE = new ModuleTypeLabelRule(); + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Map getLabel(ReadGraph graph, Object content) throws DatabaseException { + Resource symbol = (Resource)content; + Resource component = graph.getSingleObject(symbol, ModelingResources.getInstance(graph).SymbolToComponentType); + + return Collections.singletonMap(ColumnKeys.SINGLE, + NameUtils.getSafeName(graph, component) + ); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/VariableNameLabelRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/VariableNameLabelRule.java new file mode 100644 index 00000000..8e97b427 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/VariableNameLabelRule.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.labelrules; + +import java.util.Collections; +import java.util.Map; + +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.labels.LabelRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.utils.ui.AdaptionUtils; + +public class VariableNameLabelRule implements LabelRule { + public static final ModuleTypeLabelRule INSTANCE = new ModuleTypeLabelRule(); + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Variable.class); + } + + @Override + public Map getLabel(ReadGraph graph, Object content) throws DatabaseException { + Variable var = AdaptionUtils.adaptToSingle(content, Variable.class); + return Collections.singletonMap(ColumnKeys.SINGLE, + var != null ? var.getName(graph) : "No variable" + ); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodeTypes/ModuleSymbolNodeType.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodeTypes/ModuleSymbolNodeType.java new file mode 100644 index 00000000..e4e8fde6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodeTypes/ModuleSymbolNodeType.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodeTypes; + +import java.util.Collection; +import java.util.Collections; +import java.util.WeakHashMap; + +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.common.NodeContextBuilder; +import org.simantics.browsing.ui.model.nodetypes.NodeType; +import org.simantics.browsing.ui.model.nodetypes.SpecialNodeType; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.ui.selection.WorkbenchSelectionElement; + +/** + * Experimental node type for Module symbols. Copied mostly from {@link SpecialNodeType}. + * Not necessary needed. + * + * @author Teemu Lempinen + * + */ +public class ModuleSymbolNodeType implements NodeType { + + private Resource resource; + private Class contentType; + + private static final WeakHashMap nodeTypeCache = + new WeakHashMap(); + + public ModuleSymbolNodeType(Resource resource) { + this.resource = resource; + this.contentType = Resource.class; + } + + public static ModuleSymbolNodeType create(Resource entityType) { + synchronized(nodeTypeCache) { + ModuleSymbolNodeType result = nodeTypeCache.get(entityType); + if(result == null) { + result = new ModuleSymbolNodeType(entityType); + nodeTypeCache.put(entityType, result); + } + return result; + } + } + + @Override + public NodeContext createNodeContext(ReadGraph graph, Object content) + throws DatabaseException { + if(contentType.isInstance(content)) + return NodeContextBuilder.buildWithData(KEY_SEQUENCE, + new Object[] {content, this} + ); + else + return null; + } + + @Override + public Class getContentType() { + return contentType; + } + + @Override + public int hashCode() { + return resource.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ModuleSymbolNodeType other = (ModuleSymbolNodeType) obj; + return resource.equals(other.resource); + } + + @Override + public boolean inherits(ReadGraph graph, NodeType superType) { + // Special node type does not support inheritance + return equals(superType); + } + + @Override + public Collection getSuper(ReadGraph g) { + return Collections.emptyList(); + } + + @Override + public String toString(ReadGraph graph) throws DatabaseException { + return "(" + NameUtils.getSafeName(graph, resource) + ")"; + } + + @Override + public WorkbenchSelectionElement getWorkbenchSelectionElement(NodeContext context) { + return null; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AbstractChartNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AbstractChartNode.java new file mode 100644 index 00000000..61eb1850 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AbstractChartNode.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import java.util.Iterator; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IDropTargetNode; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.CancelTransactionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ExceptionUtils; + +public abstract class AbstractChartNode extends AbstractNode implements IDropTargetNode, IDeletableNode { + + public AbstractChartNode(Resource data) { + super(data); + } + + + /** + * Add variable to this chart, if the dropped element(s) can be adapted to a {@link Variable} + */ + @Override + public void drop(Object data) { + IStructuredSelection selection = (IStructuredSelection)data; + Iterator iterator = selection.iterator(); + while(iterator.hasNext()) { + Object o = iterator.next(); + if(o instanceof IAdaptable) { + Variable v = (Variable) ((IAdaptable)o).getAdapter(Variable.class); + if(v != null) { + addVariableToChart(v); + } + } + } + } + + + /** + * Adds a variable to this chart and map it to the first rangeAxis + * @param variable + */ + protected abstract void addVariableToChart(final Variable variable); + + @Override + public void delete() throws DeleteException { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException { + RemoverUtil.remove(graph, data); + } + }); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BarChartNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BarChartNode.java new file mode 100644 index 00000000..9dff79b6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BarChartNode.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.SingleObjectWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; + +/** + * Bar chart node + * @author Teemu Lempinen + * + */ +public class BarChartNode extends AbstractChartNode { + + public BarChartNode(Resource data) { + super(data); + } + + + /** + * Adds a variable to this chart + * @param variable + */ + @Override + protected void addVariableToChart(final Variable variable) { + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + Resource plot = graph.syncRequest(new SingleObjectWithType(data, l0.ConsistsOf, jfree.Plot)); + if(plot == null) + return; + + Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + + if(dataset == null) + return; + + // Create the series and attach it to the dataset + String rvi = Variables.getRVI(graph, variable); + ChartUtils.createSeries(graph, dataset, rvi); + } + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BookNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BookNode.java new file mode 100644 index 00000000..02f5bc51 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BookNode.java @@ -0,0 +1,11 @@ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; + +public class BookNode extends AbstractNode { + + public BookNode(Resource data) { + super(data); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartsFolder.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartsFolder.java new file mode 100644 index 00000000..d75b01ba --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartsFolder.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; + +/** + * Folder containing all sysdyn charts + * @author Teemu Lempinen + * + */ +public class ChartsFolder extends AbstractNode { + + public ChartsFolder(Resource resource) { + super(resource); + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if(clazz == adapter) // There is no resource for this node.. + return null; + return super.getAdapter(adapter); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ConfigurationNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ConfigurationNode.java new file mode 100644 index 00000000..4b614428 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ConfigurationNode.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.IDeletable; +import org.simantics.db.Resource; +import org.simantics.db.layer0.variable.Variable; + +public class ConfigurationNode extends VariableNode implements IDeletable { + + public ConfigurationNode(Resource resource) { + super(resource); + } + + public ConfigurationNode(Variable variable, Resource represents) { + super(variable, represents); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/EnumerationNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/EnumerationNode.java new file mode 100644 index 00000000..7d7ee9dc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/EnumerationNode.java @@ -0,0 +1,108 @@ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.CancelTransactionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.VariableNameValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ExceptionUtils; + +public class EnumerationNode extends VariableNode implements IModifiableNode, IDeletableNode { + + public EnumerationNode(Resource resource) { + super(resource); + } + + public EnumerationNode(Variable variable, Resource represents) { + super(variable, represents); + } + + @Override + public Modifier getModifier(String columnId) { + + final Session session = SimanticsUI.getSession(); + LabelModifier modifier = new LabelModifier(session, data, session.getService(Layer0.class).HasName) { + @Override + public String isValid(String label) { + if (!new VariableNameValidator().isValid(data, label)) + return "Not valid"; + else + return null; + } + + @Override + public void modify(final String label) { + try { + session.syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) + throws DatabaseException { + + String originalName = graph.getRelatedValue(data, Layer0.getInstance(graph).HasName); + if(!originalName.equals(label)) { + Resource configuration = graph.getPossibleObject(data, Layer0.getInstance(graph).PartOf); + new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, label); + graph.claimLiteral(data, Layer0.getInstance(graph).HasName, label); + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + super.modify(label); + } + }; + return modifier; + } + + @Override + public void delete() throws DeleteException { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException { + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource redeclaration : graph.getObjects(data, sr.Redeclaration_replacedEnumeration_Inverse)) { + graph.deny(redeclaration, sr.Module_redeclaration_Inverse); + } + + for(Resource redeclaration : graph.getObjects(data, sr.Redeclaration_replacingEnumeration_Inverse)) { + graph.deny(redeclaration, sr.Module_redeclaration_Inverse); + } + + Layer0 L0 = Layer0.getInstance(graph); + Resource conf = graph.getPossibleObject(data, L0.PartOf); + for(Resource var : graph.syncRequest(new ObjectsWithType(conf, L0.ConsistsOf, sr.Variable))) { + Resource arrayIndexes = graph.getPossibleObject(var, sr.Variable_arrayIndexesList); + if(arrayIndexes != null) { + if(ListUtils.getNode(graph, arrayIndexes, data) != null) { + ListUtils.removeElement(graph, arrayIndexes, data); + } + } + } + + RemoverUtil.remove(graph, data); + + } + }); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentNode.java new file mode 100644 index 00000000..deeb8dd7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentNode.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IDoubleClickableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.CancelTransactionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.project.IProject; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.handlers.SysdynExperimentActivator; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.ExceptionUtils; + +public class ExperimentNode extends AbstractNode implements IDoubleClickableNode, IDeletableNode, IModifiableNode{ + + public ExperimentNode(Resource resource) { + super(resource); + } + + @Override + public boolean handleDoubleClick() { + if (data == null) + return false; + IProject project = SimanticsUI.getProject(); + IExperimentManager experimentManager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + if (experimentManager == null) { + ErrorLogger.defaultLogWarning("Experiment manager not available.", new Exception()); + return false; + } + SysdynExperimentActivator.scheduleActivation(SimanticsUI.getSession(), project, experimentManager, data); + return true; + } + + @Override + public Modifier getModifier(String columnId) { + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data) { + @Override + public String isValid(String label) { + if (label.isEmpty()) + return "Empty label not allowed"; + return null; + } + }; + return modifier; + } + + @Override + public void delete() throws DeleteException { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException { + Collection results = graph.getObjects(data, SysdynResource.getInstance(graph).Experiment_result); + if(results != null) + for(Resource result : results) + SimulationResultNode.unlinkResult(graph, result); + Collection resultSets = graph.getObjects(data, SysdynResource.getInstance(graph).Experiment_resultSet); + if(resultSets != null) + for(Resource resultSet : resultSets) + SimulationResultSetNode.unlinkResultSet(graph, resultSet); + RemoverUtil.remove(graph, data); + } + }); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentsFolder.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentsFolder.java new file mode 100644 index 00000000..76be910d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentsFolder.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; + +public class ExperimentsFolder extends AbstractNode { + + public ExperimentsFolder(Resource resource) { + super(resource); + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if(clazz == adapter) // There is no resource for this node.. + return null; + return super.getAdapter(adapter); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExportTester.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExportTester.java new file mode 100644 index 00000000..dad1cd44 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExportTester.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ + +package org.simantics.sysdyn.ui.browser.nodes; + +import java.util.Collection; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.simantics.DatabaseJob; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.db.request.Read; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * This class tests whether the export functionality is active + * + * @author Tuomas Miettinen + * @author Tuukka Lehtonen + */ +public class ExportTester extends PropertyTester { + + @Override + public boolean test(Object receiver, final String property, final Object[] args, final Object expectedValue) { + // Find the resource from the receiver. + Resource inputResource = ResourceAdaptionUtils.toSingleResource(receiver); + if (inputResource == null) { + @SuppressWarnings("rawtypes") + Collection a = AdaptionUtils.adaptToCollection(receiver, AbstractNode.class); + if (a.size() > 1) // Multiple selections. + return false; + if (a.size() == 1) + inputResource = (Resource)a.iterator().next().data; + } + if (inputResource == null) { + + IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor(); + IEditorPart editor = page.getActiveEditor(); + if (editor instanceof DiagramEditor) { + inputResource = ((DiagramEditor)editor).getInputResource(); + } else { + return false; + } + } + final Resource resource = inputResource; + + Session session = SimanticsUI.peekSession(); + if (session == null) + return false; + + if (DatabaseJob.inProgress()) + return false; + + // Check if we can get the model of the resource. + try { + return session.syncRequest(new Read() { + @Override + public Boolean perform(ReadGraph g) throws DatabaseException { + if (g.sync(new PossibleModel(resource)) != null) { + return true; + } + return false; + } + }); + } catch (DatabaseException e) { + // Purposefully not logging these exceptions, there might be way too + // many even under normal circumstances. + // TODO: add debug tracing options controlling the printing of these exceptions + return false; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionLibraryNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionLibraryNode.java new file mode 100644 index 00000000..00a3dcb5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionLibraryNode.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IDropTargetNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.FunctionLibraryNameValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +public class FunctionLibraryNode extends AbstractNode implements IDeletableNode, IModifiableNode, IDropTargetNode { + + + public FunctionLibraryNode(Resource resource) { + super(resource); + } + + @Override + public Modifier getModifier(String columnId) { + try { + Resource hasName = Layer0.getInstance(SimanticsUI.getSession()).HasName; + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data, hasName) { + @Override + public String isValid(String label) { + if (!new FunctionLibraryNameValidator().isValid(data, label)) + return "Not valid"; + else + return null; + } + }; + return modifier; + } catch (DatabaseException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void delete() throws DeleteException { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + RemoverUtil.remove(graph, data); + } + }); + } + + @Override + public void drop(Object data) { + final Resource[] resources = ResourceAdaptionUtils.toResources(data); + final Resource library = this.data; + if(resources.length > 0) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + for(Resource tobeMoved : resources) { + if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) || + graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) { + graph.deny(tobeMoved, l0.PartOf); + graph.claim(tobeMoved, l0.PartOf, library); + } + } + } + }); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionNode.java new file mode 100644 index 00000000..21312513 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionNode.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IDropTargetNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.FunctionNameValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +public class FunctionNode extends VariableNode implements IDeletableNode, IModifiableNode, IDropTargetNode { + + public FunctionNode(final Resource resource) { + super(resource); + } + + @Override + public Modifier getModifier(String columnId) { + try { + Resource hasName = Layer0.getInstance(SimanticsUI.getSession()).HasName; + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data, hasName) { + @Override + public String isValid(String label) { + if (!new FunctionNameValidator().isValid(data, label)) + return "Not valid"; + else + return null; + } + }; + return modifier; + } catch (DatabaseException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void delete() throws DeleteException { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + RemoverUtil.remove(graph, data); + } + }); + } + + @Override + public void drop(Object data) { + final Resource[] resources = ResourceAdaptionUtils.toResources(data); + final Resource thisFunction = this.data; + + if(resources.length > 0) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource library = null; + for(Resource tobeMoved : resources) { + if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) || + graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) { + if(library == null) { + library = graph.getSingleObject(thisFunction, l0.PartOf); + } + graph.deny(tobeMoved, l0.PartOf); + graph.claim(tobeMoved, l0.PartOf, library); + } + } + } + }); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionsFolder.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionsFolder.java new file mode 100644 index 00000000..5e4f8748 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionsFolder.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.IDropTargetNode; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +public class FunctionsFolder extends AbstractNode implements IDropTargetNode{ + + public FunctionsFolder(Resource resource) { + super(resource); + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if(clazz == adapter) // There is no resource for this node.. + return null; + return super.getAdapter(adapter); + } + + @Override + public void drop(Object data) { + final Resource[] resources = ResourceAdaptionUtils.toResources(data); + final Resource library = this.data; + if(resources.length > 0) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + for(Resource tobeMoved : resources) { + if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) || + graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) { + graph.deny(tobeMoved, l0.PartOf); + graph.claim(tobeMoved, l0.PartOf, library); + } + } + } + }); + } + } + + + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/HistoryDataNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/HistoryDataNode.java new file mode 100644 index 00000000..196a52ef --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/HistoryDataNode.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.CancelTransactionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ExceptionUtils; + +public class HistoryDataNode extends SimulationResultNode { + + public HistoryDataNode(Resource resource) { + super(resource); + } + + @Override + public void delete() throws DeleteException { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException { + RemoverUtil.remove(graph, data); + } + }); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InputNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InputNode.java new file mode 100644 index 00000000..ca731e92 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InputNode.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.db.Resource; +import org.simantics.db.layer0.variable.Variable; + +public class InputNode extends VariableNode { + + public InputNode(Resource resource) { + super(resource); + } + + public InputNode(Variable variable, Resource represents) { + super(variable, represents); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/LineChartNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/LineChartNode.java new file mode 100644 index 00000000..ef2ec492 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/LineChartNode.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.SingleObjectWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; + +/** + * Node representing a line chart + * @author Teemu Lempinen + * + */ +public class LineChartNode extends AbstractChartNode { + + public LineChartNode(Resource data) { + super(data); + } + + /** + * Adds a variable to this chart and map it to the first rangeAxis + * @param variable + */ + @Override + protected void addVariableToChart(final Variable variable) { + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + Resource plot = graph.syncRequest(new SingleObjectWithType(data, l0.ConsistsOf, jfree.Plot)); + if(plot == null) + return; + + Resource rangeAxis = null; + Resource dataset = null; + Resource rangeAxisList = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList); + if(rangeAxisList == null || ListUtils.toList(graph, rangeAxisList).isEmpty()) { + // No range axis -> Create a new one + rangeAxis = ChartUtils.createNumberRangeAxis(graph, plot); + Resource domainAxis = graph.getPossibleObject(plot, jfree.Plot_domainAxis); + dataset = ChartUtils.createXYDataset(graph, plot, domainAxis, rangeAxis); + } else { + rangeAxis = ListUtils.toList(graph, rangeAxisList).get(0); + dataset = graph.getPossibleObject(rangeAxis, jfree.Dataset_mapToRangeAxis_Inverse); + } + + // Create the series and attach it to the dataset + String rvi = Variables.getRVI(graph, variable); + ChartUtils.createSeries(graph, dataset, rvi); + } + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModelNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModelNode.java new file mode 100644 index 00000000..eb7229b1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModelNode.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IDoubleClickableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.CancelTransactionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.db.request.Write; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.ModelNameValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ExceptionUtils; + +public class ModelNode extends AbstractNode implements IDoubleClickableNode, IDeletableNode, IModifiableNode { + + Listener configurationNameSynchronizer; + private boolean disposed = false; + + public ModelNode(Resource resource) { + super(resource); + + // Not the best solution for name sync + configurationNameSynchronizer = new Listener() { + + @Override + public void execute(final String result) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SimulationResource sim = SimulationResource.getInstance(graph); + Resource configuration = graph.getPossibleObject(data, sim.HasConfiguration); + graph.claimLiteral(configuration, l0.HasLabel, result); + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + }; + + SimanticsUI.getSession().asyncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + return graph.getPossibleRelatedValue(data, Layer0.getInstance(graph).HasLabel); + } + + }, configurationNameSynchronizer); + } + + @Override + public Modifier getModifier(String columnId) { + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data) { + @Override + public String isValid(String label) { + if (!new ModelNameValidator().isValid(data, label)) + return "Not valid"; + else + return null; + } + + @Override + protected Write getWriteRequest(final String label) { + return new WriteRequest() { + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + g.claimLiteral(data, l0.HasLabel, label); + String safeName = NameUtils.findFreshName(g, label, g.getSingleObject(data, l0.PartOf), l0.ConsistsOf, "%s%d"); + g.claimLiteral(data, l0.HasName, safeName); + } + }; + } + }; + return modifier; + } + + @Override + public void delete() throws DeleteException { + disposed = true; + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException { + Layer0 l0 = Layer0.getInstance(graph); + + for(Resource r : graph.getObjects(data, l0.ConsistsOf)) + if(graph.isInstanceOf(r, SysdynResource.getInstance(graph).Result)) + SimulationResultNode.deleteResultFiles(graph, r); + + RemoverUtil.remove(graph, data); + } + }); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + + } + + @Override + public boolean handleDoubleClick() { + return true; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleNode.java new file mode 100644 index 00000000..297124a0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleNode.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.PasteHandler; +import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.layer0.Layer0; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.ui.utils.VariableNameValidator; +import org.simantics.ui.SimanticsUI; + +public class ModuleNode extends ConfigurationNode implements IModifiableNode { + + Resource configuration; + + public ModuleNode(Resource resource) { + super(resource); + + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Resource type = graph.getPossibleObject(data, Layer0.getInstance(graph).InstanceOf); + configuration = graph.getPossibleObject(type, StructuralResource2.getInstance(graph).IsDefinedBy); + } + }); + } + + public ModuleNode(Variable variable, Resource represents) { + super(variable, represents); + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Resource type = graph.getPossibleObject(data, Layer0.getInstance(graph).InstanceOf); + configuration = graph.getPossibleObject(type, StructuralResource2.getInstance(graph).IsDefinedBy); + } + }); + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if(PasteHandler.class == adapter && configuration != null) + return new DefaultPasteHandler(configuration); + return super.getAdapter(adapter); + } + + @Override + public Modifier getModifier(String columnId) { + try { + final Session session = SimanticsUI.getSession(); + Resource hasName = Layer0.getInstance(session).HasName; + LabelModifier modifier = new LabelModifier(session, data, hasName) { + @Override + public String isValid(String label) { + if (!new VariableNameValidator().isValid(data, label)) + return "Not valid"; + else + return null; + } + + @Override + public void modify(final String label) { + try { + session.syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) + throws DatabaseException { + + String originalName = graph.getRelatedValue(data, Layer0.getInstance(graph).HasName); + if(!originalName.equals(label)) { + Resource configuration = graph.getPossibleObject(data, Layer0.getInstance(graph).PartOf); + new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, label); + graph.claimLiteral(data, Layer0.getInstance(graph).HasName, label); + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + super.modify(label); + } + }; + return modifier; + } catch (DatabaseException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleTypeNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleTypeNode.java new file mode 100644 index 00000000..6d773446 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleTypeNode.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import java.util.Collection; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.layer0.adapter.PasteHandler; +import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.issues.ontology.IssueResource; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.ui.utils.ModuleTypeNameValidator; +import org.simantics.ui.SimanticsUI; + +public class ModuleTypeNode extends AbstractNode implements IDeletableNode, IModifiableNode { + + + Listener configurationNameSynchronizer; + private boolean disposed = false; + private Resource configuration; + + public ModuleTypeNode(Resource resource) { + super(resource); + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + ModelingResources mr = ModelingResources.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + Resource type = graph.getPossibleObject(data, mr.SymbolToComponentType); + configuration = graph.getPossibleObject(type, sr2.IsDefinedBy); + } + }); + + // Not the best solution for name sync + configurationNameSynchronizer = new Listener() { + + @Override + public void execute(final String result) { + if(result == null) + return; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + if(configuration != null) + graph.claimLiteral(configuration, Layer0.getInstance(graph).HasLabel, result); + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + }; + + SimanticsUI.getSession().asyncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + Resource type = graph.getPossibleObject(data, mr.SymbolToComponentType); + return (String) (type != null ? graph.getRelatedValue(type, l0.HasName) : null); + } + + }, configurationNameSynchronizer); + + } + + @Override + public Modifier getModifier(String columnId) { + Modifier modifier = null; + try { + modifier = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Modifier perform(ReadGraph graph) throws ManyObjectsForFunctionalRelationException, ServiceException { + ModelingResources mr = ModelingResources.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource type = graph.getPossibleObject(data, mr.SymbolToComponentType); + + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), type, l0.HasName) { + @Override + public String isValid(String label) { + if (!new ModuleTypeNameValidator().isValid(data, label)) + return "Not valid"; + else + return null; + } + }; + + + return modifier; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + return modifier; + } + + @Override + public void delete() throws DeleteException { + disposed = true; + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException{ + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 st = StructuralResource2.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + + Resource type = graph.getPossibleObject(data, mr.SymbolToComponentType); + Resource model = graph.getSingleObject(type, l0.PartOf); + Resource modelConfiguration = graph.getSingleObject(model, SimulationResource.getInstance(graph).HasConfiguration); + if (!graph.syncRequest(new ObjectsWithType(modelConfiguration, l0.ConsistsOf, type)).isEmpty()) { + throw new ModuleDeleteException("The module is used at the model configuration"); + } + Collection moduleTypes = graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, st.ComponentType)); + for(Resource r : moduleTypes) { + Resource configuration = graph.getPossibleObject(r, st.IsDefinedBy); + if(configuration != null && !graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, type)).isEmpty()) { + throw new ModuleDeleteException("The module is used at another module: " + graph.getRelatedValue(r, l0.HasName)); + } + } + + IssueResource ISSUE = IssueResource.getInstance(graph); + // Remove issues + for(Resource issueSource : graph.syncRequest(new ObjectsWithType(type, l0.ConsistsOf, ISSUE.Sources_DependencyTracker))) { + for(Resource issue : graph.syncRequest(new ObjectsWithType(issueSource, ISSUE.IssueSource_Manages, ISSUE.Issue))) { + RemoverUtil.remove(graph, issue); + } + } + RemoverUtil.remove(graph, type); + } + }); + } catch (ModuleDeleteException e) { + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + MessageDialog dialog = new MessageDialog(shell, "Unable to delete", null, e.message, SWT.ERROR, + new String[] { "OK" }, 0); + dialog.create(); + dialog.open(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + private class ModuleDeleteException extends DatabaseException { + private static final long serialVersionUID = 4076002781765246919L; + String message; + + public ModuleDeleteException(String message) { + this.message = message; + } + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if(PasteHandler.class == adapter && configuration != null) + return new DefaultPasteHandler(configuration); + return super.getAdapter(adapter); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModulesNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModulesNode.java new file mode 100644 index 00000000..faf9faed --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModulesNode.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; + +public class ModulesNode extends AbstractNode { + + public ModulesNode(Resource resource) { + super(resource); + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if(clazz == adapter) // There is no resource for this node.. + return null; + return super.getAdapter(adapter); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/OperatingInterfacesFolder.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/OperatingInterfacesFolder.java new file mode 100644 index 00000000..ce152952 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/OperatingInterfacesFolder.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; + +public class OperatingInterfacesFolder extends AbstractNode { + + public OperatingInterfacesFolder(Resource resource) { + super(resource); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/PieChartNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/PieChartNode.java new file mode 100644 index 00000000..776cbdb0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/PieChartNode.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.SingleObjectWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; + +/** + * Node for pie charts + * @author Teemu Lempinen + * + */ +public class PieChartNode extends AbstractChartNode { + + public PieChartNode(Resource data) { + super(data); + } + + /** + * Adds a variable to this chart + * @param variable + */ + @Override + protected void addVariableToChart(final Variable variable) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + Resource plot = graph.syncRequest(new SingleObjectWithType(data, l0.ConsistsOf, jfree.Plot)); + if(plot == null) + return; + + Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset)); + + if(dataset == null) + return; + + // Create the series and attach it to the dataset + String rvi = Variables.getRVI(graph, variable); + Resource series = ChartUtils.createSeries(graph, dataset, rvi); + graph.claimLiteral(series, jfree.Series_exploded, false); + } + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModule.java new file mode 100644 index 00000000..0a102065 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModule.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; + +public class SCLModule extends AbstractNode { + + public SCLModule(Resource resource) { + super(resource); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModulesFolder.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModulesFolder.java new file mode 100644 index 00000000..9900d886 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModulesFolder.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; + +public class SCLModulesFolder extends AbstractNode { + + public SCLModulesFolder(Resource resource) { + super(resource); + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if(clazz == adapter) // There is no resource for this node.. + return null; + return super.getAdapter(adapter); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SensitivityChartNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SensitivityChartNode.java new file mode 100644 index 00000000..026330cf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SensitivityChartNode.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.db.Resource; +import org.simantics.db.layer0.variable.Variable; + +public class SensitivityChartNode extends AbstractChartNode { + + public SensitivityChartNode(Resource data) { + super(data); + } + + @Override + protected void addVariableToChart(Variable variable) { + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionLibraryNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionLibraryNode.java new file mode 100644 index 00000000..e2269eba --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionLibraryNode.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDropTargetNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.SharedFunctionLibraryNameValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +public class SharedFunctionLibraryNode extends FunctionLibraryNode implements IDropTargetNode { + + public SharedFunctionLibraryNode(Resource resource) { + super(resource); + } + + @Override + public void delete() throws DeleteException { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + + graph.deny(data, l0.PartOf); + graph.deny(data, l0.IsLinkedTo_Inverse); + + // TODO: remove file + } + }); + } + + @Override + public Modifier getModifier(String columnId) { + try { + Resource hasName = Layer0.getInstance(SimanticsUI.getSession()).HasName; + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data, hasName) { + @Override + public String isValid(String label) { + if (!new SharedFunctionLibraryNameValidator().isValid(data, label)) + return "Not valid"; + else + return null; + } + }; + return modifier; + } catch (DatabaseException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void drop(Object data) { + final Resource[] resources = ResourceAdaptionUtils.toResources(data); + final Resource library = this.data; + if(resources.length > 0) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + for(Resource tobeMoved : resources) { + if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) || + graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) { + graph.deny(tobeMoved, l0.PartOf); + graph.claim(tobeMoved, l0.PartOf, library); + } + } + + } + }); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionsFolder.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionsFolder.java new file mode 100644 index 00000000..0531fd92 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionsFolder.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; + +public class SharedFunctionsFolder extends AbstractNode { + + public SharedFunctionsFolder(Resource data) { + super(data); + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if(clazz == adapter) // There is no resource for this node.. + return null; + return super.getAdapter(adapter); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SheetNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SheetNode.java new file mode 100644 index 00000000..39fdb224 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SheetNode.java @@ -0,0 +1,83 @@ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.IDoubleClickableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.RVI; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.utils.SheetNameValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.workbench.ResourceEditorInput2; +import org.simantics.utils.ui.workbench.WorkbenchUtils; + +public class SheetNode extends AbstractNode implements IModifiableNode, IDoubleClickableNode { + + public SheetNode(Resource data) { + super(data); + } + + @Override + public Modifier getModifier(String columnId) { + + Session session = SimanticsUI.getSession(); + LabelModifier modifier = new LabelModifier(session, data, session.getService(Layer0.class).HasName) { + @Override + public String isValid(String label) { + if (!new SheetNameValidator().isValid(data, label)) + return "Not valid"; + else + return null; + } + }; + return modifier; + } + + @Override + public boolean handleDoubleClick() { + + try { + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + + Variable variable = graph.adapt(data, Variable.class); + final Resource model = Variables.getModel(graph, variable); + final RVI rvi = variable.getRVI(graph); + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + private static final String EDITOR_ID = "org.simantics.spreadsheet.ui.editor2"; + + @Override + public void run() { + try { + System.out.println("Activating sheet: model=" + model + " rvi=" + rvi); + WorkbenchUtils.openEditor(EDITOR_ID, new ResourceEditorInput2(EDITOR_ID, data, model, rvi)); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + }); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + + return true; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultNode.java new file mode 100644 index 00000000..bc9c4a3f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultNode.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import java.io.File; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IDoubleClickableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.CancelTransactionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.handlers.ToggleResultActivation; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ExceptionUtils; + +public class SimulationResultNode extends AbstractNode implements IDoubleClickableNode, IDeletableNode, IModifiableNode { + + public SimulationResultNode(Resource resource) { + super(resource); + } + + + @Override + public Modifier getModifier(String columnId) { + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data) { + @Override + public String isValid(String label) { + if (label.isEmpty()) + return "Empty label not allowed"; + return null; + } + }; + return modifier; + } + + + @Override + public void delete() throws DeleteException { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException { + unlinkResult(graph, data); + } + }); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + + } + + + public static void unlinkResult(WriteGraph graph, Resource result) throws DatabaseException { + deleteResultFiles(graph, result); + RemoverUtil.remove(graph, result); + } + + public static void deleteResultFiles(WriteGraph graph, Resource result) throws DatabaseException { + String path; + path = graph.getPossibleRelatedValue(result, SysdynResource.getInstance(graph).Result_resultFile); + if(path != null) { + File file = new File(path); + file.delete(); + File parent = file.getParentFile(); + if(parent.listFiles() != null && parent.listFiles().length == 0) + parent.delete(); + } + } + + + @Override + public boolean handleDoubleClick() { + Resource[] resources = {data}; + ToggleResultActivation.toggleActivation(resources); + return true; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultSetNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultSetNode.java new file mode 100644 index 00000000..194e1c9e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultSetNode.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IDoubleClickableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.CancelTransactionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.handlers.ToggleResultSetActivation; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ExceptionUtils; + +public class SimulationResultSetNode extends AbstractNode implements IDoubleClickableNode, IDeletableNode, IModifiableNode { + + public SimulationResultSetNode(Resource resource) { + super(resource); + } + + + @Override + public Modifier getModifier(String columnId) { + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data) { + @Override + public String isValid(String label) { + if (label.isEmpty()) + return "Empty label not allowed"; + return null; + } + }; + return modifier; + } + + + @Override + public void delete() throws DeleteException { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException { + unlinkResultSet(graph, data); + } + }); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + + } + + + public static void unlinkResultSet(WriteGraph graph, Resource resultSet) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for (Resource result : graph.syncRequest(new ObjectsWithType(resultSet, sr.Experiment_result, sr.Result))) { + SimulationResultNode.unlinkResult(graph, result); + } + RemoverUtil.remove(graph, resultSet); + } + + @Override + public boolean handleDoubleClick() { + Resource[] resources = {data}; + ToggleResultSetActivation.toggleActivation(resources); + return true; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SymbolNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SymbolNode.java new file mode 100644 index 00000000..43456151 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SymbolNode.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.IDeletable; +import org.simantics.db.Resource; + +public class SymbolNode extends AbstractNode implements IDeletable { + + public SymbolNode(Resource resource) { + super(resource); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/VariableNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/VariableNode.java new file mode 100644 index 00000000..fdfcb134 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/VariableNode.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.browser.nodes; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.utils.VariableNameValidator; +import org.simantics.ui.SimanticsUI; + +public class VariableNode extends AbstractNode implements IModifiableNode { + + Variable variable; + + public VariableNode(Resource resource) { + super(resource); + } + + public VariableNode(Variable variable, Resource represents) { + super(represents); + this.variable = variable; + } + + public Variable getVariable() { + return variable; + } + + @Override + public Modifier getModifier(String columnId) { + try { + final Session session = SimanticsUI.getSession(); + Resource hasName = Layer0.getInstance(session).HasName; + LabelModifier modifier = new LabelModifier(session, data, hasName) { + @Override + public String isValid(String label) { + if (!new VariableNameValidator().isValid(data, label)) + return "Not valid"; + else + return null; + } + + @Override + public void modify(final String label) { + try { + session.syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) + throws DatabaseException { + + String originalName = graph.getRelatedValue(data, Layer0.getInstance(graph).HasName); + if(!originalName.equals(label)) { + Resource configuration = graph.getPossibleObject(data, Layer0.getInstance(graph).PartOf); + new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, label); + graph.claimLiteral(data, Layer0.getInstance(graph).HasName, label); + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + super.modify(label); + } + }; + return modifier; + } catch (DatabaseException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java new file mode 100644 index 00000000..240874fe --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.utils.binaryPredicates.InversePredicate; +import org.simantics.layer0.utils.binaryPredicates.OrderedSetElementsPredicate; +import org.simantics.mapping.constraint.instructions.IInstruction; +import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction; +import org.simantics.mapping.rule.instructions.IRuleInstruction; +import org.simantics.sysdyn.SysdynResource; + +public class DiagramToCompositeMapping3 extends org.simantics.modeling.mapping.DiagramToCompositeMapping3 { + + private SysdynResource sdr; + + public DiagramToCompositeMapping3(ReadGraph g, Resource mapping) + throws DatabaseException { + super(g, mapping); + } + + @Override + protected void setup(ReadGraph graph) { + sdr = SysdynResource.getInstance(graph); + } + + @Override + protected Resource getConfigurationConnectionType() { + return sdr.DependencyConnection; + } + + @Override + public CreationInstruction componentCreationInstruction(int component, int componentType, int configuration) { + return new SysdynCreationInstruction(project, configurationRoot, component, componentType, configuration); + } + + @Override + protected IRuleInstruction additiveRule() { + return + + if_(bf(OrderedSetElementsPredicate.INSTANCE, Diagram, Element), + query( + if_(and(bf(L0.InstanceOf, Element, ElementType), + bf(MOD.SymbolToComponentType, ElementType, ComponentType) + ), + // If element type of the element has a corresponding component type + createComponentRule(), + + if_(and(b(DIA.Connection, Element), bf(L0.InstanceOf, Element, ElementType), bf(MOD.DiagramConnectionTypeToConnectionType, ElementType, ComponentType)), + createNormalConnectionRule(), + + if_(b(DIA.Flag, Element), + createFlagRule() + ) + ) + ) + ) + ); + } + + @Override + protected IRuleInstruction destructiveRule() { + return + if_(and(bf(L0.ConsistsOf, Configuration, Component), + b(mapped, Component) // handle only mapped components + ), + query( + if_(and(bf(MOD.ComponentToElement, Component, Element), + bf(new InversePredicate(OrderedSetElementsPredicate.INSTANCE), Element, Diagram) + ), + // If component has a corresponding element in the diagram + if_(and(statement_bff(Component, ConnectionRelation, Connection, STR.IsConnectedTo), + b(mapped, Connection) + ), + // If component has a mapped connection + unless( + bf(MOD.ConnectionToDiagramConnection, Connection, DiagramConnectionRelation), + // If the configuration connection does not have a correspondence in the diagram remove it + and(deny(exists(Connection))) + ) + ), + + unless( + bf(MOD.ConnectionToDiagramConnection, Component, Element), + // If the configuration connection does not have a correspondence in the diagram remove it + and(deny(exists(Component))) + ) + + ) + ) + ); + } + + @Override + protected IInstruction claimBasicConnection() { + return and(exists( + bf(MOD.DiagramConnectionToConnection, Element, Connection), + Connection + ), + bb(L0.InstanceOf, Connection, ComponentType), + bb(L0.PartOf, Connection, Configuration), + b(mapped, Connection) + + ); + } + +// @Override +// protected IInstruction claimBasicConnection() { +// return and(exists( +// bf(MOD.DiagramConnectionToConnection, Element, Connection), +// Connection +// ), +// bb(L0.InstanceOf, Connection, ComponentType), +// b(mapped, Connection), +// bb(L0.PartOf, Connection, Configuration) +// ); +// } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java new file mode 100644 index 00000000..4d1f39a4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor; + +import java.awt.dnd.DnDConstants; +import java.util.Collections; +import java.util.Set; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchPartSite; +import org.simantics.db.ReadGraph; +import org.simantics.db.Session; +import org.simantics.diagram.handler.DeleteHandler; +import org.simantics.diagram.synchronization.IModifiableSynchronizationContext; +import org.simantics.diagram.synchronization.SynchronizationHints; +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.impl.CanvasContext; +import org.simantics.g2d.connection.IConnectionAdvisor; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.participant.ElementPainter; +import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementClasses; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.IElementClassProvider; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.participant.GridPainter; +import org.simantics.g2d.participant.RulerPainter; +import org.simantics.jfreechart.chart.element.PopulateChartDropParticipant; +import org.simantics.modeling.mapping.ElementCopyAdvisor; +import org.simantics.modeling.mapping.MappedElementCopyAdvisor; +import org.simantics.modeling.ui.diagramEditor.handlers.LinkBrowsingHandler; +import org.simantics.structural2.modelingRules.IModelingRules; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.editor.participant.CreateVariablesShortcutParticipant; +import org.simantics.sysdyn.ui.editor.participant.SelectionUpdaterParticipant; +import org.simantics.sysdyn.ui.editor.participant.SysdynComponentCopyAdvisor; +import org.simantics.sysdyn.ui.editor.participant.SysdynElementClassProviders; +import org.simantics.sysdyn.ui.editor.participant.SysdynPopulateElementDropParticipant; +import org.simantics.sysdyn.ui.elements.CloudFactory; +import org.simantics.sysdyn.ui.elements.SysdynElementClasses; +import org.simantics.sysdyn.ui.elements.SysdynElementFactory; +import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses; +import org.simantics.sysdyn.ui.elements.connections.RouteFlowEdgeClass; +import org.simantics.sysdyn.ui.elements.connections.SysdynConnectionClass; +import org.simantics.sysdyn.ui.handlers.ExtendedCopyPasteHandler; +import org.simantics.sysdyn.ui.properties.SysdynPropertyPage; +import org.simantics.ui.workbench.IPropertyPage; +import org.simantics.utils.datastructures.hints.IHintContext; +import org.simantics.utils.threads.AWTThread; +import org.simantics.utils.threads.ThreadUtils; + +/** + * @author Tuukka Lehtonen + */ +public class DiagramViewer extends org.simantics.modeling.ui.diagramEditor.DiagramViewer { + + protected String getPopupId() { + return "#SysdynDiagramPopup"; + } + + @Override + public void createPartControl(Composite parent) { + super.createPartControl(parent); + } + + @Override + protected Set getPropertyPageContexts() { + return Collections.singleton(SysdynResource.URIs.Browser); + } + + @Override + protected IPropertyPage createPropertyPage(IWorkbenchPartSite site, Set contexts) { + return new SysdynPropertyPage(site, contexts); + } + + @Override + protected IElementClassProvider createElementClassProvider(ReadGraph graph) { + SysdynResource sr = SysdynResource.getInstance(graph); + ElementClass dependencyClass = SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.DependencyConnection)); + ElementClass flowClass = RouteFlowEdgeClass.FLOW_CLASS.newClassWith(new StaticObjectAdapter(sr.FlowConnection)); + return SysdynElementClassProviders.mappedProvider( + ElementClasses.CONNECTION, dependencyClass, + ElementClasses.FLAG, CloudFactory.createElementClass(sr.CloudSymbol, SysdynElementFactory.createTerminals(graph, sr.CloudSymbol)), + ConnectionClasses.FLOW, flowClass, + ConnectionClasses.DEPENDENCY, dependencyClass, + SysdynElementClasses.VALVE, CloudFactory.createElementClass(sr.ValveSymbol, SysdynElementFactory.createTerminals(graph, sr.ValveSymbol)) + ); + + + } + + @Override + public void initializeCanvasContext(CanvasContext ctx) { + super.initializeCanvasContext(ctx); + // GRID and RULER have to be set here. They cause deadlocks in Show Module if set in onCreated() + IHintContext h = ctx.getDefaultHintContext(); + h.setHint(GridPainter.KEY_GRID_ENABLED, Boolean.FALSE); + h.setHint(RulerPainter.KEY_RULER_ENABLED, Boolean.FALSE); + h.setHint(Hints.KEY_DISPLAY_MARGINS, Boolean.FALSE); + h.setHint(Hints.KEY_DISPLAY_PAGE, Boolean.FALSE); + } + + @Override + protected void onCreated() { + sourceDiagram.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.FALSE); + sourceDiagram.setHint(SynchronizationHints.COPY_ADVISOR, new MappedElementCopyAdvisor(new ElementCopyAdvisor(), new SysdynComponentCopyAdvisor())); + + ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() { + + @Override + public void run() { + if (isDisposed()) { + return; + } else { + if(canvasContext != null && sourceDiagram != null) { + ElementPainter ep = canvasContext.getSingleItem(ElementPainter.class); + for(IElement e : sourceDiagram.getElements()) { + if(e.getElementClass().getId().contains("Connection")){ + ep.update(e); + } + } + } + } + } + }); + } + + @Override + protected void addKeyBindingParticipants(CanvasContext ctx) { + ctx.add(new DeleteHandler(getEditorSite().getActionBars().getStatusLineManager())); + ctx.add(new CreateVariablesShortcutParticipant(synchronizer)); + ctx.add(new ExtendedCopyPasteHandler(getEditorSite().getActionBars().getStatusLineManager()).setWorkbenchSite(getEditorSite())); + } + + @Override + protected void initializeSynchronizationContext(ReadGraph graph, IModifiableSynchronizationContext context) { + super.initializeSynchronizationContext(graph, context); + + // Make sure SysdynResource is available. + SysdynResource.getInstance(graph); + } + + @Override + protected void addStructureParticipants(ICanvasContext ctx) { + addWorkbenchSelectionProvider(ctx); + + // Add visual browsing capabilities for structural models + + // Remove double click handler, because it is not working properly + // ctx.add(new StructuralBrowsingHandler(getSite(), sessionContext, getResourceInput2())); + ctx.add(new LinkBrowsingHandler(getSite(), this, sessionContext)); + + } + + protected void addDropParticipants(ICanvasContext ctx) { + ctx.getDefaultHintContext().setHint(Hints.KEY_ALLOWED_DRAG_ACTIONS, DnDConstants.ACTION_COPY); + + ctx.add(new SysdynPopulateElementDropParticipant(synchronizer)); + ctx.add(new PopulateChartDropParticipant(synchronizer)); + } + + @Override + protected void addOtherParticipants(CanvasContext ctx) { + ctx.add(new SelectionUpdaterParticipant()); + } + + @Override + protected PointerInteractor getPointerInteractor() { + return new org.simantics.sysdyn.ui.editor.participant.SysdynPointerInteractor(true, true, true, false, true, false, synchronizer.getElementClassProvider()); + } + + @Override + protected IConnectionAdvisor getConnectionAdvisor(IModelingRules modelingRules, Session session) { + return new SysdynConnectionAdvisor(modelingRules, sessionContext.getSession()); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromComponentAdapter.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromComponentAdapter.java new file mode 100644 index 00000000..fb89ccc3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromComponentAdapter.java @@ -0,0 +1,204 @@ +package org.simantics.sysdyn.ui.editor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.db.layer0.variable.RVI; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.diagram.content.ConnectionUtil; +import org.simantics.diagram.flag.FlagUtil; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ComponentUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.actions.NavigateToTarget; +import org.simantics.modeling.ui.Activator; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.threads.SWTThread; +import org.simantics.utils.threads.ThreadUtils; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * @author Tuukka Lehtonen + */ +public class OpenDiagramFromComponentAdapter extends AbstractResourceEditorAdapter { + + private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer"; + + public OpenDiagramFromComponentAdapter() { + super("Diagram Editor", Activator.COMPOSITE_ICON); + } + + @Override + public boolean canHandle(ReadGraph graph, Object input) throws DatabaseException { + Resource r = tryGetResource(graph, input); + if (r == null) + return false; + Variable v = AdaptionUtils.adaptToSingle(input, Variable.class); + Collection rs = tryFindDiagram(graph, r, v); + return !rs.isEmpty(); + } + + private Resource tryGetResource(ReadGraph graph, Object input) throws DatabaseException { + Resource r = ResourceAdaptionUtils.toSingleResource(input); + if (r == null) { + Variable v = AdaptionUtils.adaptToSingle(input, Variable.class); + r = findResource(graph, v); + } + return r; + } + + private Resource findResource(ReadGraph graph, Variable v) throws DatabaseException { + while (v != null) { + Resource r = v.getPossibleRepresents(graph); + if (r != null) + return r; + v = v.browsePossible(graph, "."); + } + return null; + } + + @Override + public void openEditor(final Object input) throws Exception { + final Display d = Display.getCurrent(); + if (d == null) + return; + + SimanticsUI.getSession().syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + Resource r = tryGetResource(graph, input); + if (r == null) + return; + + Variable v = AdaptionUtils.adaptToSingle(input, Variable.class); + + final Collection rs = tryFindDiagram(graph, r, v); + if (rs.isEmpty()) + return; + + SWTThread.getThreadAccess(d).asyncExec(new Runnable() { + @Override + public void run() { + for (Runnable runnable : rs) { + runnable.run(); + } + } + }); + } + }); + } + + private Collection tryFindDiagram(ReadGraph g, Resource module, Variable variable) throws DatabaseException { + try { + return findDiagram(g, module, variable); + } catch (DatabaseException e) { + return Collections.emptyList(); + } + } + + private Collection findDiagram(ReadGraph g, Resource module, Variable variable) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + SysdynResource SYSDYN = SysdynResource.getInstance(g); + + if (g.isInstanceOf(module, SYSDYN.IndependentVariable) || g.isInstanceOf(module, SYSDYN.Input) || g.isInstanceOf(module, SYSDYN.Module)) { + Collection result = new ArrayList(1); + + Variable moduleVariable = Variables.getVariable(g, module); + RVI rvi = moduleVariable.getRVI(g); + + Resource composite = g.getSingleObject(module, l0.PartOf); + Resource model = g.syncRequest(new PossibleModel(composite)); + + final Resource diagram = ComponentUtils.getCompositeDiagram(g, composite); + +// final ResourceArray compositePath = StructuralVariables.getCompositeArray(g, composite); +// final ResourceArray variablePath = compositePath.removeFromBeginning(1); +// +// Resource model = StructuralVariables.getModel(g, compositePath.head()); +// if (model == null) +// return Collections.emptyList(); +// +// String rvi = StructuralVariables.getRVI(g, variablePath); +// if (rvi == null) +// return Collections.emptyList(); + + if (variable != null) { + // Get proper RVI from variable if it exists. + Variable context = Variables.getPossibleContext(g, variable); + if (context != null) { + // We want the composite's RVI, not the component in it. + Variable parent = variable.getParent(g); + if (parent != null) { + rvi = parent.getRVI(g); +// String contextURI = context.getURI(g); +// String parentURI = parent.getURI(g); +// rvi = parentURI.replace(contextURI, ""); + model = Variables.getModel(g, context); + } + } + } + + final Collection selectedObjects = findElementObjects(g, module); + + result.add( + NavigateToTarget.editorActivator(EDITOR_ID, diagram, model, rvi, new Callback() { + @Override + public void run(IEditorPart part) { + final ICanvasContext openedCanvas = (ICanvasContext) part.getAdapter(ICanvasContext.class); + assert openedCanvas != null; + // CanvasContext-wide denial of initial zoom-to-fit on diagram open. + openedCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.FALSE); + ThreadUtils.asyncExec(openedCanvas.getThreadAccess(), + NavigateToTarget.elementSelectorZoomer(openedCanvas, selectedObjects, false)); + } + })); + return result; + } + + // Nothing to open + return Collections.emptyList(); + } + + public static Collection findElementObjects(ReadGraph g, Resource module) throws DatabaseException { + DiagramResource DIA = DiagramResource.getInstance(g); + ModelingResources MOD = ModelingResources.getInstance(g); + final Collection selectedObjects = new ArrayList(); + for (Resource element : g.getObjects(module, MOD.ComponentToElement)) { + if (g.isInstanceOf(element, DIA.Flag) && FlagUtil.isExternal(g, element)) { + // Use external flag primarily if one exists in the correspondences + selectedObjects.clear(); + selectedObjects.add(element); + break; + } else if (g.isInstanceOf(element, DIA.RouteGraphConnection)) { + selectedObjects.add(element); + } else if (g.isInstanceOf(element, DIA.Connection)) { + // Okay, we need to find a part of the connection + ConnectionUtil cu = new ConnectionUtil(g); + cu.gatherConnectionParts(element, selectedObjects); + } else { + selectedObjects.add(element); + } + } + for(Resource element : g.getObjects(module, MOD.HasParentComponent_Inverse)) { + selectedObjects.add(element); + } + return selectedObjects; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromConfigurationAdapter.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromConfigurationAdapter.java new file mode 100644 index 00000000..8fe5d1dd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromConfigurationAdapter.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor; + +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.ResourceArray; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.modeling.ComponentUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.ui.Activator; +import org.simantics.operation.Layer0X; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.structural2.StructuralVariables; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.workbench.ResourceEditorInput2; +import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter; +import org.simantics.utils.ui.workbench.WorkbenchUtils; + +public class OpenDiagramFromConfigurationAdapter extends AbstractResourceEditorAdapter { + + private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer"; + + public OpenDiagramFromConfigurationAdapter() { + super("Diagram Editor", Activator.COMPOSITE_ICON); + } + + protected String getEditorId() { + return EDITOR_ID; + } + + @Override + public boolean canHandle(ReadGraph g, Resource r) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + if(g.isInheritedFrom(r, sr.ModuleSymbol)) { + ModelingResources mr = ModelingResources.getInstance(g); + StructuralResource2 sr2 = StructuralResource2.getInstance(g); + Resource componentType = g.getSingleObject(r, mr.SymbolToComponentType); + r = g.getSingleObject(componentType, sr2.IsDefinedBy); + } + Layer0X L0X = Layer0X.getInstance(g); + Resource represents = g.getPossibleObject(r, L0X.Represents); + if(represents != null){ + if(g.isInstanceOf(represents, sr.Configuration)) { + r = represents; + } + } + return ComponentUtils.compositeHasDiagram(g, r) /*|| ComponentUtils.componentHasDiagram(g, r)*/; + } + + @Override + public void openEditor(final Resource r) throws Exception { + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph g) throws DatabaseException { + Resource cr = r; + Layer0X L0X = Layer0X.getInstance(g); + if(g.isInheritedFrom(r, SysdynResource.getInstance(g).ModuleSymbol)) { + ModelingResources mr = ModelingResources.getInstance(g); + StructuralResource2 sr2 = StructuralResource2.getInstance(g); + Resource componentType = g.getSingleObject(r, mr.SymbolToComponentType); + Resource configuration = g.getSingleObject(componentType, sr2.IsDefinedBy); + cr = configuration; + } else { + Resource represents = g.getPossibleObject(r, L0X.Represents); + if(represents != null && g.isInstanceOf(represents, SysdynResource.getInstance(g).Configuration)){ + cr = represents; + } else { + cr = r; + } + } + + + final Resource diagram = ComponentUtils.getPossibleCompositeDiagram(g, cr); + if(diagram == null) return; + final ResourceArray compositePath = StructuralVariables.getCompositeArray(g, cr); + final ResourceArray variablePath = compositePath.removeFromBeginning(1); + + final Resource model = StructuralVariables.getModel(g, compositePath.head()); + if(model == null) return; + + + + final String rvi = StructuralVariables.getRVI(g, variablePath); + if(rvi == null) return; + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + try { + String editorId = getEditorId(); +// System.out.println("Activating diagram: model=" + modelURI + " rvi='" + rvi + "'"); + WorkbenchUtils.openEditor(editorId, new ResourceEditorInput2(editorId, diagram, model, rvi)); + } catch (PartInitException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }); + + } + + }); + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynConnectionAdvisor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynConnectionAdvisor.java new file mode 100644 index 00000000..ffcfd38e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynConnectionAdvisor.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.diagram.content.ConnectionUtil; +import org.simantics.diagram.content.ResourceTerminal; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.g2d.connection.IConnectionAdvisor; +import org.simantics.g2d.diagram.handler.Topology.Terminal; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.structural2.modelingRules.CPIgnore; +import org.simantics.structural2.modelingRules.ConnectionJudgement; +import org.simantics.structural2.modelingRules.ConnectionJudgementType; +import org.simantics.structural2.modelingRules.IConnectionPoint; +import org.simantics.structural2.modelingRules.IModelingRules; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements.CloudFactory.CloudSceneGraph; + +public class SysdynConnectionAdvisor implements IConnectionAdvisor { + + IModelingRules modelingRules; + RequestProcessor processor; + + public SysdynConnectionAdvisor(IModelingRules modelingRules, + RequestProcessor processor) { + this.modelingRules = modelingRules; + this.processor = processor; + } + + IConnectionPoint getConnectionPoint(ReadGraph g, IElement element, Terminal term) throws DatabaseException { + Object obj = null; + if (element != null) + obj = ElementUtils.getObject(element); + + if (obj instanceof Resource) { + Resource elementResource = (Resource) obj; + return ConnectionUtil.toConnectionPoint(g, elementResource, term); + } + + // FIXME: this currently allows connections to begin from flags + // but is rather hackish. + if(element.getElementClass().containsClass(CloudSceneGraph.class)) { + return CPIgnore.NULL_INSTANCE; + } + + return null; + } + + @Override + public Object canBeConnected(Object backend, + final IElement element1, final Terminal term1, + final IElement element2, final Terminal term2) { + try { + if(backend == null) + backend = processor; + return ((RequestProcessor)backend).syncRequest(new Read() { + + @Override + public Object perform(ReadGraph g) throws DatabaseException { + if(element1 != null && term1 != null && element2 != null && term2 != null) { + StaticObjectAdapter soa = element1.getElementClass().getSingleItem(StaticObjectAdapter.class); + Resource startElementResource = soa.adapt(Resource.class); + Object r = ElementUtils.getObject(element2); + if(r == null || !(r instanceof Resource)) + return null; + Resource endElementResource = (Resource) r; + + DiagramResource dr = DiagramResource.getInstance(g); + Resource terminal2 = ((ResourceTerminal) term2).getResource(); + SysdynResource sr = SysdynResource.getInstance(g); + + + // Chech that end terminal has IsHeadOfTerminal relation + Resource connectionPoint = g.getPossibleObject(terminal2, dr.HasConnectionPoint); + if(connectionPoint == null || !g.isSubrelationOf(connectionPoint, sr.IsHeadOfTerminal)) { + return null; + } + + + // If end element is input symbol, allow only one connection and only from a module + if(g.isInstanceOf(endElementResource, sr.InputSymbol)) { + if(!g.isInheritedFrom(startElementResource, sr.ModuleSymbol)) return null; + if(g.getObjects(endElementResource, sr.IsHeadOfTerminal).size() > 0) return null; + } + + } + + ArrayList cps = new ArrayList(); + cps.add(getConnectionPoint(g, element1, term1)); + if(element2 != null) + cps.add(getConnectionPoint(g, element2, term2)); + ConnectionJudgement judgement = + modelingRules.judgeConnection(g, cps); + + if(judgement.type == ConnectionJudgementType.LEGAL) + return judgement; + else + return null; + } + + }); + } catch(DatabaseException e) { + e.printStackTrace(); + return null; + } + } + + @Override + public boolean canBeginConnection(Object backend, + final IElement element, final Terminal term) { + try { + if(backend == null) + backend = processor; + return ((RequestProcessor)backend).syncRequest(new Read() { + + @Override + public Boolean perform(ReadGraph g) throws DatabaseException { + return modelingRules.judgeConnection(g, + Arrays.asList(getConnectionPoint(g, element, term))) + .type != ConnectionJudgementType.ILLEGAL; + } + + }); + } catch(DatabaseException e) { + e.printStackTrace(); + return false; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynCreationInstruction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynCreationInstruction.java new file mode 100644 index 00000000..67721548 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynCreationInstruction.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor; + +import gnu.trove.TIntIntHashMap; + +import java.util.Collection; +import java.util.HashMap; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.common.utils.URIStringUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction; +import org.simantics.modeling.services.ComponentNamingUtil; +import org.simantics.modeling.services.NamingException; +import org.simantics.operation.Layer0X; +import org.simantics.project.IProject; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements.ShadowVariableReferenceDialogRunnable; +import org.simantics.utils.threads.SWTThread; + +public class SysdynCreationInstruction extends CreationInstruction { + + IProject project; + Resource configurationRoot; + int lComponentType; + int lConfiguration; + + public SysdynCreationInstruction(IProject project, Resource configurationRoot, int variableId, int componentType, + int configuration) { + super(variableId); + this.project = project; + this.configurationRoot = configurationRoot; + lComponentType = componentType; + lConfiguration = configuration; + } + + @Override + public Resource create(WriteGraph g, Object[] bindings) throws DatabaseException { + Resource componentType = (Resource) bindings[lComponentType]; + Resource configuration = (Resource) bindings[lConfiguration]; + + Layer0 l0 = Layer0.getInstance(g); + Layer0X L0X = Layer0X.getInstance(g); + + try { + + // Naming strategy + String proposition = URIStringUtils.escape(ComponentNamingUtil.findFreshInstanceName(g, project, configuration, configuration, componentType)); + Resource result = GraphUtils.create(g, + l0.HasName, proposition + ); + g.claim(result, L0X.Represents, result); + + // Add uninitialized tag. The tag is used to start name editing + SysdynResource SR = SysdynResource.getInstance(g); + g.claim(result, SR.IndependentVariable_isUninitialized, result); + + // Async reference dialog for shadow variables + if(SR.Shadow.equals(componentType)) { + Layer0 L0 = Layer0.getInstance(g); + Collection referrableVariables = g.syncRequest(new ObjectsWithType(configuration, L0.ConsistsOf, SR.IndependentVariable)); + referrableVariables.addAll( g.syncRequest(new ObjectsWithType(configuration, L0.ConsistsOf, SR.Input))); + HashMap names = new HashMap(); + for(Resource var : referrableVariables) { + String name = NameUtils.getSafeName(g, var); + names.put(name, var); + } + SWTThread.getThreadAccess().asyncExec(new ShadowVariableReferenceDialogRunnable(result, names)); + } + + return result; + } catch (NamingException e1) { + throw new DatabaseException(e1); + } + } + + @Override + public void mapVariables(TIntIntHashMap map) { + super.mapVariables(map); + lComponentType = map.get(lComponentType); + lConfiguration = map.get(lConfiguration); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorInput.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorInput.java new file mode 100644 index 00000000..7e317c6b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorInput.java @@ -0,0 +1,387 @@ +package org.simantics.sysdyn.ui.editor; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistableElement; +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.ResourceArray; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.AdaptionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.service.LifecycleSupport; +import org.simantics.db.service.SerialisationSupport; +import org.simantics.operation.Layer0X; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.icons.ImageDescriptorProvider; +import org.simantics.ui.workbench.ResourceEditorInput2; +import org.simantics.ui.workbench.ResourceEditorInputFactory2; +import org.simantics.ui.workbench.TitleRequest; +import org.simantics.ui.workbench.ToolTipRequest; +import org.simantics.utils.ObjectUtils; +import org.simantics.utils.datastructures.cache.ProvisionException; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.workbench.StringMemento; + +/** + * TEMPORARY fix to support sysdyn + * + * @author tlteemu + * + */ +public class SysdynEditorInput extends ResourceEditorInput2 { + + private final static boolean DEBUG_UPDATE = false; + + private static final String NO_NAME = "(no name)"; + + private final String editorID; + + private String randomAccessResourceId; + + private transient Resource resource; + + /** + * Gotten from the editor that needs to initialize this input. Currently + * needed for two things: {@link #exists()} and {@link #saveState(IMemento)}. + */ + private transient Session session; + + private transient boolean exists; + + private transient String name; + + private transient String tooltip; + + private transient ImageDescriptor imageDesc; + + /** Persistent memento for external data */ + private final StringMemento persistentStore = new StringMemento(); + + /** + * @param editorID + * @param r + */ + public SysdynEditorInput(String editorID, Resource r, Resource model, String rvi) { + super(editorID, r, model, rvi); + if (editorID == null) + throw new IllegalArgumentException("null editor id"); + if (r == null) + throw new IllegalArgumentException("null resource"); + + this.editorID = editorID; + this.randomAccessResourceId = ""; + this.resource = r; + this.rvi = rvi; + this.session = SimanticsUI.getSession(); + + ensureRandomAccessId(); + setNonExistant(); + } + + void ensureRandomAccessId() { + if (resource == null) + throw new IllegalStateException("resource is null, input is disposed"); + // Make sure that the resource has a random access id + try { + SerialisationSupport support = session.getService(SerialisationSupport.class); + randomAccessResourceId = String.valueOf(support.getRandomAccessId(resource)); + } catch (DatabaseException e) { + throw new RuntimeException(e); + } + } + + @Override + public void init(IAdaptable adapter) throws DatabaseException { + if (resource == null && randomAccessResourceId != null) { + getSession().syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph g) throws DatabaseException { + try { + long id = Long.parseLong(randomAccessResourceId); + resource = g.getService(SerialisationSupport.class).getResource(id); + update(g); + } catch (NumberFormatException e) { + setNonExistant(); + } catch (DatabaseException e) { + setNonExistant(); + } + } + }); + } else { + if (resource != null) { + updateCaches(getSession(), true); + } + } + } + + @Override + public void dispose() { + //System.out.println("dispose resource editor input: " + name); + // NOTE: this has to be done since Eclipse will cache these IEditorInput + // instances within EditorHistoryItem's that are stored in an EditorHistory + // instance. They are held by strong reference which means that the session + // cannot be collected if it is not nulled here. + session = null; + resource = null; + } + + /** + * @return a graph instance if it exists and has not yet been disposed, + * null otherwise + */ + public Session getSession() { + // TODO: also throw an exception if the session is disposed + if (session == null) + throw new IllegalStateException("session is disposed"); + return session; + } + + @Override + public boolean exists() { + return exists; + } + + @Override + public boolean exists(ReadGraph graph) throws DatabaseException { + try { + assertExists(graph); + return true; + } catch (ResourceNotFoundException e) { + } catch (Nonexistant e) { + } + return false; + } + + @Override + public Resource getResource() { + return resource; + } + + @Override + @Deprecated + public ResourceArray getResourceArray() { + return new ResourceArray(resource); + } + + @Override + public String getRVI() { + return rvi; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getImageDescriptor() + */ + @Override + public ImageDescriptor getImageDescriptor() { + return imageDesc; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getName() + */ + @Override + public String getName() { + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getToolTipText() + */ + @Override + public String getToolTipText() { + return tooltip; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getPersistable() + */ + @Override + public IPersistableElement getPersistable() { + // Don't allow persistability when it's not possible. + if (!isPersistable()) + return null; + return this; + } + + protected boolean isPersistable() { + if (session == null) + return false; + LifecycleSupport lc = session.peekService(LifecycleSupport.class); + if (lc == null) + return false; + if (lc.isClosed()) + return false; + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPersistableElement#getFactoryId() + */ + @Override + public String getFactoryId() { + return ResourceEditorInputFactory2.getFactoryId(); + } + + /** + * Saves the state of the given resource editor input into the given memento. + * + * @param memento the storage area for element state + * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento) + */ + @Override + public void saveState(IMemento memento) { +// List ids = randomAccessResourceId; + if (randomAccessResourceId == null) { + // Must create a new random access ID. + ensureRandomAccessId(); + } + IMemento child = memento.createChild(ResourceEditorInputFactory2.TAG_RESOURCE_ID); + child.putTextData(randomAccessResourceId); + memento.putString(ResourceEditorInputFactory2.TAG_EDITOR_ID, editorID); +// memento.putString(ResourceEditorInputFactory2.TAG_MODEL_URI, modelURI); + memento.putString(ResourceEditorInputFactory2.TAG_MODEL_ID, modelId); + memento.putString(ResourceEditorInputFactory2.TAG_RVI, rvi); + memento.putString(ResourceEditorInputFactory2.TAG_EXTERNAL_MEMENTO_ID, persistentStore.toString()); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + //System.out.println("[ResourceEditorInput] getAdapter: " + adapter.getName()); + return null; + } + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + editorID.hashCode(); + result = prime * result + ObjectUtils.hashCode(modelId); + result = prime * result + ObjectUtils.hashCode(rvi); + result = prime * result + ObjectUtils.hashCode(randomAccessResourceId); + return result; + } + + private void updateCaches(RequestProcessor processor, boolean sync) throws DatabaseException { + ReadRequest req = new ReadRequest() { + @Override + public void run(ReadGraph g) throws DatabaseException { + update(g); + } + }; + if (sync) { + processor.syncRequest(req); + } else { + processor.asyncRequest(req); + } + } + + static class Nonexistant extends DatabaseException { + private static final long serialVersionUID = -7964385375237203651L; + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + } + + /* (non-Javadoc) + * @see org.simantics.ui.workbench.IResourceEditorInput#update(org.simantics.db.Graph) + */ + @Override + public void update(ReadGraph g) throws DatabaseException { + Resource r = getResource(); + if (r == null) + return; + + if (DEBUG_UPDATE) + System.out.println("update(" + this + ")"); + + try { + assertExists(g); + + name = g.syncRequest(new TitleRequest(editorID, this)); + if (name == null) + name = NO_NAME; + + tooltip = g.syncRequest(new ToolTipRequest(editorID, this)); + if (tooltip == null) + tooltip = NO_NAME; + + try { + ImageDescriptorProvider idp = g.adapt(r, ImageDescriptorProvider.class); + imageDesc = idp.get(); + } catch (AdaptionException e) { + imageDesc = ImageDescriptor.getMissingImageDescriptor(); + } catch (ProvisionException e) { + imageDesc = ImageDescriptor.getMissingImageDescriptor(); + ErrorLogger.defaultLogError(e); + } + + if (DEBUG_UPDATE) + System.out.println("update(" + this + ") finished"); + } catch (DatabaseException e) { + if (DEBUG_UPDATE) + e.printStackTrace(); + setNonExistant(); + } + } + + private void assertExists(ReadGraph g) throws DatabaseException { + Resource r = getResource(); + if (r == null) + throw new Nonexistant(); + + // 1. Check resource existence + boolean exists = g.hasStatement(r); + if (!exists) + throw new Nonexistant(); + + // 2. Validate modelURI + if (getModel(g) != null && g.getPossibleURI(getModel(g)) != null) { + Layer0X L0X = Layer0X.getInstance(g); + + // 3. Validate RVI + Resource model = getModel(g); + Resource baseRealization = g.getPossibleObject(model, L0X.HasBaseRealization); + Variable modelVariable = Variables.getVariable(g, g.getURI(baseRealization)); + modelVariable.browse(g, getRVI()); + } + + // Touch the diagram title calculation within this existence + // checking request. + g.syncRequest(new TitleRequest(editorID, this)); + } + + private void setNonExistant() { + if (DEBUG_UPDATE) + System.out.println("setNonExistant(" + this + " @ " + System.identityHashCode(this) + ")"); + + exists = false; + tooltip = name = NO_NAME; + imageDesc = ImageDescriptor.getMissingImageDescriptor(); + } + + public IMemento getPersistentStore() { + return persistentStore; + } + + @Override + public String toString() { + return getClass().getSimpleName() + " [name=" + getName() + ", resource=" + resource + "]"; + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorNamingService.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorNamingService.java new file mode 100644 index 00000000..98f825bf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorNamingService.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor; + +import org.eclipse.ui.IEditorInput; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.ui.features.EditorNamingService2; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.workbench.IResourceEditorInput2; + +/** + * SysdynEditorNamingService provides names for diagram viewers. + * If the viewer shows an instantiated module, the service provides a name of type: "instanceName : instanceOf". + * Otherwise works as standard EditorNamingService2. + * + * @author Teemu Lempinen + * + */ +public class SysdynEditorNamingService extends EditorNamingService2 { + + @Override + public String getName(ReadGraph g, String editorId, IEditorInput in) throws DatabaseException { + if(in instanceof IResourceEditorInput2) { + IResourceEditorInput2 input = (IResourceEditorInput2) in; + + if(input.getRVI() != null && !input.getRVI().isEmpty()) { + Resource model = input.getModel(g); + if(model != null) { + Resource configuration = g.getPossibleObject(model, SimulationResource.getInstance(g).HasConfiguration); + String configurationName = NameUtils.getSafeName(g, configuration); + String uri = g.getURI(input.getModel(g)) + "/" + configurationName + input.getRVI(); + Variable v = Variables.getPossibleVariable(g, uri); + if(v != null) { + String name = input.getRVI(); + if(name.contains("/")) + name = name.substring(name.lastIndexOf("/") + 1); + + Resource instanceOf = g.getPossibleObject(v.getRepresents(g), Layer0.getInstance(g).InstanceOf); + return name + " : " + NameUtils.getSafeName(g, instanceOf); + } + } + } else { + ModelingResources mr = ModelingResources.getInstance(g); + SysdynResource sr = SysdynResource.getInstance(g); + Resource composite = g.getPossibleObject(input.getResource(), mr.DiagramToComposite); + if(composite != null) { + if(g.isInstanceOf(composite, sr.Configuration)) + composite = g.getPossibleObject(composite, Layer0.getInstance(g).PartOf); + if(composite != null) + return NameUtils.getSafeName(g, composite); + } + } + } + return super.getName(g, editorId, in); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/CreateVariablesShortcutParticipant.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/CreateVariablesShortcutParticipant.java new file mode 100644 index 00000000..96d6f930 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/CreateVariablesShortcutParticipant.java @@ -0,0 +1,322 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor.participant; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.util.Set; + +import org.simantics.db.Resource; +import org.simantics.db.common.request.Queries; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.adapter.GraphToDiagramSynchronizer; +import org.simantics.diagram.elements.TextNode; +import org.simantics.diagram.query.DiagramRequests; +import org.simantics.g2d.canvas.SGDesignation; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.DiagramMutator; +import org.simantics.g2d.diagram.DiagramUtils; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant; +import org.simantics.g2d.diagram.participant.ElementPainter; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.participant.MouseUtil; +import org.simantics.g2d.participant.MouseUtil.MouseInfo; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; +import org.simantics.scenegraph.g2d.events.KeyEvent; +import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent; +import org.simantics.scenegraph.g2d.events.KeyEvent.KeyReleasedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; +import org.simantics.scenegraph.g2d.nodes.ShapeNode; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements.AuxiliaryFactory; +import org.simantics.sysdyn.ui.elements.CloudFactory; +import org.simantics.sysdyn.ui.elements.InputFactory; +import org.simantics.sysdyn.ui.elements.LoopFactory; +import org.simantics.sysdyn.ui.elements.ShadowFactory; +import org.simantics.sysdyn.ui.elements.StockFactory; +import org.simantics.sysdyn.ui.elements.ValveFactory; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.ui.ExceptionUtils; + +public class CreateVariablesShortcutParticipant extends AbstractDiagramParticipant { + + private GraphToDiagramSynchronizer synchronizer; + + private VariableInformation variableInformation; + + @Dependency + MouseUtil mouseUtil; + + @Dependency + Selection selection; + + @Dependency + ElementPainter diagramPainter; + + ShapeNode node; + G2DParentNode parent; + + private boolean createVar; + private IDiagram createVarDiagram; + + @SGInit(designation = SGDesignation.CANVAS) + public void init(G2DParentNode parent) { + this.parent = parent; + } + + public void removeSG() { + node.remove(); + node = null; + setDirty(); + } + + void updateSG() { + + if (node == null) { + node = variableInformation.node; + } + + MouseInfo mi = mouseUtil.getMouseInfo(0); + if (mi == null) + return; + + Point2D newPos = mi.canvasPosition; + double x = newPos.getX(); + double y = newPos.getY(); + + AffineTransform origAt = node.getTransform(); + double oldX = origAt.getTranslateX(); + double oldY = origAt.getTranslateY(); + AffineTransform move = new AffineTransform(); + move.setToTranslation(x - oldX, y - oldY); + AffineTransform at2 = new AffineTransform(origAt); + at2.preConcatenate(move); + node.setTransform(at2); + setDirty(); + } + + public CreateVariablesShortcutParticipant(GraphToDiagramSynchronizer synchronizer) { + this.synchronizer = synchronizer; + } + + @EventHandler(priority = -10) + public boolean handleKeyboardEvent(KeyEvent ke) { + + KeyPressedEvent kpe; + if (ke instanceof KeyPressedEvent) { + + kpe = (KeyPressedEvent) ke; + + if (!kpe.isShiftDown() || isEditing()) + return false; + + if (kpe.keyCode == java.awt.event.KeyEvent.VK_A) { + variableInformation = new VariableInformation( + java.awt.event.KeyEvent.VK_A, + SysdynResource.URIs.AuxiliarySymbol, + (ShapeNode)AuxiliaryFactory.AUX_STATIC_IMAGE.init(parent) + ); + } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_S) { + variableInformation = new VariableInformation( + java.awt.event.KeyEvent.VK_S, + SysdynResource.URIs.StockSymbol, + (ShapeNode)StockFactory.STOCK_IMAGE.init(parent) + ); + } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_C) { + variableInformation = new VariableInformation( + java.awt.event.KeyEvent.VK_C, + SysdynResource.URIs.CloudSymbol, + (ShapeNode)CloudFactory.CLOUD_IMAGE.init(parent) + ); + } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_V) { + variableInformation = new VariableInformation( + java.awt.event.KeyEvent.VK_V, + SysdynResource.URIs.ValveSymbol, + (ShapeNode)ValveFactory.VALVE_STATIC_IMAGE.init(parent) + ); + } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_I) { + variableInformation = new VariableInformation( + java.awt.event.KeyEvent.VK_I, + SysdynResource.URIs.InputSymbol, + (ShapeNode)InputFactory.INPUT_IMAGE.init(parent) + ); + } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_G) { + variableInformation = new VariableInformation( + java.awt.event.KeyEvent.VK_G, + SysdynResource.URIs.ShadowSymbol, + (ShapeNode)ShadowFactory.GHOST_IMAGE.init(parent) + ); + } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_L) { + variableInformation = new VariableInformation( + java.awt.event.KeyEvent.VK_L, + SysdynResource.URIs.LoopSymbol, + (ShapeNode)LoopFactory.LOOP_STATIC_IMAGE.init(parent) + ); + } + + if (variableInformation != null) { + updateSG(); + return true; + } + } + + KeyReleasedEvent kre; + if (ke instanceof KeyReleasedEvent) { + kre = (KeyReleasedEvent) ke; + + if (variableInformation != null + && (kre.keyCode == variableInformation.shortcutKey || kre.keyCode == java.awt.event.KeyEvent.VK_SHIFT)) { + if (node != null) { + // If there is a variable to be created, do it when a key is released. + if (createVar) { + createVar = false; + createVariableOnDiagram(createVarDiagram); + } + variableInformation = null; + removeSG(); + return true; + } + } + } + + return false; + + } + + @EventHandler(priority = -10) + public boolean handleMouse(MouseMovedEvent e) { + + if (variableInformation != null ) { + updateSG(); + } else { + if (node != null) { + removeSG(); + } + } + return false; + } + + + @EventHandler(priority = 100) + public boolean handleMouseEvent(MouseEvent me) { + + + MouseEvent.MouseClickEvent mce; + if (me instanceof MouseEvent.MouseClickEvent) { + mce = (MouseEvent.MouseClickEvent) me; + } else { + return false; + } + + if (! + ( + mce.button == MouseEvent.LEFT_BUTTON && + variableInformation != null && + mce.stateMask == MouseEvent.SHIFT_MASK + )) + { + return false; + } + + final IDiagram d = getHint(DiagramHints.KEY_DIAGRAM); + if (d == null) + return false; + + // Need to create a new variable, save the diagram to do this later. + createVar = true; + createVarDiagram = d; + + return true; + } + + + private void createVariableOnDiagram(IDiagram d) { + DiagramUtils.mutateDiagram(d, new Callback() { + @Override + public void run(DiagramMutator m) { + + Resource r; + try { + r = SimanticsUI + .getSession() + .syncRequest( + Queries + .resource(variableInformation.symbolURI)); + ElementClass ec = SimanticsUI.getSession().syncRequest( + DiagramRequests.getElementClass(r, diagram)); + + IElement element = m.newElement(ec); + + // MouseUtil mutil = new MouseUtil(); + MouseInfo minfo = mouseUtil.getMouseInfo(0); + + //at least when using breakpoints this is possible + if(minfo == null) + return; + + Point2D p = minfo.canvasPosition; + //FIXME - Arto element doesn't know its size at first. Hopefully temp fix. + p.setLocation(p.getX()-5.46, p.getY()+1); + + ElementUtils.setPos(element, p); + + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + + } + }); + + synchronizer.getCanvasContext().getContentContext().setDirty(); + + } + + private class VariableInformation { + public String symbolURI; + public ShapeNode node; + public int shortcutKey; + + public VariableInformation(int shortcutKey, String symbolURI, ShapeNode node) { + this.symbolURI = symbolURI; + this.node = node; + this.shortcutKey = shortcutKey; + } + } + + private boolean isEditing() { + int selectionId = 0; + Set ss = selection.getSelection(selectionId); + if (ss.isEmpty()) { + return false; + } + for (IElement e : ss) { + for(Object o : e.getHints().values()) { + if (o instanceof TextNode) { + TextNode tn = (TextNode) o; + if(tn.isEditMode()) + return true; + } + } + } + return false; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SelectionUpdaterParticipant.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SelectionUpdaterParticipant.java new file mode 100644 index 00000000..023c78ce --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SelectionUpdaterParticipant.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor.participant; + +import java.util.Collection; + +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.VirtualGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.canvas.impl.HintReflection.HintListener; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintObservable; +import org.simantics.utils.ui.AdaptionUtils; + + +public class SelectionUpdaterParticipant extends AbstractDiagramParticipant { + + @Dependency Selection selection; + + @HintListener(Class = Selection.class, Field = "SELECTION0") + public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { + IDiagram diagram = sender.getHint(DiagramHints.KEY_DIAGRAM); + Collection elements = AdaptionUtils.adaptToCollection(newValue, IElement.class); + if(diagram != null) { + Session session = SimanticsUI.getSession(); + session.asyncRequest(new ModifyDiagramSelection(session.getService(VirtualGraph.class), diagram, elements)); + } + } + + @HintListener(Class = Selection.class, Field = "SELECTION0") + public void hintRemoved(IHintObservable sender, Key key, Object oldValue) { + IDiagram diagram = sender.getHint(DiagramHints.KEY_DIAGRAM); + if(diagram != null) { + Session session = SimanticsUI.getSession(); + session.asyncRequest(new ModifyDiagramSelection(session.getService(VirtualGraph.class), diagram, null)); + } + } + + + private class ModifyDiagramSelection extends WriteRequest { + IDiagram diagram; + Collection elements; + + public ModifyDiagramSelection(VirtualGraph provider, IDiagram diagram, Collection elements) { + super(provider); + this.elements = elements; + this.diagram = diagram; + } + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Resource diagramRuntime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE); + + if(diagramRuntime == null) { + return; + } + + SysdynResource SR = SysdynResource.getInstance(graph); + DiagramResource DR = DiagramResource.getInstance(graph); + + graph.deny(diagramRuntime, SR.ConfigurationDiagram_selection); + + if(elements != null) { + for(IElement e : elements) { + Resource object = e.getHint(ElementHints.KEY_OBJECT); + if(object != null && graph.isInstanceOf(object, DR.Element)) { + graph.claim(diagramRuntime, SR.ConfigurationDiagram_selection, object); + } + } + } + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynComponentCopyAdvisor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynComponentCopyAdvisor.java new file mode 100644 index 00000000..8e615863 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynComponentCopyAdvisor.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor.participant; + +import java.util.Map; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ServiceException; +import org.simantics.diagram.synchronization.ISynchronizationContext; +import org.simantics.diagram.synchronization.StatementEvaluation; +import org.simantics.diagram.synchronization.SynchronizationHints; +import org.simantics.diagram.synchronization.graph.CopyAdvisorUtil; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ComponentUtils; +import org.simantics.modeling.mapping.ComponentCopyAdvisor; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.datastructures.BinaryFunction; + +public class SysdynComponentCopyAdvisor extends ComponentCopyAdvisor { + + private Layer0 L0; + private StructuralResource2 STR; + private SysdynResource SYSDYN; + + @Override + public Object copy(ISynchronizationContext context, WriteGraph graph, Resource source, Resource sourceContainer, Resource targetContainer, Map map) throws DatabaseException { +// Object copy = super.copy(context, graph, source, sourceContainer, targetContainer, map); + + BinaryFunction tester = new BinaryFunction() { + @Override + public StatementEvaluation call(ReadGraph graph, Statement statement) { + try { + if(statement.getPredicate().equals(L0.List_Next) || + statement.getPredicate().equals(L0.List_Previous)) { + return StatementEvaluation.INCLUDE_AND_FOLLOW; + } else if(statement.getPredicate().equals(L0.List_Element)){ + if(graph.isInstanceOf(statement.getObject(), SYSDYN.Enumeration)) + return StatementEvaluation.INCLUDE; + else + return StatementEvaluation.INCLUDE_AND_FOLLOW; + } else if(statement.getPredicate().equals(SYSDYN.Shadow_original)) + return StatementEvaluation.INCLUDE; + } catch (ServiceException e) { + e.printStackTrace(); + } + return StatementEvaluation.USE_DEFAULT; + } + + }; + + SYSDYN = SysdynResource.getInstance(graph); + L0 = Layer0.getInstance(graph); + STR = StructuralResource2.getInstance(graph); + Resource copy = null; + if (graph.isInstanceOf(source, STR.Connection)) { + // Configuration connections are not named, can't use TG copy for + // them at the moment. + copy = CopyAdvisorUtil.copy2(graph, source, null, map); + } else { +// Resource model = graph.syncRequest(new PossibleModel(targetContainer)); +// copy = CopyAdvisorUtil.copy4(graph, source, model); + copy = CopyAdvisorUtil.copy2(graph, source, tester, map); + } + + Layer0 L0 = Layer0.getInstance(graph); + if (graph.hasStatement(sourceContainer, L0.ConsistsOf, source)) + graph.claim(targetContainer, L0.ConsistsOf, copy); + + if (context.get(SynchronizationHints.NO_RENAME) == null) +// renameComponent(context, graph, source, copy, sourceContainer, targetContainer); + rename(context, graph, source, (Resource)copy, sourceContainer, targetContainer); + + return copy; + } + + + public String rename(ISynchronizationContext context, WriteGraph graph, Resource source, + Resource copy, Resource sourceContainer, Resource targetContainer) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + String copyName = NameUtils.getSafeName(graph, copy); + Resource configurationRoot = ComponentUtils.getCompositeConfigurationRoot(graph, targetContainer); + String name = NameUtils.findFreshName(graph, copyName, configurationRoot, l0.ConsistsOf, "%s%d"); + graph.claimLiteral(copy, l0.HasName, name, Bindings.STRING); + return name; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java new file mode 100644 index 00000000..72de5cbe --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java @@ -0,0 +1,472 @@ +package org.simantics.sysdyn.ui.editor.participant; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.diagram.participant.ConnectTool2; +import org.simantics.diagram.participant.ConnectionBuilder; +import org.simantics.diagram.participant.ControlPoint; +import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit; +import org.simantics.g2d.connection.IConnectionAdvisor; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.handler.Topology.Terminal; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementClasses; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.impl.Element; +import org.simantics.g2d.elementclass.BranchPointClass; +import org.simantics.g2d.elementclass.FlagClass; +import org.simantics.g2d.routing.Constants; +import org.simantics.g2d.routing.IConnection; +import org.simantics.g2d.routing.IRouter2; +import org.simantics.g2d.routing.TrivialRouter2; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.events.MouseEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; +import org.simantics.scenegraph.g2d.nodes.ShapeNode; +import org.simantics.scenegraph.g2d.snap.ISnapAdvisor; +import org.simantics.structural2.modelingRules.ConnectionJudgement; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.editor.routing.FlowRouter; +import org.simantics.sysdyn.ui.elements.CloudFactory; +import org.simantics.sysdyn.ui.elements.SysdynElementHints; +import org.simantics.sysdyn.ui.elements.ValveFactory.ValveSceneGraph; +import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.ExceptionUtils; + +public class SysdynConnectTool extends ConnectTool2 { + + public SysdynConnectTool(TerminalInfo startTerminal, int mouseId, + Point2D startCanvasPos) { + super(startTerminal, mouseId, startCanvasPos); + } + + @Override + @SGInit + public void initSG(G2DParentNode parent) { + ghostNode = parent.addNode(G2DParentNode.class); + ghostNode.setZIndex(PAINT_PRIORITY); + + ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class); + pathNode.setColor(Color.BLACK); + pathNode.setStroke(new BasicStroke(1f)); + pathNode.setScaleStroke(true); + pathNode.setZIndex(0); + + G2DParentNode points = ghostNode.getOrCreateNode("points", G2DParentNode.class); + points.setZIndex(1); + + updateSG(); + } + + @Override + protected TerminalInfo createFlag(EdgeEnd connectionEnd) { + ElementClass flagClass = elementClassProvider.get(ElementClasses.FLAG); + IElement e = Element.spawnNew(flagClass); + + e.setHint(FlagClass.KEY_FLAG_TYPE, endToFlagType(connectionEnd)); + e.setHint(FlagClass.KEY_FLAG_MODE, FlagClass.Mode.Internal); + + TerminalInfo ti = new TerminalInfo(); + ti.e = e; + + // start: this part changed to support overlapping terminals + ArrayList terminals = new ArrayList(); + ElementUtils.getTerminals(e, terminals, false); + ti.t = terminals.get(0); + // end + + ti.posElem = TerminalUtil.getTerminalPosOnElement(e, ti.t); + ti.posDia = TerminalUtil.getTerminalPosOnDiagram(e, ti.t); + + return ti; + } + + static class Segment { + public final ControlPoint begin; + public final ControlPoint end; + public Path2D path; + + public Segment(ControlPoint begin, ControlPoint end) { + this.begin = begin; + this.end = end; + } + + @Override + public String toString() { + return "Segment[begin=" + begin + ", end=" + end + ", path=" + path + "]"; + } + } + + private List toSegments(Deque points) { + if (points.isEmpty()) + return Collections.emptyList(); + + List segments = new ArrayList(); + + Iterator it = points.iterator(); + ControlPoint prev = it.next(); + while (it.hasNext()) { + ControlPoint next = it.next(); + segments.add(new Segment(prev, next)); + prev = next; + } + + return segments; + } + + public interface SysdynConnection extends IConnection { } + + @Override + protected void updateSG() { + if (controlPoints.isEmpty()) + return; + + // Route connection segments separately + IRouter2 router = ElementUtils.getHintOrDefault(diagram, DiagramHints.ROUTE_ALGORITHM, TrivialRouter2.INSTANCE); + final List segments = toSegments(controlPoints); + //System.out.println("controlpoints: " + controlPoints); + //System.out.println("segments: " + segments); + router.route(new SysdynConnection() { + @Override + public Collection getSegments() { + return segments; + } + + @Override + public Connector getBegin(Object seg) { + return getConnector(((Segment) seg).begin); + } + + @Override + public Connector getEnd(Object seg) { + return getConnector(((Segment) seg).end); + } + + private Connector getConnector(ControlPoint cp) { + Connector c = new Connector(); + c.x = cp.getPosition().getX(); + c.y = cp.getPosition().getY(); + + c.allowedDirections = Constants.EAST_FLAG | Constants.WEST_FLAG + | Constants.NORTH_FLAG | Constants.SOUTH_FLAG; + + TerminalInfo ti = cp.getAttachedTerminal(); + if (ti != null && (ti != startFlag && ti != endFlag)) { + if(ti.e.getElementClass().containsClass(ValveSceneGraph.class)) { + Rectangle2D bounds = ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D(); + c.parentObstacle = new Rectangle2D.Double( + bounds.getCenterX() - FlowRouter.OFFSET, + bounds.getCenterY() - FlowRouter.OFFSET, + FlowRouter.OFFSET * 2, + FlowRouter.OFFSET * 2); + } else { + c.parentObstacle = ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D(); + } + } else if (ti != null && ti == startFlag) { + c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y), + ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D()); + } else if (isEndingInFlag() && ti.e != null) { + c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y), + CloudFactory.CLOUD_IMAGE.getBounds()); + } else { + c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y), + BranchPointClass.DEFAULT_IMAGE2.getBounds()); + } + + return c; + } + + @Override + public void setPath(Object seg, Path2D path) { + ((Segment) seg).path = (Path2D) path.clone(); + } + }); + + // Combine the routed paths + Path2D path = new Path2D.Double(); + for (Segment seg : segments) { + //System.out.println("SEG: " + seg); + if (seg.path != null) + path.append(seg.path.getPathIterator(null), true); + } + + // Create scene graph to visualize the connection. + ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class); + pathNode.setShape(path); + + /* + * Removed Points + */ + + setDirty(); + } + + @Override + protected Object canConnect(final IConnectionAdvisor advisor, final IElement endElement, final Terminal endTerminal) { + final IElement se = startTerminal != null ? startTerminal.e : startFlag.e; + final Terminal st = startTerminal != null ? startTerminal.t : null; + + if(se.equals(endElement)) return null; + if(Boolean.FALSE.equals(diagram.getHint(DiagramHints.KEY_USE_CONNECTION_FLAGS)) && endElement == null) { + return null; + } + + if(endElement == null && endTerminal == null) + return advisor.canBeConnected(null, se, st, endElement, endTerminal); + + try { + return SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Object perform(ReadGraph g) throws DatabaseException { + + // Checking if connection type can be connected to the intended endElement + SysdynResource sr = SysdynResource.getInstance(g); + StaticObjectAdapter soa = endElement.getElementClass().getSingleItem(StaticObjectAdapter.class); + Resource end = soa.adapt(Resource.class); + ElementClass dependency = elementClassProvider.get(ConnectionClasses.DEPENDENCY); + ElementClass flow = elementClassProvider.get(ConnectionClasses.FLOW); + ElementClass currentConnection = elementClassProvider.get(ElementClasses.CONNECTION); + if(currentConnection.equals(dependency)) { + if(end.equals(sr.CloudSymbol)) return null; + soa = se.getElementClass().getSingleItem(StaticObjectAdapter.class); + Resource start = soa.adapt(Resource.class); + if(g.isInheritedFrom(start, sr.ModuleSymbol) && !end.equals(sr.InputSymbol)) return null; + if(end.equals(sr.ShadowSymbol)) return null; + } else if (currentConnection.equals(flow)) { + if(!(end.equals(sr.StockSymbol) || end.equals(sr.ValveSymbol) || end.equals(sr.CloudSymbol))) return null; + } else { + return null; + } + + + if (advisor == null) + return Boolean.TRUE; + return advisor.canBeConnected(g, se, st, endElement, endTerminal); + } + + }); + } catch(DatabaseException e) { + e.printStackTrace(); + return null; + } + + } + + @Override + protected boolean processMouseMove(MouseMovedEvent me) { + mouseHasMoved = true; + + Point2D mouseControlPos = me.controlPosition; + Point2D mouseCanvasPos = util.controlToCanvas(mouseControlPos, new Point2D.Double()); + + ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); + if (snapAdvisor != null) + snapAdvisor.snap(mouseCanvasPos); + + // Record last snapped canvas position of mouse. + this.lastMouseCanvasPos.setLocation(mouseCanvasPos); + + if (isEndingInFlag()) { + endFlagNode.setTransform(AffineTransform.getTranslateInstance(mouseCanvasPos.getX(), mouseCanvasPos.getY())); + } + + List tiList = ((SysdynPointerInteractor)pi).pickTerminals(me.controlPosition); + TerminalInfo ti = null; + + IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); + for(TerminalInfo info : tiList) { + if(advisor == null || info.e == null || info.t == null) + continue; + Object canConnect = canConnect(advisor, info.e, info.t); + if (canConnect != null) { + ti = info; + break; + } + } + + if (ti != null && !isStartTerminal(ti.e, ti.t)) { + Pair canConnect = canConnect(ti.e, ti.t); + if (canConnect != null) { + connectionJudgment = canConnect.first; + + if (!isEndingInFlag() || !TerminalUtil.isSameTerminal(ti, endTerminal)) { + controlPoints.getLast() + .setPosition(ti.posDia) + .setAttachedToTerminal(ti); + + endTerminal = ti; + } + + // Make sure that we are ending with a flag if ALT is pressed + // and no end terminal is defined. If we are in flow creation + // mode, we want to show the terminal cloud (or flag) even when + // alt is not pressed. + if (inFlowMode() && flowInProgress() && !startTerminals.isEmpty()) + endWithoutTerminal(lastMouseCanvasPos, true); + else + endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)); + updateSG(); + return false; + } + } + + connectionJudgment = null; + if (isEndTerminalDefined()) { + // CASE: Mouse was previously on top of a valid terminal to end + // the connection. Now the mouse has been moved where there is + // no longer a terminal to connect to. + // + // => Disconnect the last edge segment from the previous + // terminal, mark endElement/endTerminal non-existent + // and connect the disconnected edge to a new branch point. + + controlPoints.getLast() + .setPosition(mouseCanvasPos) + .setDirection(calculateCurrentBranchPointDirection()) + .setAttachedToTerminal(null); + + endTerminal = null; + } else { + // CASE: Mouse was not previously on top of a valid ending + // element terminal. + // + // => Move and re-orient last branch point. + + controlPoints.getLast() + .setPosition(mouseCanvasPos) + .setDirection(calculateCurrentBranchPointDirection()); + } + + // Make sure that we are ending with a flag if ALT is pressed and no end + // terminal is defined. If we are in flow creation mode, we want to show + // the terminal cloud (or flag) even when alt is not pressed. + if (inFlowMode() && flowInProgress() && !startTerminals.isEmpty()) + endWithoutTerminal(lastMouseCanvasPos, true); + else + endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me)); + updateSG(); + return false; + } + + @Override + protected boolean processMouseButtonPress(MouseButtonPressedEvent e) { + MouseButtonEvent me = e; + + // Do nothing before the mouse has moved at least a little. + // This prevents the user from ending the connection right where + // it started. + if (!mouseHasMoved) + return true; + + if (me.button == MouseEvent.LEFT_BUTTON || + (me.button == MouseEvent.RIGHT_BUTTON && flowInProgress() && !inFlowMode())) { + Point2D mouseControlPos = me.controlPosition; + Point2D mouseCanvasPos = util.getInverseTransform().transform(mouseControlPos, new Point2D.Double()); + + ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR); + if (snapAdvisor != null) + snapAdvisor.snap(mouseCanvasPos); + + // Clicked on an allowed end terminal. End connection & end mode. + if (isEndTerminalDefined()) { + createConnection(); + remove(); + return true; + } else { + // Finish connection in thin air only if the + // connection was started from a valid terminal. + + // If we are in flow creation mode, we want to be able to + // create the terminal cloud (or flag) without having to + // press alt. + + if (!startTerminals.isEmpty() && ((me.stateMask & MouseEvent.ALT_MASK) != 0 || + (inFlowMode() && flowInProgress()))) { + Pair pair = canConnect(null, null); + if (pair != null) { + connectionJudgment = (ConnectionJudgement) pair.first; + selectedStartTerminal = pair.second; + createConnection(); + setDirty(); + remove(); + } else { + // Inform the user why connection couldn't be created. + ErrorLogger.defaultLogWarning("Can't resolve connection type for new connection.", null); + } + return true; + } else if (routePointsAllowed() + && (me.stateMask & (MouseEvent.ALT_MASK | MouseEvent.SHIFT_MASK | MouseEvent.CTRL_MASK)) == 0) { + // Add new connection control point. + controlPoints.add(newControlPointWithCalculatedDirection(mouseCanvasPos)); + resetForcedBranchPointDirection(); + updateSG(); + } + } + } + + return true; + } + + private boolean inFlowMode() { + return SysdynElementHints.FLOW_TOOL.equals(getHint(SysdynElementHints.SYSDYN_KEY_TOOL)); + } + + private boolean flowInProgress() { + return elementClassProvider.get(ElementClasses.CONNECTION).equals(elementClassProvider.get(ConnectionClasses.FLOW)); + } + + @Override + protected void createConnection() { + + if(this.connectionJudgment == null) return; + + final ConnectionJudgement judgment = this.connectionJudgment; + // ConnectionBuilder changed to SysdynconnectionBuilder to support overlapping terminals and valve creation + final ConnectionBuilder builder = new SysdynConnectionBuilder(this.diagram); + final Deque controlPoints = this.controlPoints; + final TerminalInfo startTerminal = this.startTerminal; + final TerminalInfo endTerminal = this.endTerminal; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + builder.create(graph, judgment, controlPoints, startTerminal, endTerminal); + } + }, new Callback() { + @Override + public void run(DatabaseException parameter) { + if (parameter != null) + ExceptionUtils.logAndShowError(parameter); + } + }); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectionBuilder.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectionBuilder.java new file mode 100644 index 00000000..159abc54 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectionBuilder.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor.participant; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.content.ConnectionUtil; +import org.simantics.diagram.participant.ConnectionBuilder; +import org.simantics.diagram.participant.ControlPoint; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.diagram.synchronization.graph.AddElement; +import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.handler.Topology.Terminal; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementClasses; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd; +import org.simantics.g2d.element.impl.Element; +import org.simantics.g2d.elementclass.FlagClass; +import org.simantics.layer0.Layer0; +import org.simantics.structural2.modelingRules.ConnectionJudgement; +import org.simantics.structural2.modelingRules.IModelingRules; +import org.simantics.sysdyn.ui.elements.SysdynElementClasses; +import org.simantics.sysdyn.ui.elements.ValveFactory; +import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses; +import org.simantics.utils.datastructures.Pair; + +public class SysdynConnectionBuilder extends ConnectionBuilder{ + + public SysdynConnectionBuilder(IDiagram diagram) { + super(diagram); + } + + /** + * @param graph + * @param judgment + * @param controlPoints + * @param startTerminal + * @param endTerminal + * @throws DatabaseException + */ + public void create(WriteGraph graph, ConnectionJudgement judgment, Deque controlPoints, + TerminalInfo startTerminal, TerminalInfo endTerminal) throws DatabaseException { + // If needs a valve, we will create two separate connections + if(needsValve(startTerminal, endTerminal)) { + createValveAndConnections(graph, judgment, controlPoints, startTerminal, endTerminal); + } + // If no need for valve, just call createConnection with false on createValve parameter + else { + createConnection(graph, judgment, controlPoints, startTerminal, endTerminal, false); + } + } + /** + * @param graph + * @param judgment + * @param controlPoints + * @param startTerminal + * @param endTerminal + * @throws DatabaseException + */ + public TerminalInfo createConnection(WriteGraph graph, ConnectionJudgement judgment, Deque controlPoints, + TerminalInfo startTerminal, TerminalInfo endTerminal, boolean createValve) throws DatabaseException { + TerminalInfo newValve = null; + + this.cu = new ConnectionUtil(graph); + + // 1. Get diagram connection to construct. + Resource connection = getOrCreateConnection(graph, startTerminal, endTerminal); + + // 1.1 Give running name to connection and increment the counter attached to the diagram. + AddElement.claimFreshElementName(graph, diagramResource, connection); + + // 2. Add branch points + List> bps = createBranchPoints(graph, connection, controlPoints); + + // 3. Create edges between branch points. + Resource firstBranchPoint = null; + Resource lastBranchPoint = null; + if (!bps.isEmpty()) { + Iterator> it = bps.iterator(); + Pair prev = it.next(); + firstBranchPoint = prev.second; + while (it.hasNext()) { + Pair next = it.next(); + cu.connect(prev.second, next.second); + prev = next; + } + lastBranchPoint = prev.second; + } + + // 4. Connect start/end terminals if those exist. + // If first/lastBranchPoint != null, connect to those. + // Otherwise connect the start/end terminals together. + Connector startConnector = null; + Connector endConnector = null; + IElement startFlag = null; + IElement endFlag = null; + + if (startTerminal != null) { + startConnector = createConnectorForNode(graph, connection, startTerminal, EdgeEnd.Begin, judgment); + } else if (createFlags) { + startFlag = createFlag(graph, connection, EdgeEnd.Begin, controlPoints.getFirst(), FlagClass.Type.In, ""); + ArrayList terminals = new ArrayList(); + ElementUtils.getTerminals(startFlag, terminals, false); + Terminal st = terminals.get(1); + startConnector = createConnectorForNode(graph, connection, (Resource) ElementUtils.getObject(startFlag), + st, EdgeEnd.Begin, judgment); + } + + if (endTerminal != null) { + endConnector = createConnectorForNode(graph, connection, endTerminal, EdgeEnd.End, judgment); + } else if (createFlags) { + if(createValve) + endFlag = createValveElement(graph, connection, EdgeEnd.End, controlPoints.getLast()); + else + endFlag = createFlag(graph, connection, EdgeEnd.End, controlPoints.getLast(), FlagClass.Type.Out, ""); + ArrayList terminals = new ArrayList(); + ElementUtils.getTerminals(endFlag, terminals, false); + Terminal et = terminals.get(0); + endConnector = createConnectorForNode(graph, connection, (Resource) ElementUtils.getObject(endFlag), + et, EdgeEnd.End, judgment); + + if(createValve) { + newValve = new TerminalInfo(); + newValve.e = endFlag; + newValve.t = terminals.get(1); + newValve.posElem = TerminalUtil.getTerminalPosOnElement(endFlag, newValve.t); + newValve.posDia = TerminalUtil.getTerminalPosOnDiagram(endFlag, newValve.t); + } + } + + if (firstBranchPoint == null || lastBranchPoint == null) { + cu.connect(startConnector.getConnector(), endConnector.getConnector()); + } else { + cu.connect(startConnector.getConnector(), firstBranchPoint); + cu.connect(lastBranchPoint, endConnector.getConnector()); + } + + // 5. Finally, set connection type according to modelling rules + IModelingRules modelingRules = diagram.getHint(DiagramModelHints.KEY_MODELING_RULES); + if (judgment.connectionType != null && modelingRules != null) { + modelingRules.setConnectionType(graph, connection, judgment.connectionType); + } + + this.cu = null; + return newValve; + } + + + /** + * @param graph + * @param connection + * @param end + * @param cp + * @param type + * @return an element describing the new created flag resource + * @throws DatabaseException + */ + public IElement createValveElement(WriteGraph graph, Resource connection, EdgeEnd end, ControlPoint cp) throws DatabaseException { + ElementClass valveClass = elementClassProvider.get(SysdynElementClasses.VALVE); + IElement valveElement = Element.spawnNew(valveClass); + Resource valveClassResource = ElementUtils.checkedAdapt(valveClass, Resource.class); + + Layer0 L0 = Layer0.getInstance(graph); + G2DResource G2D = G2DResource.getInstance(graph); + DiagramResource DIA = DiagramResource.getInstance(graph); + + Resource valve = graph.newResource(); + graph.claim(valve, L0.InstanceOf, null, valveClassResource); + graph.claim(valve, L0.PartOf, diagramResource); + AddElement.claimFreshElementName(graph, diagramResource, valve); + valveElement.setHint(ElementHints.KEY_OBJECT, valve); + + OrderedSetUtils.add(graph, diagramResource, valve); + + AffineTransform at = AffineTransform.getTranslateInstance(cp.getPosition().getX(), cp.getPosition().getY()); + valveElement.setHint(ElementHints.KEY_TRANSFORM, at); + double[] matrix = new double[6]; + at.getMatrix(matrix); + graph.claimLiteral(valve, DIA.HasTransform, G2D.Transform, matrix); + + // Put the element on all the currently active layers if possible. + if (layerManager != null) { + layerManager.removeFromAllLayers(graph, valve); + layerManager.putElementOnVisibleLayers(diagram, graph, valve); + } + + return valveElement; + } + + private boolean needsValve(TerminalInfo startTerminal, TerminalInfo endTerminal) { + if (!elementClassProvider.get(ElementClasses.CONNECTION) + .equals(elementClassProvider.get(ConnectionClasses.FLOW))) + return false; + if(startTerminal != null && startTerminal.e != null && startTerminal.e.getElementClass().getId().equals(ValveFactory.class.getSimpleName())) { + return false; + } else if(endTerminal != null && endTerminal.e != null && endTerminal.e.getElementClass().getId().equals(ValveFactory.class.getSimpleName())) { + return false; + } + return true; + } + + private void createValveAndConnections(WriteGraph graph, ConnectionJudgement judgment, Deque controlPoints, + TerminalInfo startTerminal, TerminalInfo endTerminal) throws DatabaseException { + + ControlPoint cpfirst = controlPoints.getFirst(); + ControlPoint cplast = controlPoints.getLast(); + + // Set the position in the middle of the route + double startX = cpfirst.getPosition().getX(); + double startY = cpfirst.getPosition().getY(); + double x = cplast.getPosition().getX(); + double y = cplast.getPosition().getY(); + Point2D pos = new Point2D.Double(startX - (startX - x) / 2, startY - (startY - y) / 2); + + // Replace the last control point with the control point in the middle + controlPoints.getLast().setPosition(pos); + + // Create a connection to a new valve and get the new valve + TerminalInfo newValve = createConnection(graph, judgment, controlPoints, startTerminal, null, true); + + // Replace the last control point with the original control point + controlPoints.getLast().setPosition(x, y); + + // Create a connection starting from the new valve + createConnection(graph, judgment, controlPoints, newValve, endTerminal, false); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynCopyPasteStrategy.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynCopyPasteStrategy.java new file mode 100644 index 00000000..319a4baa --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynCopyPasteStrategy.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor.participant; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import org.simantics.Simantics; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.handler.CopyPasteUtil; +import org.simantics.diagram.handler.DefaultCopyPasteStrategy; +import org.simantics.diagram.handler.PasteOperation; +import org.simantics.diagram.handler.Paster; +import org.simantics.diagram.handler.Paster.NodeMap; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.ui.utils.VariableNameValidator; +import org.simantics.utils.ui.ErrorLogger; + +/** + * A copy-paste-strategy that changes variable names in the equations of copied variables. + * + * + * @author Teemu Lempinen + * + */ +public class SysdynCopyPasteStrategy extends DefaultCopyPasteStrategy { + + @Override + public void paste(final PasteOperation op) { + try { + if (op.sameDiagram() && op.cut) { + CopyPasteUtil.localCutPaste(op); + } else { + Session session = Simantics.getSession(); + if (CopyPasteUtil.onlyFlagsWithoutCorrespondence(session, op.ea) + && CopyPasteUtil.checkFlagExternality(session, op.ea.flags, false)) { + CopyPasteUtil.continueFlags(op); + } else { + Paster paster = new Paster(session, op); + paster.perform(); + renameVariablesInEquations(session, paster.getNodeMap()); + } + } + } catch (DatabaseException e) { + ErrorLogger.defaultLogError(e); + } + } + + /** + * Rename variables in equations that need to be renamed. + * + * 1. Find the original variables and their names that were copied + * 2. For each copied variables, modify its equations. If equation had a reference + * to another copied variable, it needs to be modified. + * @param session + * @param nodeMap + */ + private void renameVariablesInEquations(Session session, final NodeMap nodeMap) { + session.asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Set copies = new HashSet(); + HashMap names = new HashMap(); + + ModelingResources MOD = ModelingResources.getInstance(graph); + // Collect copied variables and their names + for(Resource var : nodeMap.allResources()) { + Resource comp = graph.getPossibleObject(var, MOD.ElementToComponent); + + Resource r = nodeMap.getResource(var); + Resource copy = graph.getPossibleObject(r, MOD.ElementToComponent); + + if(comp != null && copy != null) { + names.put(NameUtils.getSafeName(graph, comp), NameUtils.getSafeName(graph, copy)); + copies.add(copy); + } + } + + // Change equations only from copied variables + for(Resource copy : copies) { + // Check for each name individually + for(String originalName : names.keySet()) { + String newName = names.get(originalName); + new VariableNameValidator().renameInEquations(graph, copy, originalName, newName); + } + } + } + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynElementClassProviders.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynElementClassProviders.java new file mode 100644 index 00000000..93c5675c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynElementClassProviders.java @@ -0,0 +1,69 @@ +package org.simantics.sysdyn.ui.editor.participant; + +import java.util.HashMap; +import java.util.Map; + +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementClassProviders; +import org.simantics.g2d.element.IElementClassProvider; + +public class SysdynElementClassProviders extends ElementClassProviders { + + /** + * Create an element class provider that based on the specified map. The + * provider will directly access the map with the received keys. The + * argument map will be copied. + * + * @param map the map to use for element class provision + * @return null if there is no provider for the specified key + */ + public static IElementClassProvider mappedProvider(Map map) { + // Copy the map as a safety measure + final Map copy = new HashMap(map); + return new ISysdynElementClassProvider() { + @Override + public ElementClass get(Object key) { + return copy.get(key); + } + + @Override + public void put(Object key, ElementClass value) { + copy.put(key, value); + } + + }; + } + + /** + * Does the same as {@link #mappedProvider(Map)}, the map is simply provided + * differently. The specified array must contain + * [key, ElementClass, key, ElementClass, ...]. + * + * @param map the map to use for element class provision + * @return null if there is no provider for the specified key + */ + public static IElementClassProvider mappedProvider(Object... keyClassPairs) { + if (keyClassPairs.length % 2 != 0) + throw new IllegalArgumentException(); + Map map = new HashMap(); + int n = keyClassPairs.length / 2; + for (int i = 0; i < n; ++i) { + Object key = keyClassPairs[i * 2]; + Object elementClass = keyClassPairs[i*2+1]; + if (!(elementClass instanceof ElementClass)) + throw new IllegalArgumentException("not an ElementClass instance: " + elementClass); + map.put(key, (ElementClass) elementClass); + } + return mappedProvider(map); + } + + + public interface ISysdynElementClassProvider extends IElementClassProvider { + + /** + * Update a value in an IElementClassProvider + */ + void put(Object key, ElementClass value); + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java new file mode 100644 index 00000000..7b348707 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java @@ -0,0 +1,185 @@ +package org.simantics.sysdyn.ui.editor.participant; +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ + +import java.awt.Shape; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.List; + +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.ICanvasParticipant; +import org.simantics.g2d.canvas.IToolMode; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.canvas.impl.DependencyReflection.Reference; +import org.simantics.g2d.connection.IConnectionAdvisor; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.handler.PickContext; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.diagram.participant.TerminalPainter; +import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil; +import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo; +import org.simantics.g2d.element.ElementClasses; +import org.simantics.g2d.element.IElementClassProvider; +import org.simantics.g2d.participant.KeyUtil; +import org.simantics.g2d.participant.MouseUtil; +import org.simantics.g2d.participant.TransformUtil; +import org.simantics.g2d.utils.GeometryUtils; +import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; +import org.simantics.scenegraph.g2d.events.MouseEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent; +import org.simantics.sysdyn.ui.editor.participant.SysdynElementClassProviders.ISysdynElementClassProvider; +import org.simantics.sysdyn.ui.editor.routing.DependencyRouter; +import org.simantics.sysdyn.ui.editor.routing.FlowRouter; +import org.simantics.sysdyn.ui.elements.AuxiliaryFactory; +import org.simantics.sysdyn.ui.elements.CloudFactory; +import org.simantics.sysdyn.ui.elements.InputFactory; +import org.simantics.sysdyn.ui.elements.ModuleFactory; +import org.simantics.sysdyn.ui.elements.SysdynElementHints; +import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses; + +/** + * Pointer tool does the following operations with mouse: + * - Selections + * - Scale + * - Rotate + * - Translate + * - Draws connections + * + * Pointer tool is active only when KEY_TOOLMODE is PointerToolMode + * + * TODO Pick rectangle not a point + * + * @author Toni Kalajainen + */ +public class SysdynPointerInteractor extends PointerInteractor { + + @Dependency Selection selection; + @Dependency KeyUtil keys; + @Dependency TransformUtil util; + @Dependency PickContext pickContext; + @Dependency MouseUtil mice; + @Reference TerminalPainter terminalPainter; + + public SysdynPointerInteractor(boolean clickSelect, boolean boxSelect, boolean dragElement, boolean dndDragElement, boolean connect, boolean doubleClickEdit, IElementClassProvider newConnectionClassProvider) { + super(clickSelect, boxSelect, dragElement, dndDragElement, connect, doubleClickEdit, newConnectionClassProvider); + } + + @Override + @EventHandler(priority = TOOL_PRIORITY) + public boolean handlePress(MouseButtonPressedEvent me) { + if (!connects()) + return false; + if (elementClassProvider == null) + return false; + + // There should (maybe) be only one sysdynConnectTool associated with + // the canvas context at a time. If this is not the case, right-clicks + // are not always handled correctly mid-connection as they are instead + // treated as commands to create a new cloud and a new flow. There + // might be a more sensible way to fix this. + if (getContext().containsItemByClass(SysdynConnectTool.class)) { + return false; + } + + IToolMode mode = getHint(Hints.KEY_TOOL); + if (!Hints.CONNECTTOOL.equals(mode)) + return false; + + IToolMode sysdynMode = getHint(SysdynElementHints.SYSDYN_KEY_TOOL); + + assertDependencies(); + + TerminalInfo ti = pickTerminal(me.controlPosition); + Point2D curCanvasPos = util.controlToCanvas(me.controlPosition, null); + + ICanvasParticipant bsi = null; + + if (me.button == MouseEvent.LEFT_BUTTON) { + if (SysdynElementHints.LOCK_TOOL.equals(sysdynMode)) + // Do nothing. + return false; + else if (SysdynElementHints.DEPENDENCY_TOOL.equals(sysdynMode)) + bsi = getDependencyConnectTool(ti, me.mouseId, curCanvasPos); + else if (SysdynElementHints.FLOW_TOOL.equals(sysdynMode)) + bsi = getFlowConnectTool(ti, me.mouseId, curCanvasPos); + else + bsi = getDependencyConnectTool(ti, me.mouseId, curCanvasPos); + } + else if (me.button == MouseEvent.RIGHT_BUTTON) { + if (SysdynElementHints.LOCK_TOOL.equals(sysdynMode) || + SysdynElementHints.DEPENDENCY_TOOL.equals(sysdynMode) || + SysdynElementHints.FLOW_TOOL.equals(sysdynMode)) + return false; + else + bsi = getFlowConnectTool(ti, me.mouseId, curCanvasPos); + } + + if (bsi != null) { + getContext().add(bsi); + return true; + } + + return false; + } + + private ICanvasParticipant getDependencyConnectTool(TerminalInfo ti, int mouseId, Point2D curCanvasPos) { + // can not have dependencies that start from thin air + if (ti == null) + return null; + // can not have dependencies that start from clouds + if (ti.e.getElementClass().getId().equals(CloudFactory.class.getSimpleName())) + return null; + + diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new DependencyRouter()); + diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, false); + ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider; + secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.DEPENDENCY)); + + // not sure if this is necessary + IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); + if (advisor == null || advisor.canBeginConnection(null, ti.e, ti.t)) { + return new SysdynConnectTool(ti, mouseId, curCanvasPos); + } + + return null; + } + + private ICanvasParticipant getFlowConnectTool(TerminalInfo ti, int mouseId, Point2D curCanvasPos) { + // flows must not start from auxiliaries, inputs or modules + if (ti != null && (ti.e.getElementClass().getId().equals(AuxiliaryFactory.class.getSimpleName()) || + ti.e.getElementClass().getId().equals(InputFactory.class.getSimpleName()) || + ti.e.getElementClass().getId().equals(ModuleFactory.class.getSimpleName()))) + return null; + + diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new FlowRouter()); + diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, true); + ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider; + secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.FLOW)); + + // not sure if this is necessary + IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR); + if (ti == null || advisor == null || advisor.canBeginConnection(null, ti.e, ti.t)) { + return new SysdynConnectTool(ti, mouseId, curCanvasPos); + } + + return null; + } + + @Override + public List pickTerminals(Point2D controlPos) { + Rectangle2D controlPickRect = new Rectangle2D.Double(controlPos.getX()-SysdynPointerInteractor.PICK_DIST, controlPos.getY()-SysdynPointerInteractor.PICK_DIST, SysdynPointerInteractor.PICK_DIST*2+1, SysdynPointerInteractor.PICK_DIST*2+1); + Shape canvasPickRect = GeometryUtils.transformShape(controlPickRect, util.getInverseTransform()); + return TerminalUtil.pickTerminals(diagram, canvasPickRect, false, true); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPopulateElementDropParticipant.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPopulateElementDropParticipant.java new file mode 100644 index 00000000..f15307c9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPopulateElementDropParticipant.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.editor.participant; + +import java.awt.dnd.DropTargetDragEvent; +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.diagram.adapter.GraphToDiagramSynchronizer; +import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.g2d.dnd.ElementClassDragItem; +import org.simantics.g2d.dnd.IDnDContext; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.ui.diagramEditor.PopulateElementDropParticipant; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; + +public class SysdynPopulateElementDropParticipant extends PopulateElementDropParticipant { + + public SysdynPopulateElementDropParticipant(GraphToDiagramSynchronizer synchronizer) { + super(synchronizer); + } + + @Override + public void dragEnter(DropTargetDragEvent dtde, IDnDContext dp) { + super.dragEnter(dtde, dp); + + // Check that user is not trying to populate a module to itself. + // This doesn't prevent infinite recursion if there is one module between two exactly the same modules. + // e.g. WorkModule -> WokrforceModule -> WorkModule creates an infinite recursion + final Collection items = dp.getItemsByClass(ElementClassDragItem.class); + if(!items.isEmpty()) { + Collection unvalidModules = null; + try { + unvalidModules = synchronizer.getSession().syncRequest(new Read>() { + + @Override + public Collection perform(ReadGraph graph) + throws DatabaseException { + Collection unvalidModules = new ArrayList(); + for(ElementClassDragItem item : items) { + StaticObjectAdapter soa = item.getElementClass().getSingleItem(StaticObjectAdapter.class); + Resource type = soa.adapt(Resource.class); + + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.isInheritedFrom(type, sr.ModuleSymbol)) { + Resource module = graph.getSingleObject(type, ModelingResources.getInstance(graph).SymbolToComponentType); + Resource configuration = graph.getSingleObject(module, StructuralResource2.getInstance(graph).IsDefinedBy); + Resource dia = graph.getSingleObject(configuration, ModelingResources.getInstance(graph).CompositeToDiagram); + Resource editorDia = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE); + if(dia.equals(editorDia)) + unvalidModules.add(item); + } + } + return unvalidModules; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + if(!unvalidModules.isEmpty()) { + for(ElementClassDragItem item : unvalidModules) { + dp.remove(item); + } + } + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynSpecialComponentCopyAdvisor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynSpecialComponentCopyAdvisor.java new file mode 100644 index 00000000..40c38350 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynSpecialComponentCopyAdvisor.java @@ -0,0 +1,44 @@ +package org.simantics.sysdyn.ui.editor.participant; + +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.synchronization.ISynchronizationContext; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ComponentUtils; + +/** + * Copy advisor for copying sysdyn elements with custom prefix and/or suffix + * @author Teemu Lempinen + * + */ +public class SysdynSpecialComponentCopyAdvisor extends SysdynComponentCopyAdvisor { + + private String prefix = ""; + private String suffix = ""; + + public SysdynSpecialComponentCopyAdvisor(String prefix, String suffix) { + this.prefix = prefix; + this.suffix = suffix; + } + + @Override + public String rename(ISynchronizationContext context, WriteGraph graph, Resource source, + Resource copy, Resource sourceContainer, Resource targetContainer) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + String copyName = NameUtils.getSafeName(graph, copy); + Resource configurationRoot = ComponentUtils.getCompositeConfigurationRoot(graph, targetContainer); + + if(prefix == null) + prefix = ""; + if(suffix == null) + suffix = ""; + + String name = NameUtils.findFreshName(graph, prefix + copyName + suffix, configurationRoot, l0.ConsistsOf, "%s%d"); + graph.claimLiteral(copy, l0.HasName, name, Bindings.STRING); + return name; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java new file mode 100644 index 00000000..bb04e70e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java @@ -0,0 +1,187 @@ +package org.simantics.sysdyn.ui.editor.routing; + +import java.awt.BasicStroke; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.Arc2D; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.g2d.routing.IConnection; +import org.simantics.g2d.routing.IConnection.Connector; +import org.simantics.g2d.routing.IRouter2; +import org.simantics.sysdyn.ui.elements.connections.Arcs; +import org.simantics.sysdyn.ui.elements.connections.DependencyEdgeClass; +import org.simantics.utils.datastructures.Triple; + +public class DependencyRouter implements IRouter2 { + + public static DependencyRouter INSTANCE = new DependencyRouter(); + + @Override + public void route(IConnection connection) { + if(connection.getSegments().isEmpty()) + return; + Object seg = connection.getSegments().iterator().next(); + Connector begin = connection.getBegin(seg); + Connector end = connection.getEnd(seg); + + Triple shapes = new Triple(new Arc2D.Double(), new Path2D.Double(), new Path2D.Double()); + createArrowShape(shapes, + begin.parentObstacle, + end.parentObstacle, + 0.1, + null); + + Path2D path = new Path2D.Double(); + path.append(shapes.first, false); + path.append(shapes.second, false); + connection.setPath(seg, path); + } + + + /* + * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2 + */ + public static double ARROW_LENGTH1 = 0.1; + public static double ARROW_LENGTH2 = 1.9; + public static double ARROW_WIDTH = 0.7; + public static double DELAYMARK_LENGTH = 6; + public static double DELAYMARK_GAP = 0.4; + + + private static Path2D createArrow(Path2D shape, double x, double y, double dx, double dy) { + if(shape == null) + shape = new Path2D.Double(); + else + shape.reset(); + + shape.moveTo(x+ARROW_LENGTH1*dx, y+ARROW_LENGTH1*dy); + x -= ARROW_LENGTH2*dx; + y -= ARROW_LENGTH2*dy; + shape.lineTo(x-ARROW_WIDTH*dy, y+ARROW_WIDTH*dx); + shape.lineTo(x+ARROW_WIDTH*dy, y-ARROW_WIDTH*dx); + shape.closePath(); + return shape; + } + + public static Arc2D createArc(Arc2D arc, Shape beginBounds, Shape endBounds, double angle) { + double x0 = beginBounds.getBounds2D().getCenterX(); + double y0 = beginBounds.getBounds2D().getCenterY(); + double x1 = endBounds.getBounds2D().getCenterX(); + double y1 = endBounds.getBounds2D().getCenterY(); + +// System.out.println("createArrowShape " + x0 + " " + y0 + " " + x1 + " " + y1); + + double offset = + Math.abs(angle) < 1.0e-6 + ? 1e3 * Math.signum(angle) + : Math.tan(Math.PI*0.5-angle)*0.5; + + double cx = 0.5*(x0+x1) + offset * (y1-y0); + double cy = 0.5*(y0+y1) + offset * (x0-x1); + double dx0 = x0 - cx; + double dy0 = y0 - cy; + double dx1 = x1 - cx; + double dy1 = y1 - cy; + + double r = Math.sqrt(dx0*dx0 + dy0*dy0); + +// Rectangle2D bounds = new Rectangle2D.Double(); +// tail.getBounds(bounds); + double angle0 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy0, dx0), beginBounds, angle < 0.0); +// head.getBounds(bounds); + double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy1, dx1), endBounds, angle > 0.0); + double extent = angle1-angle0; + //double arcAngle = angle0; + if(angle < 0.0) { + double temp = angle0; + angle0 = angle1; + angle1 = temp; + extent = -extent; + } + if(extent < 0) + extent += Math.PI*2.0; + else if(extent >= 360.0) + extent -= Math.PI*2.0; + if(arc == null) + arc = new Arc2D.Double(); + arc.setArc(cx-r, cy-r, 2*r, 2*r, + Math.toDegrees(angle0), + Math.toDegrees(extent), + Arc2D.OPEN); +// + return arc; + } + + public static Point2D computeCenter(Rectangle2D tail, Rectangle2D head, double angle) { + + double x0 = tail.getCenterX(); + double y0 = tail.getCenterY(); + double x1 = head.getCenterX(); + double y1 = head.getCenterY(); + +// System.out.println("createArrowShape " + x0 + " " + y0 + " " + x1 + " " + y1); + + double offset = + Math.abs(angle) < 1.0e-6 + ? 1e3 * Math.signum(angle) + : Math.tan(Math.PI*0.5-angle)*0.5; + + double cx = 0.5*(x0+x1) + offset * (y1-y0); + double cy = 0.5*(y0+y1) + offset * (x0-x1); + + return new Point2D.Double(cx, cy); + + } + + + public static Path2D createDelayMark(Path2D shape, double x, double y, double angle, BasicStroke stroke) { + if(shape == null) + shape = new Path2D.Double(); + else + shape.reset(); + + float strokeWidth = stroke != null ? stroke.getLineWidth() : DependencyEdgeClass.DEFAULT_STROKE_WIDTH; + + double dx = Math.cos(angle) * (DELAYMARK_LENGTH + strokeWidth) / 2; + double dy = -Math.sin(angle) * (DELAYMARK_LENGTH + strokeWidth) / 2; + double dxGap = Math.cos(angle + Math.PI / 2) * (DELAYMARK_GAP / 2 + strokeWidth); + double dyGap = -Math.sin(angle + Math.PI / 2) * (DELAYMARK_GAP / 2 + strokeWidth); + shape.moveTo(x - dx - dxGap, y - dy - dyGap); + shape.lineTo(x + dx - dxGap, y + dy - dyGap); + shape.moveTo(x - dx + dxGap, y - dy + dyGap); + shape.lineTo(x + dx + dxGap, y + dy + dyGap); + return shape; + } + + public static Triple createArrowShape(Triple shapes, Shape beginBounds, Shape endBounds, double angle, Stroke stroke) { + if(shapes == null || shapes.first == null || shapes.second == null || shapes.third == null) { + shapes = new Triple(new Arc2D.Double(), new Path2D.Double(), new Path2D.Double()); + } + createArc(shapes.first, beginBounds, endBounds, angle); + + double angle0 = Math.toRadians(shapes.first.getAngleStart()); + double angle1 = Math.toRadians(shapes.first.getAngleStart() + shapes.first.getAngleExtent()); + double x = Math.cos(angle > 0.0 ? angle1 : angle0); + double y = -Math.sin(angle > 0.0 ? angle1 : angle0); + double r = shapes.first.getHeight() / 2; + + createArrow(shapes.second, shapes.first.getCenterX() + r*x, shapes.first.getCenterY() + r*y, + angle < 0.0 ? -y : y, + angle > 0.0 ? -x : x); + + double angleCenter = Math.toRadians(shapes.first.getAngleStart() + (shapes.first.getAngleExtent() / 2)); + double arcCenterX = shapes.first.getCenterX() + r * Math.cos(angleCenter); + double arcCenterY = shapes.first.getCenterY() - r * Math.sin(angleCenter); + createDelayMark(shapes.third, arcCenterX, arcCenterY, angleCenter, + stroke instanceof BasicStroke ? (BasicStroke)stroke : null); + + return shapes; + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/FlowRouter.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/FlowRouter.java new file mode 100644 index 00000000..fc64625a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/FlowRouter.java @@ -0,0 +1,139 @@ +package org.simantics.sysdyn.ui.editor.routing; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.g2d.routing.Constants; +import org.simantics.g2d.routing.IConnection; +import org.simantics.g2d.routing.IConnection.Connector; +import org.simantics.g2d.routing.IRouter2; +import org.simantics.sysdyn.ui.elements.connections.Flows; + +public class FlowRouter implements IRouter2{ + + SysdynLocalRouter localRouter; + + public static final float OFFSET = 0.5f; + + public FlowRouter() { + this(false); + } + + public FlowRouter(boolean roundCorners) { + this.localRouter = new SysdynLocalRouter(); + } + + private Path2D route(double beginX, double beginY, int sDir, Rectangle2D beginObstacle, + double endX, double endY, int tDir, Rectangle2D endObstacle) { + localRouter.sx = beginX; + localRouter.sy = beginY; + if(beginObstacle == null) { + localRouter.aMinX = beginX; + localRouter.aMinY = beginY; + localRouter.aMaxX = beginX; + localRouter.aMaxY = beginY; + } + else { + localRouter.aMinX = beginObstacle.getMinX(); + localRouter.aMinY = beginObstacle.getMinY(); + localRouter.aMaxX = beginObstacle.getMaxX(); + localRouter.aMaxY = beginObstacle.getMaxY(); + } + localRouter.sourceDirection = sDir; + + localRouter.tx = endX; + localRouter.ty = endY; + if(endObstacle == null) { + localRouter.bMinX = endX; + localRouter.bMinY = endY; + localRouter.bMaxX = endX; + localRouter.bMaxY = endY; + } + else { + localRouter.bMinX = endObstacle.getMinX(); + localRouter.bMinY = endObstacle.getMinY(); + localRouter.bMaxX = endObstacle.getMaxX(); + localRouter.bMaxY = endObstacle.getMaxY(); + } + localRouter.targetDirection = tDir; + + // adjust flows to start and stop within the obstacle + if(sDir == Constants.EAST || sDir == Constants.WEST) { + localRouter.aMinY = localRouter.aMinY + OFFSET; + localRouter.aMaxY = localRouter.aMaxY - OFFSET; + } + if(tDir == Constants.EAST || tDir == Constants.WEST) { + localRouter.bMinY = localRouter.bMinY + OFFSET; + localRouter.bMaxY = localRouter.bMaxY - OFFSET; + } + if(sDir == Constants.SOUTH || sDir == Constants.NORTH) { + localRouter.aMinX = localRouter.aMinX + OFFSET; + localRouter.aMaxX = localRouter.aMaxX - OFFSET; + } + if(tDir == Constants.SOUTH || tDir == Constants.NORTH) { + localRouter.bMinX = localRouter.bMinX + OFFSET; + localRouter.bMaxX = localRouter.bMaxX - OFFSET; + } + + localRouter.route(); + + Path2D completePath = new Path2D.Double(); + + completePath = Flows.createOffsetPath(localRouter.path, OFFSET); + completePath.append(Flows.createOffsetPath(localRouter.path, -OFFSET), false); + + return completePath; + } + + @Override + public void route(IConnection connection) { + Collection segments = connection.getSegments(); + if(segments.size() == 1) + for(Object seg : segments) { + Connector begin = connection.getBegin(seg); + Connector end = connection.getEnd(seg); + + double bestLength = Double.POSITIVE_INFINITY; + Path2D bestPath = null; + + for(int sDir : Constants.POSSIBLE_DIRECTIONS[begin.allowedDirections]) + for(int tDir : Constants.POSSIBLE_DIRECTIONS[end.allowedDirections]) { + Path2D path = route(begin.x, begin.y, sDir, begin.parentObstacle, + end.x, end.y, tDir, end.parentObstacle); + + double length = pathCost(path); + if(length < bestLength) { + bestLength = length; + bestPath = path; + } + } + + if(bestPath != null) + connection.setPath(seg, bestPath); + } + } + + + final static AffineTransform IDENTITY = new AffineTransform(); + + static double pathCost(Path2D path) { + double length = 0.0; + PathIterator it = path.getPathIterator(IDENTITY); + double[] temp = new double[6]; + double x=0.0, y=0.0; + double bendCount = 0.0; + while(!it.isDone()) { + bendCount += 1.0; + if(it.currentSegment(temp) != PathIterator.SEG_MOVETO) + length += Math.abs(x - temp[0] + y - temp[1]); + x = temp[0]; + y = temp[1]; + it.next(); + } + return bendCount - 1.0 / length; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/SysdynLocalRouter.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/SysdynLocalRouter.java new file mode 100644 index 00000000..253e6a17 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/SysdynLocalRouter.java @@ -0,0 +1,477 @@ +package org.simantics.sysdyn.ui.editor.routing; + +import java.awt.geom.Path2D; +import java.util.ArrayList; + +import org.simantics.g2d.routing.Constants; + +public class SysdynLocalRouter { + + static final double OFFSET = 1.0; + + double aMinX; + double aMinY; + double aMaxX; + double aMaxY; + + double bMinX; + double bMinY; + double bMaxX; + double bMaxY; + + double sx; + double sy; + + double tx; + double ty; + + int sourceDirection; + int targetDirection; + + ArrayList points; + Path2D path; + + public SysdynLocalRouter() { + } + + /** + * Case where both source and target connection directions are to east. + */ + void routeEast() { + if (bMinX >= aMaxX || tx >= 0 && !(bMaxY < aMinY || aMaxY < bMinY)) { + if (ty != 0.0) { + /* ______ ______ + * | | | | + * | |----\ | | + * | | \--->| | + * |______| |______| + */ + double mx = 0.5 * (aMaxX + bMinX); + point(mx, 0.0); + point(mx, ty); + } else + ; // Just a straight line + } else { + double x0 = bMinX; + double x1 = aMaxX; + double my; + /* ______ + * | | + * | | + * /->| | + * | |______| + * | + * \-------------\ + * ______ | + * | | | + * | |-/ + * | | + * |______| + * + * If the elements are separated in Y-direction, + * route between the elements (this is always the shortest path). + */ + if (bMaxY < aMinY) + my = 0.5 * (aMinY + bMaxY); + else if (aMaxY < bMinY) + my = 0.5 * (aMaxY + bMinY); + else { + /* + * /------------------------\ + * | ______ ______ | + * | | | | | | + * | | | | |--+ + * +->| | | | | + * | |______| |______| | + * | | + * \------------------------/ + * + * or + * + * /-----------\ + * | ______ | + * | | | | + * | | | | + * /--+->| | | + * | ___|______| | + * | | | | + * | | |-+---/ + * | | | | + * | |______| | + * | | + * \----------/ + * + * We may choose either lower or upper path. + */ + double upperX0 = bMinX; + double upperX1 = aMaxX; + double lowerX0 = bMinX; + double lowerX1 = aMaxX; + double upperY = Math.min(aMinY, bMinY); + double lowerY = Math.max(aMaxY, bMaxY); + + if (aMinX < bMinX) { + if (ty < 0.5 * (aMinY + aMaxY)) + lowerX0 = aMinX; + else + upperX0 = aMinX; + } + + if (bMaxX > aMaxX) { + if (ty < 0.5 * (aMinY + aMaxY)) + upperX1 = bMaxX; + else + lowerX1 = bMaxX; + } + + double upperLength = upperX1 - upperY + (upperX1 - upperX0) + + (ty - upperY) + (tx - upperX0); + double lowerLength = lowerX1 + lowerY + (lowerX1 - lowerX0) + + (lowerY - ty) + (tx - lowerX0); + + if (upperLength < lowerLength) { + x0 = upperX0; + x1 = upperX1; + my = upperY; + } else { + x0 = lowerX0; + x1 = lowerX1; + my = lowerY; + } + } + point(x1, 0.0); + point(x1, my); + point(x0, my); + point(x0, ty); + } + } + + void routeWest() { + if (tx >= 0.0) { + double fx = Math.max(aMaxX, bMaxX); + double mx = 0.5 * (aMaxX + bMinX); + if (bMinY >= 0.0 || bMaxY <= 0.0 || mx < 0.0) { + /* ______ + * | | + * | | + * | |<-\ + * ______ |______| | + * | | | + * | |-------------------/ + * | | + * |______| + */ + point(fx, 0.0); + } + else { + /* /-------------\ + * | ______ | + * | | | | + * ______ | | | | + * | | | | |<-+ + * | |----+ |______| | + * | | | | + * |______| \-------------/ + * + * We may choose either upper or lower path + * by the path length. + */ + double my = Math.abs(bMinY) + Math.abs(ty - bMinY) < Math + .abs(bMaxY) + Math.abs(ty - bMaxY) ? bMinY : bMaxY; + point(mx, 0.0); + point(mx, my); + point(fx, my); + } + point(fx, ty); + } else { + double fx = Math.max(aMaxX, bMaxX); + double mx = 0.5 * (aMinX + bMaxX); + point(fx, 0.0); + if (ty <= aMinY || ty >= aMaxY + || (tx >= mx && ty >= aMinY && ty <= aMaxY)) { + /* ______ + * | | + * | | + * | |--\ + * ______ |______| | + * | | | + * | |<------------------/ + * | | + * |______| + */ + point(fx, ty); + } + else { + /* /-------------\ + * | ______ | + * | | | | + * ______ | | | | + * | | | | |--+ + * | |<---+ |______| | + * | | | | + * |______| \-------------/ + * + * We may choose either upper or lower path + * by the path length. + */ + double my = Math.abs(aMinY) + Math.abs(ty - aMinY) < Math + .abs(aMaxY) + Math.abs(ty - aMaxY) ? aMinY : aMaxY; + point(fx, my); + point(mx, my); + point(mx, ty); + } + } + } + + void routeSouth() { + if (tx > 0.0 && (bMinY >= 0.0 || (ty > 0.0 && bMinX <= aMaxX))) + point(tx, 0.0); + else if (bMinX > aMaxX) { + double mx = 0.5 * (aMaxX + bMinX); + point(mx, 0.0); + point(mx, bMinY); + point(tx, bMinY); + } else { + double fx = aMaxX; + double my = 0.5 * (aMaxY + bMinY); + if (my < aMaxY && (tx < aMinX || ty < aMinY)) { + my = Math.min(aMinY, bMinY); + if (bMaxX > aMaxX) + fx = bMaxX; + } + point(fx, 0.0); + point(fx, my); + point(tx, my); + } + } + + double xx, xy, yx, yy; + + void point(double x, double y) { + lineTo(x * xx + y * yx + sx, x * xy + y * yy + sy); + } + + /* + * should draw only horizontal or vertical lines. Determine the offset and + * draw both lines. + */ + void lineTo(double x, double y) { + double cx = path.getCurrentPoint().getX(); + double cy = path.getCurrentPoint().getY(); + + if (Math.abs(cx - x) < 1e-5) { + // Vertical line + if(points.size() % 2 == 0) { + points.add(points.get(points.size()-2)); + } + points.add(y); + } else if (Math.abs(cy - y) < 1e-5) { + // Horizontal line + if(points.size() % 2 != 0) { + points.add(cy); + } + points.add(x); + } + path.lineTo(x, y); + } + void rotate() { + double temp; + + temp = tx; + tx = ty; + ty = -temp; + + temp = aMinX; + aMinX = aMinY; + aMinY = -aMaxX; + aMaxX = aMaxY; + aMaxY = -temp; + + temp = bMinX; + bMinX = bMinY; + bMinY = -bMaxX; + bMaxX = bMaxY; + bMaxY = -temp; + + temp = xx; + xx = -xy; + xy = temp; + + temp = yx; + yx = -yy; + yy = temp; + + --targetDirection; + if (targetDirection < 0) + targetDirection += 4; + --sourceDirection; + } + + void flip() { + double temp; + + ty = -ty; + + temp = aMinY; + aMinY = -aMaxY; + aMaxY = -temp; + + temp = bMinY; + bMinY = -bMaxY; + bMaxY = -temp; + + yx = -yx; + yy = -yy; + + targetDirection = (targetDirection + 2) % 4; + } + + /* + * Puts source terminal to origo and rotates the situation so that the + * connection leaves to east. Finally, the case where target direction is to + * south is eliminated by optionally flipping the situation. + */ + void canonicalize() { + aMinX -= sx; + aMinY -= sy; + aMaxX -= sx; + aMaxY -= sy; + bMinX -= sx; + bMinY -= sy; + bMaxX -= sx; + bMaxY -= sy; + tx -= sx; + ty -= sy; + xx = yy = 1.0; + xy = yx = 0.0; + while (sourceDirection > 0) + rotate(); + + if (targetDirection == Constants.SOUTH) + flip(); + } + + public void route() { + /* + * Three cases: 1. Obstacles share X-axis at some point 2. Obstacles + * share Y-Axis at some point 3. Obstacles don't share axis => Have to + * make corners. + */ +// if ( +// aMinX > bMinX && aMinX < bMaxX || +// aMaxX > bMinX && aMaxX < bMaxX || +// aMinX < bMinX && aMaxX > bMaxX) { +// // Obstacles share x-axis => no corner +// double minX = aMinX > bMinX ? aMinX : bMinX; +// double maxX = aMaxX < bMaxX ? aMaxX : bMaxX; +// double middle = minX + (maxX - minX) / 2; +// sx = middle; +// tx = middle; +// if (sy > ty) { +// sy = aMinY; +// ty = bMaxY; +// } else { +// sy = aMaxY; +// ty = bMinY; +// } +// } else if ( +// aMinY > bMinY && aMinY < bMaxY || +// aMaxY > bMinY && aMaxY < bMaxY || +// aMinY < bMinY && aMaxY > bMaxY) { +// // Obstacles share y-axis => no corner +// double minY = aMinY > bMinY ? aMinY : bMinY; +// double maxY = aMaxY < bMaxY ? aMaxY : bMaxY; +// double middle = minY + (maxY - minY) / 2; +// sy = middle; +// ty = middle; +// if (sx > tx) { +// sx = aMinX; +// tx = bMaxX; +// } else { +// sx = aMaxX; +// tx = bMinX; +// } +// } else { + sx = aMinX + (aMaxX - aMinX) / 2; + sy = aMinY + (aMaxY - aMinY) / 2; + tx = bMinX + (bMaxX - bMinX) / 2; + ty = bMinY + (bMaxY - bMinY) / 2; + // Move starting point to the edge of the start element + switch (sourceDirection) { + case Constants.WEST: + sx = aMinX; + break; + case Constants.EAST: + sx = aMaxX; + break; + case Constants.NORTH: + sy = aMinY; + break; + case Constants.SOUTH: + sy = aMaxY; + break; + } + + // Move target point to the edge of the ending element + switch (targetDirection) { + case Constants.EAST: + tx = bMaxX; + break; + case Constants.WEST: + tx = bMinX; + break; + case Constants.NORTH: + ty = bMinY; + break; + case Constants.SOUTH: + ty = bMaxY; + break; + } +// } + + path = new Path2D.Double(); + points = new ArrayList(); + + path.moveTo(sx, sy); + points.add(sx); + points.add(sy); + + // Vertical and horizontal cases + if ((Math.abs(sx - tx) < 1e-5 && isVertical()) + || (Math.abs(sy - ty) < 1e-5 && isHorizontal())) { + lineTo(tx, ty); + return; + } + + + canonicalize(); + switch (targetDirection) { + case Constants.EAST: + routeWest(); + break; + case Constants.WEST: + routeEast(); + break; + case Constants.NORTH: + routeSouth(); + break; + } + + point(tx, ty); + + } + + private boolean isVertical() { + return + (sourceDirection == Constants.SOUTH && targetDirection == Constants.SOUTH) + || + (sourceDirection == Constants.NORTH && targetDirection == Constants.NORTH); + } + + private boolean isHorizontal() { + return + (sourceDirection == Constants.EAST && targetDirection == Constants.EAST) + || + (sourceDirection == Constants.WEST && targetDirection == Constants.WEST); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryFactory.java new file mode 100644 index 00000000..ab3bbd30 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryFactory.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.geom.Ellipse2D; +import java.util.Collection; + +import org.simantics.db.Resource; +import org.simantics.diagram.elements.ResizeRectangularSceneGraph; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.handler.impl.BoundsOutline; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.OutlinePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; +import org.simantics.g2d.utils.Alignment; + +/** + * @author Tuukka Lehtonen + */ +public class AuxiliaryFactory extends SysdynElementFactory { + + public static final Image AUX_STATIC_IMAGE = new ShapeImage(new Ellipse2D.Double(-5, -2, 10, 4), null, new BasicStroke(1), true); + + @Override + protected ElementClass compileElementClass(Resource elementType, Collection terminals) { + return ElementClass.compile( + SimpleElementLayers.INSTANCE, + OutlinePick.INSTANCE, + TextImpl.INSTANCE, + TextColorImpl.BLACK, + TextFontImpl.DEFAULT, + DefaultTransform.INSTANCE, + new StaticObjectAdapter(elementType), + new StaticSymbolImpl(AUX_STATIC_IMAGE), + StaticSymbolImageInitializer.INSTANCE, + new SysdynTextElementHandler(0, 0, Alignment.CENTER, 0, 1.5, 1.5, true), + BoundsOutline.INSTANCE, + ResizeRectangularSceneGraph.INSTANCE, + RESIZE_PROPERTY_SETTER, + new WholeElementTerminals(terminals) + ).setId(AuxiliaryFactory.class.getSimpleName()); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/BorderSceneGraph.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/BorderSceneGraph.java new file mode 100644 index 00000000..2126e9c3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/BorderSceneGraph.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.geom.AffineTransform; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.SceneGraphNodeKey; +import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.datastructures.hints.IHintContext.Key; + +public class BorderSceneGraph implements SceneGraph, Callback { + + public static final BorderSceneGraph INSTANCE = new BorderSceneGraph(); + + private static final long serialVersionUID = 5544256245734478634L; + + private static final Key BORDER_NODE = new SceneGraphNodeKey(RectangleNode.class, "BORDER_NODE"); + + @Override + public void init(IElement e, G2DParentNode parent) { + RectangleNode node = ElementUtils.getOrCreateNode(e, parent, BORDER_NODE, "border", RectangleNode.class, this); + + // Calculate borders from text node bounds. + node.init(ElementUtils.getElementBounds(e)); + AffineTransform transform = ElementUtils.getTransform(e); + if(transform != null) + node.setTransform(transform); + } + + @Override + public void run(RectangleNode node) { + node.setZIndex(-10); + } + + @Override + public void cleanup(IElement e) { + ElementUtils.removePossibleNode(e, BORDER_NODE); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/CloudFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/CloudFactory.java new file mode 100644 index 00000000..64895012 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/CloudFactory.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.SceneGraphNodeKey; +import org.simantics.g2d.element.handler.HandleMouseEvent; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.g2d.element.handler.impl.BorderColorImpl; +import org.simantics.g2d.element.handler.impl.BoundsOutline; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.HoverImpl; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.OutlinePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.events.MouseEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent; +import org.simantics.scenegraph.g2d.nodes.ShapeNode; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintListener; +import org.simantics.utils.datastructures.hints.IHintObservable; + +public class CloudFactory extends SysdynElementFactory { + + public static final double CLOUD_SIZE_X = 2.5; + public static final double CLOUD_SIZE_Y = 1.7; + public static final double CLOUD_CURVES = 7; + + private static final BasicStroke STROKE = new BasicStroke(1f); + public static final Image CLOUD_IMAGE = new ShapeImage(getCloudShape(), null, STROKE, true); + + static Shape getCloudShape() { + Path2D path = new Path2D.Double(); + double ox = CLOUD_SIZE_X; + double oy = 0.0; + double posX = 0; + double posY = 0; + path.moveTo(posX + ox, posY + oy); + for (int i = 1; i < CLOUD_CURVES + 1; ++i) { + double angle = (Math.PI * 2.0 / CLOUD_CURVES) * i; + double x = Math.cos(angle) * CLOUD_SIZE_X; + double y = Math.sin(angle) * CLOUD_SIZE_Y; + path.curveTo( + posX + (2*ox + x)*0.5, posY + (2*oy + y)*0.5, + posX + (ox + 2*x)*0.5, posY + (oy + 2*y)*0.5, + posX + x, posY + y); + ox = x; + oy = y; + } + return path; + } + + public static ElementClass createElementClass(Resource elementType, Collection terminals) { + return ElementClass.compile( + SimpleElementLayers.INSTANCE, + OutlinePick.INSTANCE, + TextImpl.INSTANCE, + TextColorImpl.BLACK, + TextFontImpl.DEFAULT, + DefaultTransform.INSTANCE, + new StaticObjectAdapter(elementType), + new StaticSymbolImpl(CLOUD_IMAGE), + StaticSymbolImageInitializer.INSTANCE, + CloudSceneGraph.INSTANCE, + HoverImpl.INSTANCE, + BoundsOutline.INSTANCE, + new BorderColorImpl(Color.BLACK), + new WholeElementTerminals(terminals) + ).setId(CloudFactory.class.getSimpleName()); + } + + @Override + public void load(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource element, IElement e) + throws DatabaseException { + super.load(graph, canvas, diagram, element, e); + e.setHint(ElementHints.KEY_BORDER_COLOR, e.getHint(ElementHints.KEY_TEXT_COLOR)); + } + + @Override + protected ElementClass compileElementClass(Resource elementType, Collection terminals) { + return createElementClass(elementType, terminals); + } + + public static class CloudSceneGraph implements SceneGraph, InternalSize, HandleMouseEvent { + + private static final long serialVersionUID = 5544256245734478634L; + + public static final CloudSceneGraph INSTANCE = new CloudSceneGraph(); + + private static final Key NODE = new SceneGraphNodeKey(ShapeNode.class, "CLOUD_NODE"); + + private IHintListener hoverHintListener; + + @Override + public void init(IElement e, G2DParentNode parent) { + + HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "cloud", HoverShapeNode.class); + + AffineTransform at = ElementUtils.getTransform(e); + + node.setStroke(STROKE); + node.setScaleStroke(true); + node.setColor(ElementUtils.getBorderColor(e, Color.BLACK)); + node.setShape(getCloudShape()); + + if(at != null) + node.setTransform(at); + + hoverHintListener = new IHintListener() { + + @Override + public void hintRemoved(IHintObservable sender, Key key, Object oldValue) { + + } + + @Override + public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { + IElement e = (IElement)sender; + HoverShapeNode shape = (HoverShapeNode) e.getHint(NODE); + if(shape == null) { + return; + } + shape.setHover(ElementUtils.isHovering(e)); + } + }; + e.addHintListener(hoverHintListener); + } + + @Override + public void cleanup(IElement e) { + e.removeHintListener(hoverHintListener); + ElementUtils.removePossibleNode(e, NODE); + } + + @Override + public Rectangle2D getBounds(IElement e, Rectangle2D size) { + if (size == null) + size = new Rectangle2D.Double(); + size.setFrame(CLOUD_IMAGE.getBounds()); + return size; + } + + @Override + public boolean handleMouseEvent(IElement e, ICanvasContext ctx, MouseEvent me) { + if (me instanceof MouseEnterEvent) { + e.setHint(ElementHints.KEY_HOVER, true); + return false; + } else if (me instanceof MouseExitEvent) { + e.setHint(ElementHints.KEY_HOVER, false); + return false; + } + return false; + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ComponentNameSynchronizer.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ComponentNameSynchronizer.java new file mode 100644 index 00000000..0e47ca9b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ComponentNameSynchronizer.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.synchronization.IModificationQueue; +import org.simantics.diagram.synchronization.ISynchronizationContext; +import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints; +import org.simantics.diagram.synchronization.graph.RelatedPropertyModification; +import org.simantics.diagram.synchronization.graph.ResourceSynchronizer; +import org.simantics.g2d.element.ElementHints; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintObservable; + +/** + * @author Tuukka Lehtonen + */ +public class ComponentNameSynchronizer extends ResourceSynchronizer { + + public static final ComponentNameSynchronizer INSTANCE = new ComponentNameSynchronizer(); + + private static final Key[] SYNCHRONIZED_HINTS = { + ElementHints.KEY_TEXT + }; + + @Override + public Key[] getSynchronizedHints() { + return SYNCHRONIZED_HINTS; + } + + @Override + public boolean hintChanged(ISynchronizationContext context, IModificationQueue queue, Resource object, IHintObservable sender, Key key, Object oldValue, Object newValue) { + if (ElementHints.KEY_TEXT.equals(key)) { + Session session = context.get(GraphSynchronizationHints.SESSION); + Layer0 l0; + try { + l0 = Layer0.getInstance(session); + ModelingResources mr = session.getService(ModelingResources.class); + return queue.offer(new RelatedPropertyModification(object, mr.ElementToComponent, l0.HasName, l0.String, newValue, Bindings.STRING), null); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + return false; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ConfigurationDiagramClassAdapter.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ConfigurationDiagramClassAdapter.java new file mode 100644 index 00000000..e562ff35 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ConfigurationDiagramClassAdapter.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.adaption.ResourceAdapter; +import org.simantics.db.procedure.AsyncProcedure; +import org.simantics.diagram.adapter.DiagramClassAdapter; +import org.simantics.g2d.diagram.DiagramClass; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.handler.LifeCycle; +import org.simantics.g2d.routing.RouterFactory; + +/** + * @author Tuukka Lehtonen + */ +public class ConfigurationDiagramClassAdapter implements ResourceAdapter { + + @Override + public void adapt(AsyncReadGraph g, Resource source, Resource r, AsyncProcedure procedure) { + procedure.execute(g, DiagramClassAdapter.INSTANCE.newClassWith( + Initializer.INSTANCE + )); + } + + static class Initializer extends LifeCycle.Stub { + public static final Initializer INSTANCE = new Initializer(); + + @Override + public void onDiagramCreated(IDiagram diagram) { + diagram.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(false, false)); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverShapeNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverShapeNode.java new file mode 100644 index 00000000..3cc5b2ff --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverShapeNode.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.Stroke; + +import org.simantics.scenegraph.ISelectionPainterNode; +import org.simantics.scenegraph.g2d.nodes.ShapeNode; +import org.simantics.scenegraph.utils.NodeUtil; + +public class HoverShapeNode extends ShapeNode implements ISelectionPainterNode { + + private static final long serialVersionUID = -4580969977763722602L; + + transient public boolean hover = false; + + @Override + protected void renderShape(Graphics2D g2d, Shape s) { + boolean fill = Boolean.TRUE.equals(dynamicFill) ? true : this.fill; + if (fill) + g2d.fill(s); + + Color oldColor = g2d.getColor(); + BasicStroke oldStroke = (BasicStroke)g2d.getStroke(); + Composite oldComposite = g2d.getComposite(); + + boolean selected = NodeUtil.isSelected(this, 1); + if (selected) { + float lineWidth = oldStroke.getLineWidth() * 5; + g2d.setStroke(new BasicStroke(lineWidth < 1.0f ? lineWidth : 1.0f)); + g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); + g2d.setColor(Color.RED); + g2d.draw(s); + g2d.setColor(oldColor); + } + + if(!selected && hover) { + g2d.setColor(Color.LIGHT_GRAY); + float lineWidth = oldStroke.getLineWidth() * 5; + g2d.setStroke(new BasicStroke(lineWidth < 1.0f ? lineWidth : 1.0f)); + g2d.draw(s); + + } + + g2d.setColor(oldColor); + g2d.setStroke(oldStroke); + g2d.setComposite(oldComposite); + + Stroke stroke = dynamicStroke != null ? dynamicStroke : this.stroke; + if (stroke != null) + g2d.draw(s); + + } + + public void setHover(boolean hover) { + this.hover = hover; + repaint(); + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Input.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Input.java new file mode 100644 index 00000000..54f83d4c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Input.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.ElementHandler; + +public class Input implements ElementHandler { + + private static final long serialVersionUID = -1526125969376635502L; + + public static final Input INSTANCE = new Input(); + + public String getInputReference(IElement e) { + return e.getHint(SysdynElementHints.KEY_INPUT_REFERENCE); + } + + + public void setInputReference(IElement e, String inputReference) { + if (inputReference != null) + e.setHint(SysdynElementHints.KEY_INPUT_REFERENCE, inputReference); + else + e.removeHint(SysdynElementHints.KEY_INPUT_REFERENCE); + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/InputFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/InputFactory.java new file mode 100644 index 00000000..b19f43da --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/InputFactory.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.diagram.elements.ResizeRectangularSceneGraph; +import org.simantics.diagram.elements.TextNode; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.SceneGraphNodeKey; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.impl.BoundsOutline; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.OutlinePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; +import org.simantics.g2d.utils.Alignment; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.datastructures.hints.IHintContext.Key; + +public class InputFactory extends SysdynElementFactory { + + private static final BasicStroke STROKE = new BasicStroke(1f); + public static final Image INPUT_IMAGE = new ShapeImage(getInputShape(), null, STROKE, true); + + static Shape getInputShape() { + Path2D path = new Path2D.Double(); + path.moveTo(-6, -1); + path.lineTo(-1, -1); + path.lineTo(-1, -2.5); + path.lineTo(1.5, 0); + path.curveTo(1.5, -2.5, 6.5, -2.5, 6.5, 0); + path.curveTo(6.5, 2.5, 1.5, 2.5, 1.5, 0); + path.lineTo(-1, 2.5); + path.lineTo(-1, 1); + path.lineTo(-6, 1); + path.closePath(); + return path; + } + + @Override + protected ElementClass compileElementClass(Resource elementType, Collection terminals) { + return ElementClass.compile( + SimpleElementLayers.INSTANCE, + OutlinePick.INSTANCE, + TextImpl.INSTANCE, + TextColorImpl.BLACK, + TextFontImpl.DEFAULT, + DefaultTransform.INSTANCE, + new StaticObjectAdapter(elementType), + new StaticSymbolImpl(INPUT_IMAGE), + StaticSymbolImageInitializer.INSTANCE, + Input.INSTANCE, + new InputSceneGraph(0, 0, Alignment.CENTER, 0, 1.5, 1.5, true), + BoundsOutline.INSTANCE, + ResizeRectangularSceneGraph.INSTANCE, + RESIZE_PROPERTY_SETTER, + new WholeElementTerminals(terminals) + ).setId(InputFactory.class.getSimpleName()); + } + + @Override + public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException { + super.load(graph, canvas, diagram, element, e); + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Resource component = null; + Resource dependency = null; + Resource refersTo = null; + Resource module = null; + String moduleName = ""; + String referenceName = ""; + component = graph.getPossibleObject(element, mr.ElementToComponent); + if(component != null) + dependency = graph.getPossibleObject(component, sr.Variable_isHeadOf); + if(dependency != null) { + refersTo = graph.getPossibleObject(dependency, sr.Dependency_refersTo); + if(refersTo != null) { + referenceName = (String) graph.getPossibleRelatedValue(refersTo, l0.HasName); + module = graph.getPossibleObject(dependency, sr.Variable_HasTail); + moduleName = (String) graph.getPossibleRelatedValue(module, l0.HasName); + } + } else { + Resource runtime = diagram.getHint((DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE)); + DiagramResource dr = DiagramResource.getInstance(graph); + String variable = (String)graph.getPossibleRelatedValue(runtime, dr.RuntimeDiagram_HasVariable); + if(variable == null) + return; + + + try { + Variable v = Variables.getVariable(graph, variable); + if(v != null) { + module = v.getRepresents(graph); + } + if(module != null) + for(Resource dep : graph.getObjects(module, sr.Variable_isHeadOf)) { + Resource reference = graph.getPossibleObject(dep, sr.Dependency_refersTo); + if(reference!= null && reference.equals(component)) { + refersTo = graph.getSingleObject(dep, sr.Variable_HasTail); + referenceName = (String) graph.getPossibleRelatedValue(refersTo, l0.HasName); + Variable parent = null; + parent = v.getParent(graph); + Resource represents = parent.getRepresents(graph); + if(parent != null && !graph.isInstanceOf(represents, sr.Configuration) && !graph.isInstanceOf(represents, sr.Experiment_Run)) { + moduleName = parent.getName(graph); + } + break; + } + } + } catch (MissingVariableException mve) { + // DO nothing. + } + } + + String inputReference = null; + if (moduleName != null && refersTo != null) { + inputReference = moduleName + "." + referenceName; + } + if (inputReference == null) { + inputReference = ""; + } + + SysdynElementUtils.setInputReference(e, inputReference); + + Font font = ElementUtils.getTextFont(e); + font = font.deriveFont(font.getStyle()); + ElementUtils.setTextFont(e, font); + } + + + public static class InputSceneGraph extends SysdynTextElementNoBounds implements InternalSize { + + private static final long serialVersionUID = -3713275157729126409L; + public static final Key INPUT_SG_NODE = new SceneGraphNodeKey(TextNode.class, "INPUT_SG_NODE"); + + private final double originX; + private final Alignment horizontalAlignment; + + public InputSceneGraph(double originX, double originY, Alignment horizontalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable) { + super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable); + this.originX = originX; + this.horizontalAlignment = horizontalAlignment; + } + + @Override + public void init(final IElement e, G2DParentNode parent) { + super.init(e, parent); + TextNode node = ElementUtils.getOrCreateNode(e, parent, INPUT_SG_NODE, "input", TextNode.class); + Font font = ElementUtils.getTextFont(e); + font = font.deriveFont((float) 10.0); +// font = font.deriveFont(Font.ITALIC); + Color color = new Color(150, 150, 150); + Color fillColor = ElementUtils.getFillColor(e); + Color borderColor = ElementUtils.getBorderColor(e, Color.BLACK); + String text = SysdynElementUtils.getInputReference(e); + double scale = 0.235; + AffineTransform at = ElementUtils.getTransform(e); + node.init(text, font, color, originX, originY, scale); + node.setBackgroundColor(fillColor); + node.setBorderColor(borderColor); + node.setHorizontalAlignment((byte) horizontalAlignment.ordinal()); + node.setBorderWidth((float) 0); + node.setEditable(false); + node.setShowSelection(false); + + if(at != null) { + node.setTransform(at); + // Use affinetransform to move the name of the valve below the valve symbol + AffineTransform at2 = (AffineTransform) at.clone(); + at2.translate(0, font.getSize2D() * scale); + node.setTransform(at2); + } + + unflipText(e); + } + + @Override + public Rectangle2D getBounds(IElement e, Rectangle2D size) { + TextNode name = (TextNode) e.getHint(SG_NODE); + TextNode reference = (TextNode) e.getHint(INPUT_SG_NODE); + if (size == null) + size = new Rectangle2D.Double(); + if (name != null) + size.setRect(name.getBoundsInLocal()); + + if(reference != null) { + /* Only the main text box as bounds + if (reference.getBoundsInLocal().getWidth() > size.getWidth()) + size.setRect(size.getX(), size.getY(), reference.getBoundsInLocal().getWidth(), size.getHeight()); + */ + } + else + size.setFrame(0, 0, 0, 0); + return size; + } + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopClockwise.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopClockwise.java new file mode 100644 index 00000000..19cf4487 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopClockwise.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.ElementHandler; + +public class LoopClockwise implements ElementHandler { + + private static final long serialVersionUID = -5104770127548577905L; + + public static final LoopClockwise INSTANCE = new LoopClockwise(); + + public String getTextLocation(IElement e) { + return e.getHint(SysdynElementHints.KEY_LOOP_CLOCKWISE); + } + + + public void setTextLocation(IElement e, Boolean clockwise) { + if (clockwise != null) + e.setHint(SysdynElementHints.KEY_LOOP_CLOCKWISE, clockwise); + else + e.removeHint(SysdynElementHints.KEY_LOOP_CLOCKWISE); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopFactory.java new file mode 100644 index 00000000..0b83ef3f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopFactory.java @@ -0,0 +1,377 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Paint; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.awt.geom.RectangularShape; +import java.util.Collection; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.elements.ITextListener; +import org.simantics.diagram.elements.TextNode; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.DiagramUtils; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.SceneGraphNodeKey; +import org.simantics.g2d.element.handler.HandleMouseEvent; +import org.simantics.g2d.element.handler.impl.BoundsOutline; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.HoverImpl; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.OutlinePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.elementclass.ImageClass.StaticImageElementHandler; +import org.simantics.g2d.image.DefaultImages; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; +import org.simantics.g2d.svg.SVGImage; +import org.simantics.g2d.utils.Alignment; +import org.simantics.modeling.ModelingResources; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.nodes.SVGNode; +import org.simantics.scenegraph.g2d.nodes.ShapeNode; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.LoopTab; +import org.simantics.sysdyn.utils.LoopUtils; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintListener; +import org.simantics.utils.datastructures.hints.IHintObservable; + +/** + * Factory for loops. + * + * @author Tuomas Miettinen + */ +public class LoopFactory extends SysdynElementFactory { + + public static final Image LOOP_STATIC_IMAGE = new ShapeImage(getLoopShape(), null, new BasicStroke(1), true); + private static Image image = null; + + @Override + public ElementClass create(ReadGraph graph, ICanvasContext canvas, + IDiagram diagram, Resource elementType) throws DatabaseException { + + // Create the loop symbol svg image + G2DResource g2d = G2DResource.getInstance(graph); + String svgDoc = graph.getPossibleRelatedValue(elementType, g2d.HasSVGDocument); + String id = "TextElement: " + NameUtils.getSafeName(graph, elementType); + if (svgDoc != null) + image = new SVGImage(id+".svg", svgDoc); + else + image = DefaultImages.ERROR_DECORATOR.get(); + + return ElementClass.compile( + SimpleElementLayers.INSTANCE, + OutlinePick.INSTANCE, + TextImpl.INSTANCE, + TextColorImpl.BLACK, + TextFontImpl.DEFAULT, + DefaultTransform.INSTANCE, + new StaticObjectAdapter(elementType), + new StaticSymbolImpl(image), + StaticSymbolImageInitializer.INSTANCE, + LoopSceneGraph.INSTANCE, + new LoopImageSceneGraph(image), + HoverImpl.INSTANCE, + BoundsOutline.INSTANCE, + LoopClockwise.INSTANCE + ).setId(LoopFactory.class.getSimpleName()); + } + + static Shape getLoopShape() { + // Used in shortcut. + Path2D loop = new Path2D.Double(); + loop.moveTo(1, 2); + loop.lineTo(0, 0); + loop.lineTo(-1, 2); + loop.closePath(); + + loop.append(new Arc2D.Double(-10, -3, 10, 10, 0, -270, Arc2D.OPEN), false); + return loop; + } + + @Override + protected String getText(ReadGraph graph, Resource element) throws DatabaseException { + // Get loop comment instead of loop name. + SysdynResource sr = SysdynResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + Resource component = graph.getPossibleObject(element, mr.ElementToComponent); + String text = null; + if (component != null) { + text = (String) graph.getPossibleRelatedValue(component, sr.Loop_Comment); + } + if (text == null) + text = ""; + else if (LoopTab.AUTO.equals(text)) { + switch (LoopUtils.getLoopType(graph, component)) { + case BALANCING: + text = "B"; + break; + case REINFORCING: + text = "R"; + break; + default: + text = ""; + } + } + return text; + } + + @Override + protected ElementClass compileElementClass(Resource elementType, + Collection terminals) { + return null; + } + + @Override + public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException { + super.load(graph, canvas, diagram, element, e); + SysdynResource sr = SysdynResource.getInstance(graph); + Boolean clockwise = graph.getPossibleRelatedValue(element, sr.LoopSymbol_Clockwise, Bindings.BOOLEAN); + if(clockwise == null) { + clockwise = Boolean.TRUE; + } + SysdynElementUtils.setLoopClockwise(e, clockwise); + } + + + + /** + * Handling for the loop image on diagram. + * @author Tuomas Miettinen + * + */ + public static class LoopImageSceneGraph extends StaticImageElementHandler { + + private static final long serialVersionUID = -185893525553743589L; + + private IHintListener hoverHintListener; + + private static final Key NODE = new SceneGraphNodeKey(LoopNode.class, "LOOP_NODE"); + + public LoopImageSceneGraph(Image i) { + super(i); + } + + @Override + public void init(IElement e, G2DParentNode parent) { + super.init(e, parent); + + // Create new hover shape node for the loop image + final LoopNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "loopHover", LoopNode.class); + + // Mirror the image if clockwise is selected. + Boolean clockwise = e.getHint(SysdynElementHints.KEY_LOOP_CLOCKWISE); + SVGNode image = e.getHint(getNodeKey()); + if (clockwise != null && clockwise) { + Point2D imageParent = (Point2D) image.localToParent(new Point2D.Double(0.0,0.0)).clone(); + AffineTransform at = new AffineTransform(-1.0, 0.0, 0.0, 1.0, imageParent.getX(), imageParent.getY()); + image.setTransform(at); + } + + // Set the shape of the shape node to match the shape of the image + RectangularShape bounds = (RectangularShape)image.getBounds().clone(); + node.setShape(bounds); + + // Set the shape node transparent + Paint paint = new Color(0,0,0,0); + node.setColor(paint); + + // Handle hover + Boolean hover = e.getHint(ElementHints.KEY_HOVER); + node.setHover(hover != null ? hover : false); + hoverHintListener = new IHintListener() { + + @Override + public void hintRemoved(IHintObservable sender, Key key, Object oldValue) { + } + + @Override + public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { + IElement e = (IElement)sender; + LoopNode shape = (LoopNode) e.getHint(NODE); + if(shape == null) { + return; + } + boolean hover = ElementUtils.isHovering(e); + shape.setHover(hover); + } + }; + e.addHintListener(hoverHintListener); + } + + @Override + public void cleanup(IElement e) { + super.cleanup(e); + e.removeHintListener(hoverHintListener); + } + } + + /** + * Handling for the text box of loop in diagram. + * @author Tuomas Miettinen + * + */ + public static class LoopSceneGraph extends SysdynTextElementNoBounds implements HandleMouseEvent { + + private static final long serialVersionUID = -5093461687773246286L; + + public static final LoopSceneGraph INSTANCE = new LoopSceneGraph(); + + private static final Key NODE = new SceneGraphNodeKey(ShapeNode.class, "LOOP_COMMENT_NODE"); + + public LoopSceneGraph() { + super(0, 0, Alignment.CENTER, 0, 1, 1, true); + } + + @Override + public void init(IElement e, G2DParentNode parent) { + super.init(e, parent); + + // Move the text box into (around) the middle of the loop image + AffineTransform at = ElementUtils.getTransform(e); + final LoopNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "loopComment", LoopNode.class); + + // Unflip the text and image + unflipText(e); + + if(at != null) { + node.setTransform(at); + + TextNode name = (TextNode) e.getHint(SG_NODE); + if(name != null) { + AffineTransform at2 = (AffineTransform) at.clone(); + at2.translate(getXCoordShift(e), getYCoordShift(e)); + + Alignment alignment = Alignment.CENTER; + + name.setTransform(at2); + if(alignment != null) + name.setHorizontalAlignment((byte) alignment.ordinal()); + } + } + } + + private static double getXCoordShift(IElement e) { + //String location = e.getHint(SysdynElementHints.KEY_LOCATION); + return 0; + } + + private static double getYCoordShift(IElement e) { + //String location = e.getHint(SysdynElementHints.KEY_LOCATION); + return 10.7; + } + + @Override + protected Callback getCallback(final IElement e, G2DParentNode parent, Class nodeClass) { + return new Callback() { + @Override + public void run(T node) { + node.setTextListener(new ITextListener() { + + Resource component; + + @Override + public void textChanged() { + } + + @Override + public void textEditingStarted() { + if(component != null) return; + + Object o = e.getHint(ElementHints.KEY_OBJECT); + if(o != null && o instanceof Resource) { + final Resource element = (Resource)o; + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + component = graph.getPossibleObject(element, ModelingResources.getInstance(graph).ElementToComponent); + } + }); + } + } + + @Override + public void textEditingCancelled() { + TextNode node = (TextNode) e.getHint(SG_NODE); + if (node != null) { + endEdit(node); + } + } + + @Override + public void textEditingEnded() { + TextNode node = (TextNode) e.getHint(SG_NODE); + if (node == null) + return; + + // Write the changed comment of the loop + final String text = node.getText(); + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) + throws DatabaseException { + if (component != null) { + SysdynResource sr = SysdynResource.getInstance(graph); + graph.deny(component, sr.Loop_Comment); + graph.claimLiteral(component, sr.Loop_Comment, text); + } + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + IDiagram diagram = ElementUtils.getDiagram(e); + DiagramUtils.synchronizeHintsToBackend(diagram, e); + endEdit(node); + } + }); + } + }; + } + + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopNode.java new file mode 100644 index 00000000..11c9c71f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopNode.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.diagram.elements.DiagramNodeUtil; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.modeling.ModelingResources; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.ParentNode; +import org.simantics.scenegraph.g2d.IG2DNode; +import org.simantics.scenegraph.g2d.nodes.ConnectionNode; +import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +/** + * Node for Sysdyn loop elements. + * + * @author Tuomas Miettinen + * + */ +public class LoopNode extends HoverShapeNode { + + /** + * Interface for nodes that can be part of loops + * @author Tuomas Miettinen + * + */ + public interface ILoopComponentNode { + + /** + * Sets or resets the loop selected status + * @param loop The loop which has been selected + * @param selected true iff the loop is selected + */ + public void setLoopSelected(LoopNode loop, boolean selected); + + } + + public static Color HIGHLIGHT_COLOR = Color.decode("#ff5fbf"); + + private boolean selected = false; + + private static final long serialVersionUID = 6173159124691715569L; + + @Override + public void render(Graphics2D g2d) { + super.render(g2d); + + // If the loop is selected, highlight also the elements that belong to the loop. + boolean selected = NodeUtil.isSelected(this, 1); + // Do nothing if the selection is and was off. + if (selected || this.selected != selected) { + this.selected = selected; + // Tell all items belonging to the loop that the loop is selected. + setLoopItemsSelected(); + } + } + + private void setLoopItemsSelected() { + // Get all variables and dependencies in the loop. + List loopItems = getAllLoopItems(); + + // Get the diagram where this loop is. + RTreeNode diagramNode = (RTreeNode)NodeUtil.getNearestParentOfType(this, RTreeNode.class); + if (diagramNode == null) + return; + + // Go through all elements on the diagram where this loop is. + Collection children = diagramNode.getNodes(); + Iterator it = children.iterator(); + while (it.hasNext()) { + IG2DNode n = it.next(); + + // Get the respective node + INode child = getNodeOfPossibleLoopComponentNode(n); + if (child instanceof ILoopComponentNode) { + ILoopComponentNode ln = (ILoopComponentNode)child; + // Get the respective element + IElement e = DiagramNodeUtil.getElement((IG2DNode)child.getParent()); + // Get the respective resource + Resource r = e.getHint(ElementHints.KEY_OBJECT); + // If the node belongs to the loop, tell it that whether the loop is selected or not. + ln.setLoopSelected(this, NodeUtil.isSelected(this, 1) && loopItems.contains(r)); + } + } + } + + /** + * Get the ILoopComponentNode under the variable, dependency, or flow. + * @param n node under which the ILoopComponentNode is sought + * @return ILoopComponentNode or null, if there is not any. + */ + private static INode getNodeOfPossibleLoopComponentNode(IG2DNode n) { + // Get all nodeIds of n's children. + Collection nodeIds = ((ParentNode)n).getNodeIds(); + + // Flows and SysdynTextNodes + for (String id : nodeIds) { + if ("text".equals(id) + || id.startsWith("flow_")) + return ((ParentNode)n).getNode(id); + } + + // Dependencies + if (n instanceof ConnectionNode) { + // See the first (and only) child of n has a DependencyNode as a child. + n = ((ConnectionNode) n).getNodes().iterator().next(); + if (n instanceof ParentNode) { + nodeIds = ((ParentNode)n).getNodeIds(); + for (String id : nodeIds) { + if (id.startsWith("edge_")) + return ((ParentNode)n).getNode(id); + } + } + } + + return null; // n was no variable, dependency, or flow + + } + + /** + * Get all variables and dependencies in the loop. + * @return A list where the items are, in unspecified order. + */ + private List getAllLoopItems() { + IElement loopElement = DiagramNodeUtil.getElement(this); + final Resource loopSymbolResource = loopElement.getHint(ElementHints.KEY_OBJECT); + List loopItems = Collections.emptyList(); + + try { + loopItems = SimanticsUI.getSession().syncRequest(new Read>(){ + + @Override + public List perform(ReadGraph graph) throws DatabaseException { + ModelingResources mod = ModelingResources.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Resource loopComponentResource = graph.getPossibleObject(loopSymbolResource, mod.ElementToComponent); + if (loopComponentResource == null) + return Collections.emptyList(); + + Resource loopResource = graph.getPossibleObject(loopComponentResource, sr.Loop_Items); + if (loopResource == null) + return Collections.emptyList(); + + List loopItems = ListUtils.toPossibleList(graph, loopResource); + if (loopItems == null) + return Collections.emptyList(); + + ArrayList dependencyItems = new ArrayList(); + + // Add dependencies and flows. + for (int i = 0; i < loopItems.size(); ++i) { + boolean skipBackwardFlows = false; + + // Go through forward dependencies and flows + Collection forwardDependencies = graph.getObjects(loopItems.get(i), sr.Variable_isTailOf); + for (Resource dependency : forwardDependencies) { + Resource dependingVariable = graph.getSingleObject(dependency, sr.Variable_HasHead); + if (dependingVariable.equals(loopItems.get((i + 1) % loopItems.size()))) { + if (graph.isInstanceOf(dependency, sr.Flow) + && graph.isInstanceOf(loopItems.get(i), sr.Stock)) { + // Flows from stocks don't count. + continue; + } + skipBackwardFlows = true; + dependencyItems.add(graph.getSingleObject(dependency, mod.ConnectionToDiagramConnection)); + break; + } + } + + if (skipBackwardFlows) + continue; + + // Backward flows from stocks. + Collection backwardFlows = graph.getObjects(loopItems.get(i), sr.Variable_isHeadOf); + for (Resource flow : backwardFlows) { + if (graph.isInstanceOf(flow, sr.Flow)) { + Resource dependingVariable = graph.getSingleObject(flow, sr.Variable_HasTail); + if (dependingVariable.equals(loopItems.get((i + 1) % loopItems.size())) + && graph.isInstanceOf(dependingVariable, sr.Stock)) { + dependencyItems.add(graph.getSingleObject(flow, mod.ConnectionToDiagramConnection)); + break; + } + } + } + } + + // Convert variables from component to element. + for (int i = 0; i < loopItems.size(); ++i) { + loopItems.set(i, graph.getPossibleObject(loopItems.get(i), mod.ComponentToElement)); + } + // Merge the two lists. + loopItems.addAll(dependencyItems); + + return loopItems; + } + + }); + } catch (DatabaseException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + return loopItems; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleFactory.java new file mode 100644 index 00000000..175a95d5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleFactory.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.db.Resource; +import org.simantics.diagram.elements.ResizeRectangularSceneGraph; +import org.simantics.diagram.elements.TextNode; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.impl.BorderColorImpl; +import org.simantics.g2d.element.handler.impl.BoundsOutline; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.OutlinePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; +import org.simantics.g2d.utils.Alignment; +import org.simantics.scenegraph.g2d.G2DParentNode; + +public class ModuleFactory extends SysdynElementFactory { + + private static final BasicStroke STROKE = new BasicStroke(2.0f); + private static final Image DEFAULT_IMAGE = new ShapeImage(new Rectangle2D.Double(-5, -2.5, 10, 5), null, STROKE, true); + + @Override + protected ElementClass compileElementClass(Resource elementType, Collection terminals) { + return ElementClass.compile( + SimpleElementLayers.INSTANCE, + OutlinePick.INSTANCE, + TextImpl.INSTANCE, + TextColorImpl.BLACK, + new TextFontImpl(new Font("arial", Font.PLAIN, 25)), + DefaultTransform.INSTANCE, + new StaticObjectAdapter(elementType), + new StaticSymbolImpl(DEFAULT_IMAGE), + StaticSymbolImageInitializer.INSTANCE, + new ModuleSceneGraph(0, 0, Alignment.CENTER, 1f , 2, 3, true), + BoundsOutline.INSTANCE, + new BorderColorImpl(Color.BLACK), + ResizeRectangularSceneGraph.INSTANCE, + RESIZE_PROPERTY_SETTER, + new WholeElementTerminals(terminals) + ).setId(ModuleFactory.class.getSimpleName()); + } + + + public static class ModuleSceneGraph extends SysdynTextElementHandler implements InternalSize { + + private static final long serialVersionUID = 2367230056477661273L; + + public ModuleSceneGraph(double originX, double originY, Alignment horizontalAlignment, double borderWidth, + double paddingX, double paddingY, boolean editable) { + super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable); + } + + + + @Override + protected TextNode getOrCreateTextNode(IElement e, G2DParentNode parent) { + return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", ModuleNode.class, getCallback(e, parent, ModuleNode.class)); + } + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleNode.java new file mode 100644 index 00000000..f2431be5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleNode.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.scenegraph.utils.NodeUtil; + +public class ModuleNode extends SysdynTextNode { + + private static final long serialVersionUID = 8535695797227320496L; + private static double CORNER_LENGTH = 2.0; + private static double CORNER_PADDING = 0.8; + + + @Override + public void render(Graphics2D g) { + super.render(g); + + BasicStroke oldStroke = (BasicStroke)g.getStroke(); + Color oldColor = g.getColor(); + + Rectangle2D bounds = getBounds(); + + + Path2D path = new Path2D.Double(); + // LEFT TOP + path.moveTo(bounds.getMinX() + CORNER_LENGTH, bounds.getMinY() - CORNER_PADDING); + path.lineTo(bounds.getMinX() - CORNER_PADDING, bounds.getMinY() - CORNER_PADDING); + path.lineTo(bounds.getMinX() - CORNER_PADDING, bounds.getMinY() + CORNER_LENGTH); + + // LEFT BOTTOM + path.moveTo(bounds.getMinX() + CORNER_LENGTH, bounds.getMaxY() + CORNER_PADDING); + path.lineTo(bounds.getMinX() - CORNER_PADDING, bounds.getMaxY() + CORNER_PADDING); + path.lineTo(bounds.getMinX() - CORNER_PADDING, bounds.getMaxY() - CORNER_LENGTH); + + // RIGHT TOP + path.moveTo(bounds.getMaxX() - CORNER_LENGTH, bounds.getMinY() - CORNER_PADDING); + path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMinY() - CORNER_PADDING); + path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMinY() + CORNER_LENGTH); + + // RIGHT BOTTOM + path.moveTo(bounds.getMaxX() - CORNER_LENGTH, bounds.getMaxY() + CORNER_PADDING); + path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMaxY() + CORNER_PADDING); + path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMaxY() - CORNER_LENGTH); + + g.setStroke(new BasicStroke((float) (/*scale**/scale*borderWidth))); + g.setColor(borderColor); + g.draw(path); + + + boolean selected = NodeUtil.isSelected(this, 1); + if (selected && showsSelection()) { + Composite oc = g.getComposite(); + g.setComposite(AlphaComposite.SrcOver.derive(0.5f)); + + g.setColor(Color.RED); + float bw = borderWidth; + double s = GeometryUtils.getScale(g.getTransform()); + if (bw <= 0f) { + bw = (float) (1f / s); + } else { + bw *= 3f * scale; + } + g.setStroke(new BasicStroke(bw)); + g.draw(path); + + g.setComposite(oc); + } + + g.setColor(oldColor); + g.setStroke(oldStroke); + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElementFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElementFactory.java new file mode 100644 index 00000000..d6b56d0a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElementFactory.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.adapter.TextElementClassFactory; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; + +/** + * Multi-line text element used in comment in sysdyn diagrams + * @author Teemu Lempinen + * + */ +public class MultilineTextElementFactory extends TextElementClassFactory { + + @Override + public void load(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource element, IElement e) + throws DatabaseException { + super.load(graph, canvas, diagram, element, e); + e.setHint(ElementHints.KEY_RESIZABLE, true); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Orientation.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Orientation.java new file mode 100644 index 00000000..dbf32579 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Orientation.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.ElementHandler; + +public class Orientation implements ElementHandler { + + private static final long serialVersionUID = 958120463924210936L; + + public static final Orientation INSTANCE = new Orientation(); + + public String getOrientation(IElement e) { + return e.getHint(SysdynElementHints.KEY_ORIENTATION); + } + + + public void setOrientation(IElement e, String orientation) { + if (orientation != null) + e.setHint(SysdynElementHints.KEY_ORIENTATION, orientation); + else + e.removeHint(SysdynElementHints.KEY_ORIENTATION); + } +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/RectangleNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/RectangleNode.java new file mode 100644 index 00000000..1f05f54b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/RectangleNode.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import org.simantics.scenegraph.g2d.G2DNode; + +public class RectangleNode extends G2DNode { + + private static final long serialVersionUID = 654692698101485672L; + + protected Rectangle2D bounds = null; + + @SyncField("bounds") + public void init(Rectangle2D bounds) { + this.bounds = bounds; + } + + @Override + public void render(Graphics2D g) { + if(bounds == null) return; + AffineTransform ot = g.getTransform(); + + g.transform(transform); + g.setColor(Color.BLACK); + double scale = g.getTransform().getScaleX(); + g.setStroke(new BasicStroke( (float)(1.0 / scale) )); + + g.draw(bounds); + g.setTransform(ot); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return bounds; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowFactory.java new file mode 100644 index 00000000..726cae6f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowFactory.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Path2D; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.elements.ResizeRectangularSceneGraph; +import org.simantics.diagram.elements.TextElementHandler; +import org.simantics.diagram.synchronization.SynchronizationHints; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.impl.BoundsOutline; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.OutlinePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; +import org.simantics.g2d.utils.Alignment; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; + +public class ShadowFactory extends SysdynElementFactory { + + private static TextElementHandler shadowHandler = new TextElementHandler(0, 0, Alignment.LEADING, 0.0, 2.0, 2.0, false); + private static final TextColorImpl GRAY = new TextColorImpl(java.awt.Color.GRAY); + private static final BasicStroke STROKE = new BasicStroke(1f); + public static final Image GHOST_IMAGE = new ShapeImage(getGhostShape(), null, STROKE, true); + + static Shape getGhostShape() { + + Path2D path = new Path2D.Double(); + + // Body + path.moveTo(-3, 3); + path.quadTo(-3, -3, 0, -3); + path.quadTo(3, -3, 3, 3); + path.lineTo(2, 2); + path.lineTo(1, 3); + path.lineTo(0, 2); + path.lineTo(-1, 3); + path.lineTo(-2, 2); + path.closePath(); + + // Eyes + path.append(new Ellipse2D.Double(-1.25, -1.25, 0.5, 0.5), false); + path.append(new Ellipse2D.Double(0.75, -1.25, 0.5, 0.5), false); + return path; + } + + + @Override + protected ElementClass compileElementClass(Resource elementType, Collection terminals) { + return ElementClass.compile( + SimpleElementLayers.INSTANCE, + OutlinePick.INSTANCE, + TextImpl.INSTANCE, + GRAY, + TextFontImpl.DEFAULT, + DefaultTransform.INSTANCE, + new StaticObjectAdapter(elementType), + new StaticSymbolImpl(GHOST_IMAGE), + StaticSymbolImageInitializer.INSTANCE, + shadowHandler, + BoundsOutline.INSTANCE, + ResizeRectangularSceneGraph.INSTANCE, + RESIZE_PROPERTY_SETTER, + new WholeElementTerminals(terminals) + ).setId(ShadowFactory.class.getSimpleName()); + } + + @Override + public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + + Resource component = graph.getPossibleObject(element, mr.ElementToComponent); + String text = null; + if (component != null) { + SysdynResource SR = SysdynResource.getInstance(graph); + Resource original = graph.getPossibleObject(component, SR.Shadow_original); + if(original != null) + text = "< " + (String) graph.getPossibleRelatedValue(original, l0.HasName) + " >"; + } + if (text == null) + text = "< --- >"; + + ElementUtils.setText(e, text); + + super.getVisualProperties(graph, element, e); + + AffineTransform at = DiagramGraphUtil.getAffineTransform(graph, element); + ElementUtils.setTransform(e, at); + + // This synchronizes only text and transformation (not font and color) + e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, SYNCHRONIZER); + + e.setHint(ElementHints.KEY_HOVER, false); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceDialogRunnable.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceDialogRunnable.java new file mode 100644 index 00000000..6e1f7de9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceDialogRunnable.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.util.HashMap; + +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; +import org.simantics.db.Resource; +import org.simantics.ui.SimanticsUI; + +public class ShadowVariableReferenceDialogRunnable implements Runnable { + + private Resource shadow; + private HashMap possibleReferences; + + public ShadowVariableReferenceDialogRunnable(Resource shadow, HashMap possibleReferences) { + this.shadow = shadow; + this.possibleReferences = possibleReferences; + } + + @Override + public void run() { + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + + ElementListSelectionDialog dialog = + new ElementListSelectionDialog(shell, new LabelProvider()); + dialog.setElements(possibleReferences.keySet().toArray(new String[possibleReferences.keySet().size()])); + dialog.setTitle("Select referred variable"); + dialog.setMultipleSelection(false); + + dialog.open(); + + Object[] result = dialog.getResult(); + + Resource resource = null; + if(result != null && result.length == 1) + resource = possibleReferences.get(result[0]); + + SimanticsUI.getSession().asyncRequest(new ShadowVariableReferenceRequest(shadow, resource)); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceRequest.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceRequest.java new file mode 100644 index 00000000..7fb80e8a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceRequest.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; + +public class ShadowVariableReferenceRequest extends WriteRequest { + + Resource shadow; + Resource original; + + public ShadowVariableReferenceRequest(Resource shadow, Resource original) { + this.shadow = shadow; + this.original = original; + } + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + if(shadow == null) + return; + + if(shadow != null && original == null) { + Resource element = graph.getPossibleObject(shadow, ModelingResources.getInstance(graph).ComponentToElement); + RemoverUtil.remove(graph, element); + } else { + SysdynResource SR = SysdynResource.getInstance(graph); + graph.claim(shadow, SR.Shadow_original, original); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Size.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Size.java new file mode 100644 index 00000000..00b0d2f3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Size.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.geom.Rectangle2D; + +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.LifeCycle; + +/** + * Class for internal size and setting default bounds when element is created. + * Used especially with comment elements (resizeable text elements) + * + * @author Teemu Lempinen + * + */ +public class Size implements InternalSize, LifeCycle { + private static final long serialVersionUID = -7459941323196171227L; + private Rectangle2D defaultBounds; + + public Size(Rectangle2D defaultSize) { + this.defaultBounds = defaultSize; + } + + /** + * Set default bounds for the created element + * @param e Element + */ + @Override + public void onElementCreated(IElement e) { + e.setHint(ElementHints.KEY_BOUNDS, defaultBounds); + } + + /** + * Returns bounds of the element + */ + @Override + public Rectangle2D getBounds(IElement e, Rectangle2D size) { + if (size==null) size = new Rectangle2D.Double(); + size.setFrame((Rectangle2D)e.getHint(ElementHints.KEY_BOUNDS)); + return size; + } + + @Override + public void onElementDestroyed(IElement e) {} + @Override + public void onElementActivated(IDiagram d, IElement e) {} + @Override + public void onElementDeactivated(IDiagram d, IElement e) {} + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((defaultBounds == null) ? 0 : defaultBounds.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Size other = (Size) obj; + if (defaultBounds == null) { + if (other.defaultBounds != null) + return false; + } else if (!defaultBounds.equals(other.defaultBounds)) + return false; + return true; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockFactory.java new file mode 100644 index 00000000..96b68951 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockFactory.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.elements.ResizeRectangularSceneGraph; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.impl.BorderColorImpl; +import org.simantics.g2d.element.handler.impl.BoundsOutline; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.OutlinePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; +import org.simantics.g2d.utils.Alignment; + +public class StockFactory extends SysdynElementFactory { + + private static final BasicStroke STROKE = new BasicStroke(1f); + public static final Image STOCK_IMAGE = new ShapeImage(new Rectangle2D.Double(-5, -2.5, 10, 5), null, STROKE, true); + + @Override + protected ElementClass compileElementClass(Resource elementType, Collection terminals) { + return ElementClass.compile( + SimpleElementLayers.INSTANCE, + OutlinePick.INSTANCE, + TextImpl.INSTANCE, + TextColorImpl.BLACK, + TextFontImpl.DEFAULT, + DefaultTransform.INSTANCE, + new StaticObjectAdapter(elementType), + new StaticSymbolImpl(STOCK_IMAGE), + StaticSymbolImageInitializer.INSTANCE, + new SysdynTextElementHandler(0, 0, Alignment.CENTER, 1f, 1.0, 1.0, true), + BoundsOutline.INSTANCE, + new BorderColorImpl(Color.BLACK), + ResizeRectangularSceneGraph.INSTANCE, + RESIZE_PROPERTY_SETTER, + new WholeElementTerminals(terminals) + ).setId(StockFactory.class.getSimpleName()); + } + + @Override + public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException { + super.load(graph, canvas, diagram, element, e); + e.setHint(ElementHints.KEY_BORDER_COLOR, e.getHint(ElementHints.KEY_TEXT_COLOR)); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementClasses.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementClasses.java new file mode 100644 index 00000000..a2cb04a7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementClasses.java @@ -0,0 +1,8 @@ +package org.simantics.sysdyn.ui.elements; + +public class SysdynElementClasses { + + public static final Object VALVE = new Object() { + public String toString() { return "VALVE"; } + }; +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementFactory.java new file mode 100644 index 00000000..174ae574 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementFactory.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.Color; +import java.awt.Font; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.resource.StringConverter; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; +import org.simantics.db.exception.ServiceException; +import org.simantics.diagram.G2DUtils; +import org.simantics.diagram.adapter.SyncElementFactory; +import org.simantics.diagram.content.ResourceTerminal; +import org.simantics.diagram.elements.ElementPropertySetter; +import org.simantics.diagram.elements.ResizeRectangularSceneGraph; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.diagram.synchronization.CompositeHintSynchronizer; +import org.simantics.diagram.synchronization.IHintSynchronizer; +import org.simantics.diagram.synchronization.SynchronizationHints; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.diagram.synchronization.graph.TransformSynchronizer; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.preferences.SysdynDiagramPreferences; +import org.simantics.sysdyn.ui.preferences.SysdynDiagramPropertyExternalRead; +import org.simantics.utils.datastructures.Pair; + +/** + * An ElementFactory that gathers common functionality for system dynamics symbols. + * Just implement {@link #compileElementClass(Resource, Collection)} to add a symbol. + * + * @author Tuukka Lehtonen + */ +public abstract class SysdynElementFactory extends SyncElementFactory { + + public static final IHintSynchronizer SYNCHRONIZER = new CompositeHintSynchronizer( + ComponentNameSynchronizer.INSTANCE, + TransformSynchronizer.INSTANCE); + + public static final ElementPropertySetter RESIZE_PROPERTY_SETTER = + new ElementPropertySetter(ResizeRectangularSceneGraph.KEY_SG_NODE); + + protected String getText(ReadGraph graph, Resource element) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + Resource component = graph.getPossibleObject(element, mr.ElementToComponent); + String text = null; + if (component != null) { + text = (String) graph.getPossibleRelatedValue(component, l0.HasName); + } + if (text == null) + text = "[empty]"; + return text; + } + + @Override + public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException { + e.setHint(ElementHints.KEY_RESIZABLE, true); + ElementUtils.setText(e, getText(graph, element)); + // Just testing loop finding. + //ModelingResources mr = ModelingResources.getInstance(graph); + //Resource component = graph.getPossibleObject(element, mr.ElementToComponent); + //ConfigurationUtils.getLoops(graph, component); + getVisualProperties(graph, element, e); + + AffineTransform at = DiagramGraphUtil.getAffineTransform(graph, element); + ElementUtils.setTransform(e, at); + + // This synchronizes only text and transformation (not font and color) + e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, SYNCHRONIZER); + + e.setHint(ElementHints.KEY_HOVER, false); + } + + /** + * Reads a collection of visualization properties e.g. colour and font. + * @param graph ReadGraph + * @param element Element resource + * @param e Diagram element + * @throws DatabaseException + */ + protected void getVisualProperties(ReadGraph graph, Resource element, IElement e) throws DatabaseException { + G2DResource g2d = G2DResource.getInstance(graph); + DiagramResource dr = DiagramResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + + if (graph.isInstanceOf(element, dr.FontProvider)) { + Statement fontStatement = graph.getPossibleStatement(element, g2d.HasFont); + if(fontStatement != null && !fontStatement.isAsserted(element)) { + ElementUtils.setTextFont(e, G2DUtils.getFont(graph, fontStatement.getObject())); + } else { + String fontdata = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair(element, SysdynDiagramPreferences.getFontPreferenceName(graph, element)))); + if(fontdata != null) { + FontData[] fdArray = PreferenceConverter.basicGetFontData(fontdata); + if(fdArray != null) { + if(fdArray.length == 1) { + FontData fd = fdArray[0]; + if(fd != null) { + Font font = new Font(fd.getName(), fd.getStyle(), fd.getHeight()); + e.setHint(ElementHints.KEY_FONT, font); + } + } + } + } + } + } + if (graph.isInstanceOf(element, dr.ColorProvider)) { + Statement colorStatement = graph.getPossibleStatement(element, g2d.HasColor); + if(colorStatement != null && !colorStatement.isAsserted(element)) { + e.setHint(ElementHints.KEY_TEXT_COLOR, G2DUtils.getColor(graph, colorStatement.getObject())); + } else { + String color = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair(element, SysdynDiagramPreferences.getColorPreferenceName(graph, element)))); + if(color != null) { + RGB rgb = StringConverter.asRGB(color, null); + if(rgb != null) { + Color c = new Color(rgb.red, rgb.green, rgb.blue); + e.setHint(ElementHints.KEY_TEXT_COLOR, c); + e.setHint(ElementHints.KEY_BORDER_COLOR, c); + } + } + + } + } + + Resource component = graph.getPossibleObject(element, mr.ElementToComponent); + if (component != null && graph.hasStatement(component, SysdynResource.getInstance(graph).IsOutput)) { + Font font = ElementUtils.getTextFont(e); + font = font.deriveFont(Font.BOLD); + ElementUtils.setTextFont(e, font); + } + + double bounds[] = DiagramGraphUtil.getPossibleRelatedDoubleArray(graph, element, G2DResource.getInstance(graph).HasBounds); + if (bounds != null) { + e.setHint(ElementHints.KEY_BOUNDS, new Rectangle2D.Double(bounds[0], bounds[1], bounds[2], bounds[3])); + } + + } + + @Override + public ElementClass create(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType) + throws DatabaseException { + return compileElementClass(elementType, createTerminals(graph, elementType)); + } + + public static Collection createTerminals(ReadGraph graph, Resource elementType) { + + try { + StructuralResource2 sr = StructuralResource2.getInstance(graph); + DiagramResource dr = DiagramResource.getInstance(graph); + + Resource definedByList = graph.getPossibleObject(elementType, sr.IsDefinedBy); + Collection definedBy = Collections.emptyList(); + if (definedByList != null) + definedBy = OrderedSetUtils.toList(graph, definedByList); + Collection terminals = new ArrayList(definedBy.size()); + for (Resource r : definedBy) { + if (graph.isInstanceOf(r, dr.Terminal)) { + terminals.add(new ResourceTerminal(r)); + } + } + return terminals; + } catch (ManyObjectsForFunctionalRelationException e) { + e.printStackTrace(); + } catch (ServiceException e) { + e.printStackTrace(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * @param elementType the type of the loaded element + * @param terminals the terminals of the element type being loaded + * @return an {@link ElementClass} representing the loaded element type + */ + protected abstract ElementClass compileElementClass(Resource elementType, Collection terminals); + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementHints.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementHints.java new file mode 100644 index 00000000..fdd74d41 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementHints.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.g2d.canvas.IToolMode; +import org.simantics.g2d.canvas.impl.ToolMode; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; + +public class SysdynElementHints { + + public static final Key KEY_INPUT_REFERENCE = new KeyOf(String.class, "INPUT_REFERENCE"); + public static final Key KEY_ORIENTATION = new KeyOf(String.class, "ORIENTATION"); + public static final Key KEY_LOCATION = new KeyOf(String.class, "LOCATION"); + public static final Key KEY_LOOP_CLOCKWISE = new KeyOf(Boolean.class, "LOOP_CLOCKWISE"); + + public static final Key SYSDYN_KEY_TOOL = new KeyOf(ToolMode.class, "SysdynKeyTool"); + public static final IToolMode DEPENDENCY_TOOL = new ToolMode("DependencyTool"); + public static final IToolMode FLOW_TOOL = new ToolMode("FlowTool"); + public static final IToolMode LOCK_TOOL = new ToolMode("LockTool"); + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementUtils.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementUtils.java new file mode 100644 index 00000000..f912495f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementUtils.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.g2d.element.IElement; + +public class SysdynElementUtils { + + + public static void setInputReference(IElement e, String inputReference) + { + Input i = e.getElementClass().getSingleItem(Input.class); + if(i != null) + i.setInputReference(e, inputReference); + } + + public static String getInputReference(IElement e) + { + Input i = e.getElementClass().getSingleItem(Input.class); + if(i != null) + return i.getInputReference(e); + else + return null; + } + + public static void setOrientation(IElement e, String orientation) + { + Orientation o = e.getElementClass().getSingleItem(Orientation.class); + if(o != null) + o.setOrientation(e, orientation); + } + + public static String getOrientation(IElement e) + { + Orientation o = e.getElementClass().getSingleItem(Orientation.class); + if(o != null) + return o.getOrientation(e); + else + return null; + } + + public static void setValveTextLocation(IElement e, String location) + { + ValveTextLocation v = e.getElementClass().getSingleItem(ValveTextLocation.class); + if(v != null) + v.setTextLocation(e, location); + } + + public static String getValveTextLocation(IElement e) + { + ValveTextLocation v = e.getElementClass().getSingleItem(ValveTextLocation.class); + if(v != null) + return v.getTextLocation(e); + else + return null; + } + + public static void setLoopClockwise(IElement e, Boolean clockwise) { + LoopClockwise l = e.getElementClass().getSingleItem(LoopClockwise.class); + if(l != null) + l.setTextLocation(e, clockwise); + } + + public static String getLoopClockwise(IElement e) + { + LoopClockwise l = e.getElementClass().getSingleItem(LoopClockwise.class); + if(l != null) + return l.getTextLocation(e); + else + return null; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementHandler.java new file mode 100644 index 00000000..408ff09b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementHandler.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT - initial API and implementation + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.geom.Rectangle2D; + +import org.simantics.diagram.elements.TextElementHandler; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.utils.Alignment; + +/** + * Version of {@link SysdynTextElementNoBounds} that supports InternalSize + * @author Teemu Lempinen + * + */ +public class SysdynTextElementHandler extends SysdynTextElementNoBounds implements InternalSize { + private static final long serialVersionUID = -1307413505370441178L; + + public static SysdynTextElementHandler INSTANCE = new SysdynTextElementHandler(); + + public SysdynTextElementHandler() { + super(); + } + + public SysdynTextElementHandler(double originX, double originY, Alignment horizontalAlignment) { + super(originX, originY, horizontalAlignment); + } + + public SysdynTextElementHandler(double originX, double originY, Alignment horizontalAlignment, double borderWidth) { + super(originX, originY, horizontalAlignment, borderWidth); + } + + public SysdynTextElementHandler(double originX, double originY, Alignment horizontalAlignment, double borderWidth, + double paddingX, double paddingY, boolean editable) { + super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable); + } + + @Override + public Rectangle2D getBounds(IElement e, Rectangle2D size) { + Rectangle2D bounds = TextElementHandler.calculateBounds(e, size, horizontalAlignment, SCALE, paddingX, paddingX); + return bounds; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementNoBounds.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementNoBounds.java new file mode 100644 index 00000000..76defa5b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementNoBounds.java @@ -0,0 +1,306 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT - initial API and implementation + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.Color; +import java.awt.geom.AffineTransform; + +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbenchPage; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.elements.DiagramNodeUtil; +import org.simantics.diagram.elements.ITextListener; +import org.simantics.diagram.elements.TextElementNoBounds; +import org.simantics.diagram.elements.TextNode; +import org.simantics.diagram.participant.SGFocusParticipant; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.chassis.SWTChassis; +import org.simantics.g2d.diagram.DiagramUtils; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.utils.Alignment; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.modeling.ui.diagramEditor.DiagramViewer; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils; +import org.simantics.sysdyn.ui.utils.VariableNameValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; + +/** + * TextElement for variables in Siamntics System Dynamics + * + * The main differences for the basic TextElementNoBounds are: + * 1. Text is never mirrored + * 2. Edit mode is activated when the variable is created + * + * @author Teemu Lempinen + * + */ +public class SysdynTextElementNoBounds extends TextElementNoBounds { + + private static final long serialVersionUID = -148784588840819612L; + + public static final Key ELEMENT_INITIALIZED = new KeyOf(Boolean.class, "SYSDYN_TEXT_ELEMENT_INITIALIZED"); + + // Constructors + public SysdynTextElementNoBounds() { + super(0, 0, Alignment.LEADING, 0); + } + + public SysdynTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment) { + super(originX, originY, horizontalAlignment, 0); + } + + public SysdynTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth) { + super(originX, originY, horizontalAlignment, borderWidth); + } + + public SysdynTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable) { + super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable); + } + + // End constructors + + protected Callback getCallback(final IElement e, G2DParentNode parent, Class nodeClass) { + return new Callback() { + @Override + public void run(T node) { + node.setTextListener(new ITextListener() { + + String textBeforeEdit; + Resource component; + + @Override + public void textChanged() { + TextNode node = (TextNode) e.getHint(SG_NODE); + if(!new VariableNameValidator().isValid(component, node.getText(), false)) { + node.setColor(Color.RED); + } else { + node.setColor(ElementUtils.getTextColor(e, Color.BLACK)); + } + + + } + + @Override + public void textEditingStarted() { + TextNode node = (TextNode) e.getHint(SG_NODE); + textBeforeEdit = node.getText(); + + if(component != null) return; + + Object o = e.getHint(ElementHints.KEY_OBJECT); + if(o != null && o instanceof Resource) { + final Resource element = (Resource)o; + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + component = graph.getPossibleObject(element, ModelingResources.getInstance(graph).ElementToComponent); + } + }); + } + } + + @Override + public void textEditingCancelled() { + TextNode node = (TextNode) e.getHint(SG_NODE); + if (node != null) { + if(new VariableNameValidator().isValid(component, node.getText(), false)) + node.setColor(ElementUtils.getTextColor(e, Color.BLACK)); + endEdit(node); + } + } + + @Override + public void textEditingEnded() { + TextNode node = (TextNode) e.getHint(SG_NODE); + if (node == null) + return; + String text = node.getText(); + if(!new VariableNameValidator().isValid(component, text, false)) { + text = textBeforeEdit; + node.setText(text); + if(new VariableNameValidator().isValid(component, text, false)) + node.setColor(ElementUtils.getTextColor(e, Color.BLACK)); + } else { + Object o = e.getHint(ElementHints.KEY_OBJECT); + final String textAfterEdit = text; + if(o != null && o instanceof Resource) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Resource configuration = graph.getPossibleObject(component, Layer0.getInstance(graph).PartOf); + new VariableNameValidator().renameInAllEquations(graph, configuration, textBeforeEdit, textAfterEdit); + } + }); + } + } + ElementUtils.setText(e, text); + IDiagram diagram = ElementUtils.getDiagram(e); + DiagramUtils.synchronizeHintsToBackend(diagram, e); + endEdit(node); + } + }); + } + }; + } + + /** + * Reverts any rotations that are assigned to the text element + * @param e + */ + public static void unflipText(IElement e) { + Object o = e.getHint(SG_NODE); + if (o instanceof TextNode) { + TextNode text = (TextNode)o; + AffineTransform at = text.getTransform(); + double x = at.getTranslateX(); + double y = at.getTranslateY(); + at.setToRotation(0); + at.setToTranslation(x, y); + at.setTransform(at); + } + } + + /** + * Activates edit mode for a newly created variable. + * + * Sets focus for diagram if the variable was created by dragging from model browser. + * + * @param e + */ + protected void activateEdit(final IElement e) { + final SysdynTextNode node = e.getHint(SG_NODE); + if(node == null) + return; + + final ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node); + // FIXME: needed only because eventdelegator registrations are done before adding node to scene graph. + if (ctx == null) + return; + if (!node.isEditMode()) { + + // Get the active editor + IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor(); + final DiagramEditor editor = (DiagramEditor)page.getActiveEditor(); + final ICanvasContext editorCtx = (ICanvasContext) editor.getViewer().getAdapter(ICanvasContext.class); + + editor.getViewer().getComposite().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + Control c = editor.getViewer().getComposite().getDisplay().getFocusControl(); + if (c == null || "BasicSymbols".equals(c.getParent().getToolTipText())) { + // If the variable has been drag and dropped, set focus to diagram and then activate edit. + + editorCtx.add(new SGFocusParticipant((SWTChassis)editor.getViewer().getComposite(), DiagramViewer.DIAGRAMMING_CONTEXT) { + + @Override + public void focusGained(java.awt.event.FocusEvent event) { + + // When focus has been gained, acticate edit and destroy the listener. + editor.getViewer().getComposite().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if (Boolean.TRUE.equals(node.setEditMode(true))) { + node.activateEdit(0, e, ctx, true); + node.repaint(); + } + } + }); + ctx.remove(this); + } + + @Override + public void focusLost(java.awt.event.FocusEvent e) { + } + }); + + editor.setFocus(); + } else { + // If the variable has been created with shortcut key, just activate the edit. + if (Boolean.TRUE.equals(node.setEditMode(true))) { + node.activateEdit(0, e, ctx, true); + node.repaint(); + } + } + } + }); + } + } + + @Override + protected TextNode getOrCreateTextNode(IElement e, G2DParentNode parent) { + return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", SysdynTextNode.class, getCallback(e, parent, SysdynTextNode.class)); + } + + @Override + public void init(final IElement e, G2DParentNode parent) { + super.init(e, parent); + + + // Add handling for activating text edit for new variables + // Store initialization status to hints to prevent unnecessary graph queries + Boolean isInitialized = e.getHint(ELEMENT_INITIALIZED); + Object o = e.getHint(ElementHints.KEY_OBJECT); + if (o instanceof Resource && !Boolean.TRUE.equals(isInitialized)) { + final Resource element = (Resource)o; + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + ModelingResources MR = ModelingResources.getInstance(graph); + Resource component = graph.getPossibleObject(element, MR.ElementToComponent); + if (component == null) + return; + + // See if the resource of the element has just been created. + Resource r = graph.getPossibleObject(component, SR.IndependentVariable_isUninitialized); + if (r == null){ + return; + } + + // If the resource is just been created, activate editing its name. + if (!graph.isInstanceOf(r, SR.Loop)) { + activateEdit(e); + } + graph.deny(component, SR.IndependentVariable_isUninitialized, r); + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + e.setHint(ELEMENT_INITIALIZED, Boolean.TRUE); + } + + unflipText(e); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java new file mode 100644 index 00000000..1d593a39 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT - initial API and implementation + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.HashMap; + +import org.simantics.diagram.elements.TextEditActivation; +import org.simantics.diagram.elements.TextNode; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.element.IElement; +import org.simantics.scenegraph.g2d.events.EventTypes; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin; +import org.simantics.sysdyn.ui.elements.LoopNode.ILoopComponentNode; +import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils; + +/** + * Text node for Sysdyn elements. + * + * Additions to the basic node: + * 1. Draw borders when hovering + * 2. Support Sysdyn's diagram locking + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class SysdynTextNode extends TextNode implements ILoopComponentNode { + + private static final long serialVersionUID = 5235077104121753251L; + private HashMap loopSelectionMap = new HashMap(); + + private boolean isLoopSelected() { + return loopSelectionMap.containsValue(true); + } + + @Override + public int getEventMask(){ + return EventTypes.FocusLostMask | super.getEventMask(); + } + + @Override + protected boolean mouseDragged(MouseDragBegin e) { + // Disable dragging if LockSketch is ON + if (SysdynElementHints.LOCK_TOOL.equals(SysdynWorkbenchUtils.getSysdynToolMode())){ + super.mouseDragged(e); + return true;} + else + return super.mouseDragged(e); + } + + + @Override + protected void renderSelectedHover(Graphics2D g, boolean isSelected, boolean isHovering) { + + if (!isSelected && isHovering) { + BasicStroke oldStroke = (BasicStroke)g.getStroke(); + Color oldColor = g.getColor(); + g.setColor(Color.LIGHT_GRAY); + g.setStroke(new BasicStroke((float)(2.0*scale))); + g.draw(getBoundsInLocal()); + g.setColor(oldColor); + g.setStroke(oldStroke); + + } else if (isLoopSelected()) { + BasicStroke oldStroke = (BasicStroke)g.getStroke(); + Color oldColor = g.getColor(); + g.setColor(LoopNode.HIGHLIGHT_COLOR); + g.setStroke(new BasicStroke((float)(2.0*scale))); + g.draw(getBoundsInLocal()); + g.setColor(oldColor); + g.setStroke(oldStroke); + + } + } + + public TextEditActivation activateEdit(int mouseId, IElement e, ICanvasContext ctx, boolean save) { + if (save) + return editActivation = super.activateEdit(mouseId, e, ctx); + return super.activateEdit(mouseId, e, ctx); + } + + @Override + public void setLoopSelected(LoopNode loop, boolean selected) { + Boolean loopSelected = loopSelectionMap.get(loop); + if (loopSelected == null || loopSelected != selected) { + loopSelectionMap.put(loop, selected); + repaint(); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java new file mode 100644 index 00000000..200ce9e5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java @@ -0,0 +1,338 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.elements.ResizeNode.TranslateEdge; +import org.simantics.diagram.elements.ResizeRectangularSceneGraph; +import org.simantics.diagram.elements.TextElementNoBounds; +import org.simantics.diagram.elements.TextNode; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.SceneGraphNodeKey; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.HoverImpl; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.OutlinePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; +import org.simantics.g2d.utils.Alignment; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.nodes.ShapeNode; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; +import org.simantics.utils.datastructures.hints.IHintListener; +import org.simantics.utils.datastructures.hints.IHintObservable; + + +public class ValveFactory extends SysdynElementFactory { + + public static final Key KEY_ROTATED = new KeyOf(Boolean.class, "ROTATED"); + + public static final double VALVE_SIZE = 1.5; + + private static final BasicStroke STROKE = new BasicStroke(1f); + public static final Image VALVE_STATIC_IMAGE = new ShapeImage(createShape(VALVE_SIZE, false), null, STROKE, true); + + /* (non-Javadoc) + * @see org.simantics.sysdyn.ui.elements.SysdynElementFactory#compileElementClass(org.simantics.db.Resource, java.util.Collection) + */ + @Override + protected ElementClass compileElementClass(Resource elementType, Collection terminals) { + return ElementClass.compile( + SimpleElementLayers.INSTANCE, + OutlinePick.INSTANCE, + TextImpl.INSTANCE, + TextColorImpl.BLACK, + TextFontImpl.DEFAULT, + DefaultTransform.INSTANCE, + new StaticObjectAdapter(elementType), + new StaticSymbolImpl(VALVE_STATIC_IMAGE), + StaticSymbolImageInitializer.INSTANCE, + HoverImpl.INSTANCE, + Orientation.INSTANCE, + ValveTextLocation.INSTANCE, + ValveSceneGraph.INSTANCE, + ValveText.INSTANCE, + new ResizeRectangularSceneGraph(TextElementNoBounds.SG_NODE), + RESIZE_PROPERTY_SETTER, + ValveBounds.INSTANCE, + ValveOutline.INSTANCE, + new WholeElementTerminals(terminals) + ).setId(ValveFactory.class.getSimpleName()); + } + + @Override + public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException { + super.load(graph, canvas, diagram, element, e); + + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource orientation = graph.getPossibleObject(element, sr.ValveSymbol_orientation); + + String orientationText; + if(orientation != null && sr.Vertical.equals(orientation)) { + orientationText = "Vertical"; + } else { + orientationText = "Horizontal"; + } + SysdynElementUtils.setOrientation(e, orientationText); + + Resource location = graph.getPossibleObject(element, sr.ValveSymbol_textLocation); + String locationText; + if(location == null || sr.Bottom.equals(location)) { + locationText = "Bottom"; + } else if(sr.Top.equals(location)) { + locationText = "Top"; + } else if(sr.Left.equals(location)) { + locationText = "Left"; + } else { + locationText = "Right"; + } + SysdynElementUtils.setValveTextLocation(e, locationText); + + + ResizeRectangularSceneGraph resize = e.getElementClass().getSingleItem(ResizeRectangularSceneGraph.class); + if(resize != null) { + + if(location == null || sr.Bottom.equals(location)) { + resize.setYTranslateEdge(TranslateEdge.NORTH); + resize.setXTranslateEdge(TranslateEdge.NONE); + } else if(sr.Top.equals(location)) { + resize.setYTranslateEdge(TranslateEdge.SOUTH); + resize.setXTranslateEdge(TranslateEdge.NONE); + } else if(sr.Left.equals(location)) { + resize.setYTranslateEdge(TranslateEdge.NONE); + resize.setXTranslateEdge(TranslateEdge.EAST); + } else { + resize.setYTranslateEdge(TranslateEdge.NONE); + resize.setXTranslateEdge(TranslateEdge.WEST); + } + } + + } + + /** + * @param valveSize + * @param rotated true for vertical valve, false + * for horizontal + * @return + */ + private static Path2D createShape(double valveSize, boolean rotated) { + Path2D path = new Path2D.Double(); + path.moveTo(-valveSize, -valveSize); + if(rotated) { + path.lineTo(-valveSize, +valveSize); + path.lineTo(+valveSize, -valveSize); + } else { + path.lineTo(+valveSize, -valveSize); + path.lineTo(-valveSize, +valveSize); + } + path.lineTo(+valveSize, +valveSize); + path.closePath(); + return path; + } + + public static class ValveText extends SysdynTextElementNoBounds { + private static final long serialVersionUID = -5354779831383095960L; + + public static ValveText INSTANCE = new ValveText(); + + public ValveText() { + super(0, 0, Alignment.CENTER, 0, 1, 1, true); + } + + @Override + public void init(IElement e, G2DParentNode parent) { + super.init(e, parent); + + TextNode text = e.getHint(TextElementNoBounds.SG_NODE); + HoverShapeNode valve = e.getHint(ValveSceneGraph.VALVE_SG_NODE); + if(valve != null && text != null) { + Rectangle2D textBounds = text.getBoundsInLocal(); + Rectangle2D valveBounds = valve.getBoundsInLocal(); + AffineTransform at = (AffineTransform) text.getTransform().clone(); + at.translate( + getTextXTranslate(e, textBounds, valveBounds), + getTextYTranslate(e, textBounds, valveBounds)); + text.setTransform(at); + } + + } + + private static double getTextXTranslate(IElement e, Rectangle2D textBounds, Rectangle2D valveBounds) { + String location = e.getHint(SysdynElementHints.KEY_LOCATION); + if(location.equals("Bottom")) { + return -textBounds.getCenterX(); + } else if(location.equals("Top")) { + return -textBounds.getCenterX(); + } else if(location.equals("Left")) { + return -textBounds.getMaxX() - valveBounds.getWidth() / 2; + } else { + return valveBounds.getMaxX() - textBounds.getMinX(); + } + } + + private static double getTextYTranslate(IElement e, Rectangle2D textBounds, Rectangle2D valveBounds) { + String location = e.getHint(SysdynElementHints.KEY_LOCATION); + if(location.equals("Bottom")) { + return valveBounds.getMaxY() - textBounds.getMinY(); + } else if(location.equals("Top")) { + return valveBounds.getMinY() - textBounds.getMaxY(); + } else if(location.equals("Left")) { + return -textBounds.getCenterY(); + } else { + return -textBounds.getCenterY(); + } + } + } + + public static class ValveBounds implements InternalSize { + private static final long serialVersionUID = -666692270776359301L; + + public static final ValveBounds INSTANCE = new ValveBounds(); + + @Override + public Rectangle2D getBounds(IElement e, Rectangle2D size) { + TextNode textNode = e.getHint(TextElementNoBounds.SG_NODE); + ValveSceneGraph valveSG = e.getElementClass().getSingleItem(ValveSceneGraph.class); + + if(textNode != null && valveSG != null) { + try { + AffineTransform elementTransform = ElementUtils.getTransform(e); + AffineTransform nodeTransform = textNode.getTransform(); + + AffineTransform elementTransformInverse = elementTransform.createInverse(); + elementTransformInverse.concatenate(nodeTransform); + + Rectangle2D text = textNode.getBoundsInLocal(); + Shape textShape = elementTransformInverse.createTransformedShape(text); + + Rectangle2D valve = valveSG.getValveBounds(e, new Rectangle2D.Double()); + + size.setRect(textShape.getBounds2D()); + size.add(valve); + return size; + } catch (NoninvertibleTransformException e1) { + e1.printStackTrace(); + } + } + // FallBack + Path2D path = createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED))); + return path.getBounds2D(); + } + + } + + public static class ValveSceneGraph implements SceneGraph { + private static final long serialVersionUID = 7987939328158347639L; + + public static final ValveSceneGraph INSTANCE = new ValveSceneGraph(); + + private static final Key VALVE_SG_NODE = new SceneGraphNodeKey(ShapeNode.class, "VALVE_SHAPE_NODE"); + + private IHintListener hoverHintListener; + + @Override + public void init(IElement e, G2DParentNode parent) { + final HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, VALVE_SG_NODE, "valveShape", HoverShapeNode.class); + + // Calculate borders from text node bounds. + node.setStroke(STROKE); + node.setScaleStroke(true); + Color color = e.getHint(ElementHints.KEY_TEXT_COLOR); + node.setColor(color != null ? color : Color.BLACK); + boolean rotated = false; + String orientation = SysdynElementUtils.getOrientation(e); + if(orientation != null && orientation.equals("Vertical")) + rotated = true; + node.setShape(createShape(VALVE_SIZE, Boolean.TRUE.equals(rotated))); + Boolean hover = e.getHint(ElementHints.KEY_HOVER); + node.setHover(hover != null ? hover : false); + + AffineTransform at = ElementUtils.getTransform(e); + if(at != null) + node.setTransform(at); + + + hoverHintListener = new IHintListener() { + + @Override + public void hintRemoved(IHintObservable sender, Key key, Object oldValue) { + + } + + @Override + public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { + IElement e = (IElement)sender; + HoverShapeNode shape = (HoverShapeNode) e.getHint(VALVE_SG_NODE); + if(shape == null) { + return; + } + boolean hover = ElementUtils.isHovering(e); + shape.setHover(hover); + } + }; + e.addHintListener(hoverHintListener); + } + + @Override + public void cleanup(IElement e) { + e.removeHintListener(hoverHintListener); + ElementUtils.removePossibleNode(e, VALVE_SG_NODE); + } + + + public Rectangle2D getValveBounds(IElement e, Rectangle2D size) { + if (size == null) + size = new Rectangle2D.Double(); + + HoverShapeNode node = e.getHint(VALVE_SG_NODE); + if(node != null) { + size.setFrame(node.getBoundsInLocal()); + } else { + size.setFrame(createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED))).getBounds2D()); + } + + // Add some padding to the valve + double padding = 1; + size.setFrame(size.getX() - padding, size.getY() - padding, size.getWidth() + padding * 2, size.getHeight() + padding * 2); + return size; + } + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java new file mode 100644 index 00000000..afac8e42 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java @@ -0,0 +1,57 @@ +package org.simantics.sysdyn.ui.elements; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.diagram.elements.TextElementNoBounds; +import org.simantics.diagram.elements.TextNode; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.impl.BoundsOutline; +import org.simantics.sysdyn.ui.elements.ValveFactory.ValveSceneGraph; + +public class ValveOutline extends BoundsOutline { + + public static final BoundsOutline INSTANCE = new ValveOutline(); + + private static final long serialVersionUID = 5544256245734478634L; + + public ValveOutline() { + super(); + } + + @Override + public Shape getElementShape(IElement e) { + TextNode textNode = e.getHint(TextElementNoBounds.SG_NODE); + ValveSceneGraph valveSG = e.getElementClass().getSingleItem(ValveSceneGraph.class); + + if(textNode != null && valveSG != null) { + try { + AffineTransform elementTransform = ElementUtils.getTransform(e); + AffineTransform nodeTransform = textNode.getTransform(); + + AffineTransform elementTransformInverse = elementTransform.createInverse(); + elementTransformInverse.concatenate(nodeTransform); + + Rectangle2D text = textNode.getBoundsInLocal(); + Shape textShape = elementTransformInverse.createTransformedShape(text); + + Rectangle2D valve = valveSG.getValveBounds(e, new Rectangle2D.Double()); + + Path2D path = new Path2D.Double(textShape); + path.append(valve, false); + + return path; + } catch (NoninvertibleTransformException e1) { + e1.printStackTrace(); + } + } + + InternalSize b = e.getElementClass().getSingleItem(InternalSize.class); + return b.getBounds(e, new Rectangle2D.Double()); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveTextLocation.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveTextLocation.java new file mode 100644 index 00000000..8957e437 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveTextLocation.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.ElementHandler; + +public class ValveTextLocation implements ElementHandler { + + private static final long serialVersionUID = 7123851901569461658L; + + public static final ValveTextLocation INSTANCE = new ValveTextLocation(); + + public String getTextLocation(IElement e) { + return e.getHint(SysdynElementHints.KEY_LOCATION); + } + + + public void setTextLocation(IElement e, String location) { + if (location != null) + e.setHint(SysdynElementHints.KEY_LOCATION, location); + else + e.removeHint(SysdynElementHints.KEY_LOCATION); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/WholeElementTerminals.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/WholeElementTerminals.java new file mode 100644 index 00000000..ff409fe1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/WholeElementTerminals.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements; + +import java.awt.Shape; +import java.util.Collection; + +import org.simantics.g2d.diagram.handler.Topology.Terminal; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.Terminals; + +/** + * @author Tuukka Lehtonen + */ +public class WholeElementTerminals extends Terminals { + + private static final long serialVersionUID = -8209833430671135001L; + + public WholeElementTerminals(Collection ts) { + super(ts); + } + + @Override + public Shape getTerminalShape(IElement node, Terminal t) { + // For each terminal, return the shape of the element. + return ElementUtils.getElementShapeOrBounds(node); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java new file mode 100644 index 00000000..c054d41b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import java.awt.Shape; + +public class Arcs { + + public static final double PI2 = Math.PI*2.0; + + /** + * Returns angle + 2PI * n such that the + * result is between -PI and PI. + */ + public static double normalizeAngle(double angle) { + return Math.IEEEremainder(angle, PI2); + } + + /** + * Returns true, if three normalized angles are clockwise oriented. + */ + public static boolean areClockwiseOrdered(double angle1, double angle2, double angle3) { + //System.out.println(angle1 + " " + angle2 + " " + angle3); + return angle1 < angle2 + ? (angle2 < angle3 || angle3 < angle1) + : (angle2 < angle3 && angle3 < angle1) + ; + } + + /** + * Returns an angle in radians between straight line from (x0,y0) to (x2,y2) + * and an arc from (x0,y0) to (x2,y2) thru (x1,y1). The angle + * is measured at (x0,y0) and is between -PI and PI. + */ + public static double angleOfArc( + double x0, double y0, + double x1, double y1, + double x2, double y2) { + double dx0 = x1-x0; + double dy0 = y1-y0; + double dx1 = x1-x2; + double dy1 = y1-y2; + double dx = x2-x0; + double dy = y2-y0; + // Length of cross product (p1-p0)x(p2-p0) + double dd = dx0*dy - dy0*dx; + + if(Math.abs(dd) < 1e-6) // Points are (almost) collinear + return 0.0; + else { + // (p1-p0)*(p1-p2) / dd + double offset = (dx0*dx1 + dy0*dy1) / dd; + double angle = Math.PI*0.5 - Math.atan(offset); + if(dd > 0.0) + angle = angle-Math.PI; + return angle; + + } + } + + /** + * + * @param startX Start point x coord + * @param startY Start point y coord + * @param cx Center of the circle x coord + * @param cy Center of the circle y coord + * @param r Radius of the circle + * @param curAngle Start angle + * @param endBounds Shape + * @param dir direction to which is iterated + * @param move amount of which is iterated + * @param noOfIteration current number of itartion + * @param turn true iff we are increasing the angle + * @param crossed true if we have crossed the boundary we're targeting + * @return new angle + */ + private static double iterateAngle(double startX, double startY, + double cx, double cy, double r, + double curAngle, Shape endBounds, boolean dir, double move, + int noOfIteration, boolean turn, boolean crossed) { + // Do this many steps + if (noOfIteration > 16) + return normalizeAngle(curAngle); + + if (crossed) // When we have crossed the boundary, start split half method + move *= 0.5; + double x_rad, y_rad; + if (dir != turn) { // The direction of iteration is based on dir and turn bits + x_rad = startX + (move * Math.sin(curAngle)); + y_rad = startY + (move * Math.cos(curAngle)); + } else { + x_rad = startX - (move * Math.sin(curAngle)); + y_rad = startY - (move * Math.cos(curAngle)); + } + curAngle = -Math.atan((y_rad-cy)/(x_rad-cx)); + if (x_rad-cx < 0) + curAngle += Math.PI; + curAngle = normalizeAngle(curAngle); + + if (endBounds.contains(x_rad, y_rad)) { + return iterateAngle(x_rad, y_rad, + cx,cy,r,curAngle,endBounds,dir, move, noOfIteration+1, false, crossed); + } + else { + // Crossed is hereafter true + return iterateAngle(x_rad, y_rad, + cx,cy,r,curAngle,endBounds,dir, move, noOfIteration+1, true, true); + } + } + + /** + * + * @param cx x coord of the center point of the circle + * @param cy y coord of the center point of the circle + * @param r radius of the circle + * @param curAngle angle of the arc + * @param endBounds bounding shape + * @param dir direction of the arc + * @return + */ + public static double nextIntersectingAngle(double cx, double cy, double r, + double curAngle, Shape endBounds, boolean dir) { + // Move this much per iteration till the border is crossed. + double move = 3.0; + return iterateAngle(endBounds.getBounds2D().getCenterX(), + endBounds.getBounds2D().getCenterY(), + cx,cy,r,curAngle,endBounds,dir,move, 0, false, false); + } + + public static boolean hitTest(Shape beginBounds, Shape endBounds, double angle, double x, double y, double tolerance) { + + boolean clockWise = angle > 0; + + double x0 = beginBounds.getBounds2D().getCenterX(); + double y0 = beginBounds.getBounds2D().getCenterY(); + double x1 = endBounds.getBounds2D().getCenterX(); + double y1 = endBounds.getBounds2D().getCenterY(); + + double offset = + Math.abs(angle) < 1.0e-6 + ? 1e3 * Math.signum(angle) + : Math.tan(Math.PI*0.5-angle)*0.5; + double cx = 0.5*(x0+x1) + offset * (y1-y0); + double cy = 0.5*(y0+y1) + offset * (x0-x1); + double dx0 = x0 - cx; + double dy0 = y0 - cy; + double dx1 = x1 - cx; + double dy1 = y1 - cy; + double r = Math.sqrt(dx0*dx0 + dy0*dy0); + double angle0 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy0, dx0), beginBounds, angle < 0.0); + double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy1, dx1), endBounds, angle > 0.0); + + double dx = x-cx; + double dy = y-cy; + double dist = dx*dx + dy*dy; + + //System.out.println("HitTest: x0=" + x0 + " y0=" + y0 + " y=" + y + " x=" + x + " dist=" + dist + " r2=" + r*r); + + double tolerance2 = tolerance * tolerance; + if(dist < (r+tolerance2)*(r+tolerance2) && + dist > (r-tolerance2)*(r-tolerance2)) { + double ang = Arcs.normalizeAngle(Math.atan2(-dy, dx)); + //System.out.println("test " + angle0 + " " + ang + " " + angle1); + if(Arcs.areClockwiseOrdered(angle0, ang, angle1) == clockWise) { + //System.out.println("hit"); + return true; + } + } + + return false; + + } + + /** + * Calculates the radial distance between an arc and a point + * @param beginBounds Begin coordinate of the arc + * @param endBounds End coordinate of the arc + * @param angle The central angle of the arc + * @param x x coordinate of the measured point + * @param y x coordinate of the measured point + * @return The radial distance between the the arc and (x,y); Double.NaN if the + * distance is not real. + */ + public static double getRadialDistance(Shape beginBounds, + Shape endBounds, double angle, double x, double y) { + + boolean clockWise = angle > 0; + + double x0 = beginBounds.getBounds2D().getCenterX(); + double y0 = beginBounds.getBounds2D().getCenterY(); + double x1 = endBounds.getBounds2D().getCenterX(); + double y1 = endBounds.getBounds2D().getCenterY(); + + double offset = + Math.abs(angle) < 1.0e-6 + ? 1e3 * Math.signum(angle) + : Math.tan(Math.PI*0.5-angle)*0.5; + double cx = 0.5*(x0+x1) + offset * (y1-y0); + double cy = 0.5*(y0+y1) + offset * (x0-x1); + double dx0 = x0 - cx; + double dy0 = y0 - cy; + double dx1 = x1 - cx; + double dy1 = y1 - cy; + double r = Math.sqrt(dx0*dx0 + dy0*dy0); + double angle0 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy0, dx0), beginBounds, angle < 0.0); + double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy1, dx1), endBounds, angle > 0.0); + + double dx = x-cx; + double dy = y-cy; + double dist2 = dx*dx + dy*dy; + + double ang = Arcs.normalizeAngle(Math.atan2(-dy, dx)); + if(!Arcs.areClockwiseOrdered(angle0, ang, angle1) == clockWise) { + return Double.NaN; + } + return Math.abs(Math.sqrt(dist2) - r); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/ConnectionClasses.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/ConnectionClasses.java new file mode 100644 index 00000000..310c59f4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/ConnectionClasses.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +public class ConnectionClasses { + + public static final Object CONNECTION = new Object() { + public String toString() { return "CONNECTION"; } + }; + + public static final Object FLAG = new Object() { + public String toString() { return "FLAG"; } + }; + + public static final Object FLOW = new Object() { + public String toString() { return "FLOW"; } + }; + + public static final Object DEPENDENCY = new Object() { + public String toString() { return "DEPENDENCY"; } + }; +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyConnectionFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyConnectionFactory.java new file mode 100644 index 00000000..3f757a08 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyConnectionFactory.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import java.awt.Color; +import java.awt.Font; +import java.util.HashMap; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.resource.StringConverter; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; +import org.simantics.databoard.Bindings; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.AsyncMultiProcedure; +import org.simantics.db.procedure.AsyncProcedure; +import org.simantics.db.procedure.SyncProcedure; +import org.simantics.diagram.G2DUtils; +import org.simantics.diagram.adapter.ElementFactoryAdapter; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.editor.routing.DependencyRouter; +import org.simantics.sysdyn.ui.preferences.SysdynDiagramPreferences; +import org.simantics.sysdyn.ui.preferences.SysdynDiagramPropertyExternalRead; +import org.simantics.utils.datastructures.Pair; + +/** + * An element class for single connection entity elements. A connection entity + * consists of connection edge segments and branch points as its children. + * + * @author Tuukka Lehtonen + */ +public class DependencyConnectionFactory extends ElementFactoryAdapter { + + public static final ElementClass CLASS = SysdynConnectionClass.CLASS; + + @Override + public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, final AsyncProcedure procedure) { + procedure.execute(graph, SysdynConnectionClass.CLASS.newClassWith(false, new StaticObjectAdapter(elementType))); + } + + @Override + protected Resource getElementClassBaseType(AsyncReadGraph graph) { + return graph.getService(DiagramResource.class).Connection; + } + + @Override + public void load(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, final Resource elementResource, + final IElement element, final AsyncProcedure procedure) { + + final AtomicInteger ready = new AtomicInteger(1); + final ConcurrentSkipListMap> properties = new ConcurrentSkipListMap>(); + + element.setHint(DiagramHints.ROUTE_ALGORITHM, DependencyRouter.INSTANCE); + + G2DResource G2D; + try { + G2D = G2DResource.getInstance(graph.getSession()); + } catch (DatabaseException e) { + e.printStackTrace(); + return; + } + + // Find possible font + graph.forPossibleStatement(elementResource, G2D.HasFont, new SyncProcedure() { + + @Override + public void execute(ReadGraph graph, Statement result) throws DatabaseException { + if(result != null && !result.isAsserted(elementResource)) { + element.setHint(ElementHints.KEY_FONT, G2DUtils.getFont(graph, result.getObject())); + } else { + String fontdata = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair(elementResource, SysdynDiagramPreferences.ARROW_FONT))); + if(fontdata != null) { + FontData[] fdArray = PreferenceConverter.basicGetFontData(fontdata); + if(fdArray != null) { + if(fdArray.length == 1) { + FontData fd = fdArray[0]; + if(fd != null) { + Font font = new Font(fd.getName(), fd.getStyle(), fd.getHeight()); + element.setHint(ElementHints.KEY_FONT, font); + } + } + } + } + + } + } + + @Override + public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException { + throwable.printStackTrace(); + } + }); + + // Find possible color + graph.forPossibleStatement(elementResource, G2D.HasColor, new SyncProcedure() { + + @Override + public void execute(ReadGraph graph, Statement result) throws DatabaseException { + if(result != null && !result.isAsserted(elementResource)) { + element.setHint(ElementHints.KEY_TEXT_COLOR, G2DUtils.getColor(graph, result.getObject())); + } else { + String color = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair(elementResource, SysdynDiagramPreferences.ARROW_COLOR))); + if(color != null) { + RGB rgb = StringConverter.asRGB(color, null); + if(rgb != null) { + Color c = new Color(rgb.red, rgb.green, rgb.blue); + element.setHint(ElementHints.KEY_TEXT_COLOR, c); + } + } + + } + } + + @Override + public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException { + throwable.printStackTrace(); + } + }); + + + // A complicated-looking procedure for obtaining all HasProperties to properties map + graph.forEachPredicate(elementResource, new AsyncMultiProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, final Resource property) { + + ready.incrementAndGet(); + Layer0 l0; + try { + l0 = Layer0.getInstance(graph.getSession()); + } catch (DatabaseException e) { + e.printStackTrace(); + return; + } + + graph.forIsSubrelationOf(property, l0.HasProperty, new AsyncProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, final Boolean isProperty) { + + if(isProperty) { + + graph.forPossibleRelatedValue(elementResource, property, new AsyncProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, final Object value) { + + Layer0 l0; + try { + l0 = Layer0.getInstance(graph.getSession()); + } catch (DatabaseException e) { + e.printStackTrace(); + return; + } + + graph.forPossibleRelatedValue(property, l0.HasName, Bindings.STRING, new AsyncProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, String name) { + + properties.put(name, Pair.make(property, value)); + if(ready.decrementAndGet() == 0) { + element.setHint(DiagramHints.PROPERTIES, new HashMap>(properties)); + procedure.execute(graph, element); + } + + } + + }); + + } + + }); + + + } else { + + if(ready.decrementAndGet() == 0) { + element.setHint(DiagramHints.PROPERTIES, new HashMap>(properties)); + procedure.execute(graph, element); + } + + } + + } + + }); + } + + @Override + public void finished(AsyncReadGraph graph) { + + if(ready.decrementAndGet() == 0) { + element.setHint(DiagramHints.PROPERTIES, new HashMap(properties)); + procedure.execute(graph, element); + } + + } + + }); + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeClass.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeClass.java new file mode 100644 index 00000000..5b86bd99 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeClass.java @@ -0,0 +1,273 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.HashMap; +import java.util.Map; + +import org.simantics.db.Resource; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.DiagramMutator; +import org.simantics.g2d.diagram.DiagramUtils; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy; +import org.simantics.g2d.diagram.handler.Topology; +import org.simantics.g2d.diagram.handler.Topology.Connection; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.SceneGraphNodeKey; +import org.simantics.g2d.element.handler.EdgeVisuals; +import org.simantics.g2d.element.handler.EdgeVisuals.ArrowType; +import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd; +import org.simantics.g2d.element.handler.Pick; +import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.g2d.element.handler.TerminalLayout; +import org.simantics.g2d.element.handler.Transform; +import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals; +import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; +import org.simantics.g2d.element.handler.impl.FillColorImpl; +import org.simantics.g2d.element.handler.impl.ParentImpl; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.elementclass.connection.EdgeClass.EdgeHandler; +import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform; +import org.simantics.g2d.utils.Alignment; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.sysdyn.ui.editor.routing.DependencyRouter; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.datastructures.hints.IHintContext.Key; + +public class DependencyEdgeClass { + + public static final float DEFAULT_STROKE_WIDTH = 0.3f; + + private static class NodePick implements Pick { + + private static final long serialVersionUID = 1L; + + public static NodePick INSTANCE = new NodePick(); + + @Override + public boolean pickTest(IElement e, Shape s, PickPolicy policy) { + Rectangle2D pickRect = null; + if (s instanceof Rectangle2D) + pickRect = (Rectangle2D) s; + else + // FIXME: suboptimal, but works. + pickRect = s.getBounds2D(); + + DependencyNode node = e.getHint(SysdynEdgeSceneGraph.KEY_SG_NODE); + if(node == null) { + return false; + } + return Arcs.hitTest(node.getBeginBounds(), node.getEndBounds(), node.getAngle(), pickRect.getCenterX(), pickRect.getCenterY(), 1.7); + + } + + } + + public static final ElementClass CLASS = + ElementClass.compile( + SysdynEdgeSceneGraph.INSTANCE, + EdgeHandler.INSTANCE, + new ConfigurableEdgeVisuals( + ArrowType.None, ArrowType.Fill, + new BasicStroke(DEFAULT_STROKE_WIDTH, + BasicStroke.CAP_BUTT, + BasicStroke.JOIN_ROUND, + 10.0f, null, 0.0f) + , 1.0, 1.0), + FillColorImpl.BLACK, + FixedTransform.INSTANCE, + TextImpl.INSTANCE, + TextColorImpl.BLACK, + TextFontImpl.DEFAULT, + NodePick.INSTANCE, + ConnectionSelectionOutline.INSTANCE, + SimpleElementLayers.INSTANCE, + ParentImpl.INSTANCE + ).setId("EdgeClass.STRAIGHT"); + + public static class SysdynEdgeSceneGraph implements SceneGraph { + + private static final long serialVersionUID = 2914383071126238996L; + + public static final SysdynEdgeSceneGraph INSTANCE = new SysdynEdgeSceneGraph(); + + public static final Stroke ARROW_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); + + public static final Key KEY_SG_NODE = new SceneGraphNodeKey(DependencyNode.class, "EDGE_NODE"); + + @Override + public void init(IElement e, G2DParentNode parent) { + DependencyNode node = ElementUtils.getOrCreateNode(e, parent, KEY_SG_NODE, "edge_" + e.hashCode(), DependencyNode.class); + + Font font = ElementUtils.getTextFont(e); + Color color = ElementUtils.getTextColor(e); + + HashMap properties = e.getHint(DiagramHints.PROPERTIES); + Pair polarityPair = (Pair)properties.get("polarity"); + Pair polarityLocationPair = (Pair)properties.get("polarityLocation"); + boolean delayMark = properties.containsKey("delayMark"); + boolean arrowHead = !properties.containsKey("hideArrow"); + + String location; + if(polarityLocationPair == null) + location = DependencyNode.INSIDE; + else + location = (String) polarityLocationPair.second; + + String text = polarityPair != null ? (String) polarityPair.second : ""; + node.init(text, location, delayMark, arrowHead, font, color, 0, 0, 0.235); + + update(e); + } + + @Override + public void cleanup(IElement e) { + ElementUtils.removePossibleNode(e, KEY_SG_NODE); + } + + public void update(final IElement e) { + + DependencyNode node = e.getHint(KEY_SG_NODE); + if(node == null) return; + final IDiagram diagram = ElementUtils.peekDiagram(e); + + node.setFieldListener(new PropertyChangeListener() { + + @Override + public void propertyChange(final PropertyChangeEvent event) { + + String field = event.getPropertyName(); + Map> properties = e.getHint(DiagramHints.PROPERTIES); + if(properties == null) return; + final Pair property = properties.get(field); + if(property == null) return; + + DiagramUtils.mutateDiagram(diagram, new Callback() { + + @Override + public void run(DiagramMutator mutator) { + mutator.modifyProperty(e, property.first, event.getNewValue()); + } + + }); + + } + + }); + + + + Shape beginTerminalShape = null; + Shape endTerminalShape = null; + if (diagram != null) { + Topology topology = diagram.getDiagramClass().getAtMostOneItemOfClass(Topology.class); + if (topology != null) { + Connection beginConnection = topology.getConnection(e, EdgeEnd.Begin); + Connection endConnection = topology.getConnection(e, EdgeEnd.End); + beginTerminalShape = getCanvasTerminalShape(beginConnection); + endTerminalShape = getCanvasTerminalShape(endConnection); + } + } + + if(beginTerminalShape == null || endTerminalShape == null) return; + + EdgeVisuals vh = e.getElementClass().getSingleItem(EdgeVisuals.class); + Map> properties = e.getHint(DiagramHints.PROPERTIES); + Pair strokeWidthPair = properties.get("strokeWidth"); + + float strokeWidth; + if(strokeWidthPair == null) + strokeWidth = DEFAULT_STROKE_WIDTH; + else + strokeWidth = (Float)strokeWidthPair.second; + + vh.setStroke(e, new BasicStroke(strokeWidth, + BasicStroke.CAP_BUTT, + BasicStroke.JOIN_MITER, + 10.0f, null, 0.0f)); + Stroke stroke = vh.getStroke(e); + Font font = ElementUtils.getTextFont(e); + Color color = ElementUtils.getTextColor(e); +// Color fillColor = ElementUtils.getFillColor(e); + Color borderColor = ElementUtils.getBorderColor(e, Color.BLACK); +// String text = ElementUtils.getText(e); + Alignment hAlign = ElementUtils.getHintOrDefault(e, ElementHints.KEY_HORIZONTAL_ALIGN, Alignment.CENTER); + node.setBackgroundColor(null); + node.setBorderColor(borderColor); + node.setHorizontalAlignment((byte) hAlign.ordinal()); + node.setPadding(0, 0); + node.setBorderWidth((float) 0); + node.setEditable(false); + node.setFont(font); + + node.setBeginBounds(beginTerminalShape); + node.setEndBounds(endTerminalShape); + node.setStroke(stroke); + node.setColor(color); + node.setShapes(DependencyRouter.createArrowShape(node.getShapes(), node.getBeginBounds(), node.getEndBounds(), node.getAngle(), node.getStroke())); + + if(properties != null) { + for(Map.Entry> entry : properties.entrySet()) { + NodeUtil.setPropertyIfSupported(entry.getKey(), entry.getValue().second, node); +// node.setProperty(entry.getKey(), entry.getValue().second); +// System.out.println("setProperty " + entry.getKey() + " => " + entry.getValue().second); + } + } + EdgeHandler eh = e.getElementClass().getAtMostOneItemOfClass(EdgeHandler.class); + Path2D path = eh.getPath(e); + if(path == null) + path = new Path2D.Double(); + else + path.reset(); + path.append(node.getShapes().first, false); + eh.setPath(e, path); + + } + + private static Shape getCanvasTerminalShape(Connection connection) { + if (connection != null && connection.node != null && connection.terminal != null) { + TerminalLayout layout = connection.node.getElementClass().getAtMostOneItemOfClass(TerminalLayout.class); + if (layout != null) { + //return layout.getTerminalShape(connection.node, connection.terminal); + Shape shp = layout.getTerminalShape(connection.node, connection.terminal); + Transform tr = connection.node.getElementClass().getAtMostOneItemOfClass(Transform.class); + if (tr == null) + return shp; + + return tr.getTransform(connection.node).createTransformedShape(shp); + + } + } + return null; + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeFactory.java new file mode 100644 index 00000000..e8f1b89f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeFactory.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.procedure.AsyncProcedure; +import org.simantics.diagram.adapter.ElementFactoryAdapter; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; + +/** + * An element class factory for sysdyn dependency connection edge segments. + * + * @author Tuukka Lehtonen + */ +public class DependencyEdgeFactory extends ElementFactoryAdapter { + + private static final ElementClass CLASS = DependencyEdgeClass.CLASS; + + @Override + public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, + AsyncProcedure procedure) { + procedure.execute(graph, CLASS); + } + + @Override + public void getClass(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource, + AsyncProcedure procedure) { + procedure.execute(graph, CLASS); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java new file mode 100644 index 00000000..96681fcb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java @@ -0,0 +1,409 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.Arc2D; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Collection; +import java.util.HashMap; + +import org.simantics.diagram.elements.TextNode; +import org.simantics.g2d.utils.Alignment; +import org.simantics.scenegraph.ISelectionPainterNode; +import org.simantics.scenegraph.g2d.IG2DNode; +import org.simantics.scenegraph.g2d.events.EventTypes; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent; +import org.simantics.scenegraph.g2d.nodes.ConnectionNode; +import org.simantics.scenegraph.g2d.nodes.SingleElementNode; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.sysdyn.ui.editor.routing.DependencyRouter; +import org.simantics.sysdyn.ui.elements.LoopNode.ILoopComponentNode; +import org.simantics.sysdyn.ui.elements.LoopNode; +import org.simantics.sysdyn.ui.elements.SysdynElementHints; +import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils; +import org.simantics.utils.datastructures.Triple; + +/** + * Node for dependency arrows and polarity text + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class DependencyNode extends TextNode implements ISelectionPainterNode, ILoopComponentNode { + + public static final String INSIDE = "Inside"; + public static final String OUTSIDE = "Outside"; + + public static final double HITMARGIN = 1.7; + + private static final long serialVersionUID = 1294351381209071074L; + + private Color color; + private Stroke stroke; + private Shape beginBounds; + private Shape endBounds; + private double angle = 0.1; + private String side; + private boolean delayMark = false; + private boolean arrowHead = true; + private transient Triple shapes = new Triple(new Arc2D.Double(), new Path2D.Double(), new Path2D.Double()); + + transient public boolean hover = false; + private boolean dragging = false; + + private transient PropertyChangeListener fieldListener = null; + + @Override + public void init() { + super.init(); + addEventHandler(this); + + } + + + /** + * Inits the dependency node with a text + * @param text Polarity + * @param side Polarity Location + * @param font Font + * @param color Color + * @param x Text initial location x + * @param y Text initial location y + * @param scale Scale + */ + public void init(String text, String side, boolean delayMark, boolean arrowHead, Font font, Color color, double x, double y, double scale) { + super.init(text, font, color, x, y, scale); + this.side = side; + this.delayMark = delayMark; + this.arrowHead = arrowHead; + setHorizontalAlignment((byte) Alignment.CENTER.ordinal()); + setVerticalAlignment((byte) Alignment.CENTER.ordinal()); + } + + @Override + public void cleanup() { + super.cleanup(); + } + + public void setFieldListener(PropertyChangeListener listener) { + this.fieldListener = listener; + } + + @ServerSide + public void commitProperty(String field, Object value) { + if(fieldListener != null) { + fieldListener.propertyChange(new PropertyChangeEvent(this, field, null, value)); + } + } + + @PropertySetter("color") + @SyncField("color") + public void setColor(Color color) { + this.color = color; + } + + @PropertySetter("stroke") + @SyncField("stroke") + public void setStroke(Stroke stroke) { + this.stroke = stroke; + } + + @PropertySetter("beginBounds") + @SyncField("beginBounds") + public void setBeginBounds(Shape beginBounds) { + this.beginBounds = beginBounds; + } + + @PropertySetter("endBounds") + @SyncField("endBounds") + public void setEndBounds(Shape endBounds) { + this.endBounds = endBounds; + } + + @PropertySetter("angle") + @SyncField("angle") + public void setAngle(Double angle) { + this.angle = angle.doubleValue(); + if(this.beginBounds != null && this.endBounds != null) + this.shapes = DependencyRouter.createArrowShape(this.shapes, this.beginBounds, this.endBounds, this.angle, this.stroke); + } + + @PropertySetter("shapes") + @SyncField("shapes") + public void setShapes(Triple shapes) { + this.shapes = shapes; + } + + public Color getColor() { + return color; + } + + public Stroke getStroke() { + return stroke; + } + + public Shape getBeginBounds() { + return beginBounds; + } + + public Shape getEndBounds() { + return endBounds; + } + + public double getAngle() { + return angle; + } + + public Triple getShapes() { + return shapes; + } + + + + @Override + public void render(Graphics2D g) { + if(beginBounds == null || endBounds == null) return; + + // Removed to let the global control handle rendering quality issues. + //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + boolean selected = NodeUtil.isSelected(this, 2); + if(font != null) g.setFont(font); + if(selected) { + g.setColor(Color.PINK); + float strokeWidth = 1.4f + 2 * (stroke instanceof BasicStroke ? ((BasicStroke)stroke).getLineWidth() : DependencyEdgeClass.DEFAULT_STROKE_WIDTH); + g.setStroke(new BasicStroke(strokeWidth)); + g.draw(shapes.first); + g.fill(shapes.second); + if(color != null) g.setColor(color); + g.setStroke(stroke); + g.draw(shapes.first); + if (arrowHead) { + g.draw(shapes.second); + g.fill(shapes.second); + } + if (delayMark) g.draw(shapes.third); + } else if (hover){ + g.setColor(Color.LIGHT_GRAY); + float strokeWidth = 1.4f + 2 * (stroke instanceof BasicStroke ? ((BasicStroke)stroke).getLineWidth() : DependencyEdgeClass.DEFAULT_STROKE_WIDTH); + g.setStroke(new BasicStroke(strokeWidth)); + g.draw(shapes.first); + g.fill(shapes.second); + if(color != null) g.setColor(color); + g.setStroke(stroke); + g.draw(shapes.first); + if (arrowHead) { + g.draw(shapes.second); + g.fill(shapes.second); + } + if (delayMark) g.draw(shapes.third); + } else if (isLoopSelected()) { + g.setColor(LoopNode.HIGHLIGHT_COLOR); + if(stroke != null) g.setStroke(stroke); + g.draw(shapes.first); + if (arrowHead) { + g.draw(shapes.second); + g.fill(shapes.second); + } + if (delayMark) g.draw(shapes.third); + } else { + if(color != null) g.setColor(color); + if(stroke != null) g.setStroke(stroke); + g.draw(shapes.first); + if (arrowHead) { + g.draw(shapes.second); + g.fill(shapes.second); + } + if (delayMark) g.draw(shapes.third); + } + + double angleRad = angle > 0 ? + Math.toRadians(shapes.first.getAngleStart() + shapes.first.getAngleExtent()) : + Math.toRadians(shapes.first.getAngleStart()); + Point2D point = angle > 0 ? shapes.first.getEndPoint() : shapes.first.getStartPoint(); + + int angle1 = 220; + int angle2 = -40; + if(OUTSIDE.equals(side)) { + angle1 *= -1; + angle2 *= -1; + } + double a = Math.toRadians(angle < 0 ? angle1 : angle2); + double s = Math.sin(a) * 3; + double c = Math.cos(a) * 4; + + g.translate(point.getX(), point.getY()); + g.rotate(-angleRad); + g.translate(s, c); + g.rotate(angleRad); + super.render(g); + g.rotate(-angleRad); + g.translate(-s, -c); + g.rotate(angleRad); + g.translate(-point.getX(), -point.getY()); + + } + + boolean pressHit = false; + private HashMap loopSelectionMap = new HashMap(); + + private boolean isLoopSelected() { + return loopSelectionMap.containsValue(true); + } + + protected boolean hitTest(org.simantics.scenegraph.g2d.events.MouseEvent event, double tolerance) { + if(beginBounds == null || endBounds == null) return false; + Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double()); + return Arcs.hitTest(beginBounds, endBounds, angle, localPos.getX(), localPos.getY(), tolerance); + } + + protected double getRadialDistanse(Point2D coord) { + if(beginBounds == null || endBounds == null) return Double.NaN; + Point2D localPos = NodeUtil.worldToLocal(this, coord, new Point2D.Double()); + return Arcs.getRadialDistance(beginBounds, endBounds, angle, localPos.getX(), localPos.getY()); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + + @Override + public int getEventMask() { + return super.getEventMask() | EventTypes.MouseDragBeginMask + | EventTypes.MouseButtonPressedMask + | EventTypes.MouseButtonReleasedMask + ; + } + + @Override + protected boolean mouseMoved(MouseMovedEvent event) { + boolean hit = hitTest(event, HITMARGIN); + if(dragging) { + Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double()); + + setAngle(Arcs.angleOfArc( + beginBounds.getBounds2D().getCenterX(), beginBounds.getBounds2D().getCenterY(), + localPos.getX(), localPos.getY(), + endBounds.getBounds2D().getCenterX(), endBounds.getBounds2D().getCenterY())); + repaint(); + } + + if (hit != hover) { + hover = hit; + repaint(); + } + return false; + } + + private static boolean isEventDummy(MouseDragBegin e) { + if (e.controlPosition.distance(0, 0) == 0 + && e.screenPosition.distance(0, 0) == 0 + && e.buttons == 0) { + return true; + } else { + return false; + } + } + + @Override + protected boolean mouseDragged(MouseDragBegin e) { + // Get rid of dummy events from dragGestureRecognized + if (isEventDummy(e)) { + return false; + } + + // Disable dragging if LockSketch is ON + if (SysdynElementHints.LOCK_TOOL.equals(SysdynWorkbenchUtils.getSysdynToolMode())) + return false; + + //System.out.println(this.toString() + " event: " + e.toString()); + boolean selected = NodeUtil.isSelected(this, 2); + double myRadialDistance = this.getRadialDistanse(e.controlPosition); + Collection nodes = this.getParent().getParent().getParent().getNodes(); + if (!selected) { + for (Object temp1 : nodes) { + if (temp1 instanceof ConnectionNode) { + for ( IG2DNode temp2 : ((ConnectionNode)temp1).getNodes()) { + if (temp2 instanceof SingleElementNode) { + for ( IG2DNode temp3 : ((SingleElementNode)temp2).getNodes()) { + if (temp3 instanceof DependencyNode){ + DependencyNode otherDependencyNode = (DependencyNode)temp3; + if (otherDependencyNode == this) { + continue; + } + double otherNodeDist = otherDependencyNode.getRadialDistanse(e.controlPosition); + if (Double.isNaN(otherNodeDist)) { + continue; + } + if (otherDependencyNode.isDragging()) { + return true; + } + if (NodeUtil.isSelected(otherDependencyNode, 2) && (otherNodeDist < HITMARGIN)) { + return false; + } + if (otherNodeDist < myRadialDistance) { + return false; + } + } + } + } + } + } + } + } + if ( (myRadialDistance < HITMARGIN) && !dragging) { + dragging = true; + return true; + } + return false; + } + + @Override + protected boolean mouseButtonPressed(MouseButtonPressedEvent e) { + return false; + } + + protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) { + if(dragging) { + commitProperty("angle", angle); + dragging = false; + } + return false; + } + + protected boolean isDragging() { + return dragging; + } + + @Override + public void setLoopSelected(LoopNode loop, boolean selected) { + Boolean loopSelected = loopSelectionMap.get(loop); + if (loopSelected == null || loopSelected != selected) { + loopSelectionMap.put(loop, selected); + repaint(); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowArrowLineStyle.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowArrowLineStyle.java new file mode 100644 index 00000000..a48e700b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowArrowLineStyle.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Path2D; +import java.io.Serializable; +import java.util.StringTokenizer; + +import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle; + + +/** + * Copied from ArrowLLineEndStyle + */ +public class FlowArrowLineStyle implements ILineEndStyle, Serializable { + + private static final long serialVersionUID = 5348566089660986479L; + + public static enum ArrowType { None, Stroke, Fill } + + public static final double length = FlowConnectionStyle.DEFAULT_LINE_WIDTH * 4; + public static final double width = FlowConnectionStyle.DEFAULT_LINE_WIDTH * 2; + public static final double space = 0.0; + + protected ArrowType type; + protected Path2D path; + protected double lineEndLength; + protected Color color; + + public FlowArrowLineStyle(String desc, Color color) { + this.type = ArrowType.None; + this.lineEndLength = 0.0; + + double l = length; + double w = width; + double s = space; + + if(color != null) + this.color = color; + else + this.color = Color.BLACK; + + StringTokenizer tokenizer = new StringTokenizer(desc); + if (tokenizer.hasMoreTokens()) { + String type = tokenizer.nextToken(); + this.type = parseType(type); + + if (tokenizer.hasMoreTokens()) { + String ls = tokenizer.nextToken(); + l = parseSize(ls, length); + + if (tokenizer.hasMoreTokens()) { + String ws = tokenizer.nextToken(); + w = parseSize(ws, width); + + if (tokenizer.hasMoreTokens()) { + String ss = tokenizer.nextToken(); + s = parseSize(ss, space); + } + } + } + if (this.type != ArrowType.None) { + this.path = arrow(l, w, s); + lineEndLength = l+s; + } + } + } + + @Override + public void render(Graphics2D g, double x, double y, int dir) { + if (type == ArrowType.None || path == null) + return; + AffineTransform old = g.getTransform(); + g.translate(x, y); + g.rotate(dir*Math.PI*0.5); + g.setColor(color); + + switch (type) { + case Fill: + g.fill(path); + break; + case Stroke: + g.draw(path); + break; + default: + break; + } + + g.setTransform(old); + } + + @Override + public double getLineEndLength(int direction) { + return lineEndLength; + } + + private static Path2D arrow(double length, double width, double space) { + Path2D.Double path = new Path2D.Double(); + path.moveTo(-space, 0); + path.lineTo(-length-space, -width); + path.lineTo(-length-space, +width); + path.closePath(); + return path; + } + + private double parseSize(String size, double defaultValue) { + try { + return Double.parseDouble(size); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + private ArrowType parseType(String type) { + String lower = type.toLowerCase(); + if ("none".equals(lower)) + return ArrowType.None; + if ("stroke".equals(lower)) + return ArrowType.Stroke; + if ("fill".equals(lower)) + return ArrowType.Fill; + throw new IllegalArgumentException("unrecognized arrow type: " + type); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[" + type + ", " + path + "]"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowConnectionStyle.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowConnectionStyle.java new file mode 100644 index 00000000..a7476de6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowConnectionStyle.java @@ -0,0 +1,97 @@ +package org.simantics.sysdyn.ui.elements.connections; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.geom.Path2D; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.diagram.connection.rendering.BasicConnectionStyle; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements.LoopNode; +import org.simantics.ui.SimanticsUI; + +public class FlowConnectionStyle extends BasicConnectionStyle { + + private static final long serialVersionUID = 2777194644079591357L; + + Color lineColor; + Stroke lineStroke; + + private Resource resource; + + // Is the default color overridden by the loop color + private boolean loopColorOverride = false; + + public static final float DEFAULT_LINE_WIDTH = 1.0f; + + public FlowConnectionStyle(Color lineColor, Stroke lineStroke, Resource resource) { + super(lineColor, Color.BLACK, 0.5, lineStroke, lineStroke, 0.8); + this.lineColor = lineColor; + this.lineStroke = lineStroke; + this.resource = resource; + } + + @Override + public void drawBranchPoint(Graphics2D g, double x, double y) { + } + + @Override + public void drawLine(Graphics2D g, double x1, double y1, double x2, double y2, boolean isTransient) { + } + + @Override + public void drawPath(Graphics2D g, Path2D path, boolean isTransient) { + if (lineColor != null) // Highlight the flow if loop where the flow belongs to is selected. + g.setColor(loopColorOverride ? LoopNode.HIGHLIGHT_COLOR : lineColor); + if (lineStroke != null) + g.setStroke(lineStroke); + + // Fetch the width of the flow + Float width = DEFAULT_LINE_WIDTH; + try { + Float connectionWidth = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Float perform(ReadGraph graph) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if (resource == null) + return null; + return graph.getPossibleRelatedValue(resource, sr.FlowConnection_width, Bindings.FLOAT); + } + }); + if (connectionWidth != null) + width = connectionWidth; + } catch (DatabaseException e) { + e.printStackTrace(); + } + + Path2D p1 = Flows.createOffsetPath(path, width/2); + Path2D p2 = Flows.createOffsetPath(path, -width/2); + p1.append(p2, false); + g.draw(p1); + } + + @Override + public void drawDegeneratedLine(Graphics2D g, double x, double y, boolean isHorizontal, boolean isTransient) { + } + + @Override + public double getDegeneratedLineLength() { + return 0; + } + + /** + * Set if the flow color should be overwritten with loop color + * @param loopColorOverride + */ + public void setLoopColorOverride(boolean loopColorOverride) { + this.loopColorOverride = loopColorOverride; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Flows.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Flows.java new file mode 100644 index 00000000..a7c6bd9e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Flows.java @@ -0,0 +1,257 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; +import java.awt.geom.Rectangle2D; + +public class Flows { + + public static double ARROW_LENGTH = 3.2; + public static double ARROW_WIDTH = 2; + + static final double OFFSET = 1.0; + static final double ARROW_OFFSET = 3.2; + + public static Path2D createArrow(Path2D arrow, Rectangle2D tail, Rectangle2D head) { + + double x = tail.getCenterX(); + double y = tail.getCenterY(); + + double cx = head.getCenterX(); + double minx = head.getMinX(); + double maxx = head.getMaxX(); + double miny = head.getMinY(); + double maxy = head.getMaxY(); + + if(arrow == null) + arrow = new Path2D.Double(); + else + arrow.reset(); + + // approach from top + if (y < miny) { + arrow.moveTo(cx, miny); + arrow.lineTo(cx + ARROW_WIDTH, miny - ARROW_LENGTH); + arrow.lineTo(cx - ARROW_WIDTH, miny - ARROW_LENGTH); + } + + // approach from beneath + else if (y > maxy) { + arrow.moveTo(cx, maxy); + arrow.lineTo(cx + ARROW_WIDTH, maxy + ARROW_LENGTH); + arrow.lineTo(cx - ARROW_WIDTH, maxy + ARROW_LENGTH); + } + + // approach from left + else if (x < minx) { + arrow.moveTo(minx, y); + arrow.lineTo(minx - ARROW_LENGTH, y - ARROW_WIDTH); + arrow.lineTo(minx - ARROW_LENGTH, y + ARROW_WIDTH); + } + + // approach from right + else if (x > maxx) { + arrow.moveTo(maxx, y); + arrow.lineTo(maxx + ARROW_LENGTH, y - ARROW_WIDTH); + arrow.lineTo(maxx + ARROW_LENGTH, y + ARROW_WIDTH); + } + else + return null; // FIXME (HN) This is just a quick bugfix, didn't understand the logic completely + + arrow.closePath(); + + return arrow; + + } + + private static Path2D createLines(Path2D lines, boolean vertical, double ... coordinates) { + if(lines == null) + lines = new Path2D.Double(); + else + lines.reset(); + createOffsetLine(lines, vertical, OFFSET, coordinates); + createOffsetLine(lines, vertical, -OFFSET, coordinates); + return lines; + } + + public static Path2D createLines(Path2D lines, boolean hasArrow, Rectangle2D valve, Rectangle2D node) { + double x0 = valve.getCenterX(); + double y0 = valve.getCenterY(); + double x1 = node.getCenterX(); + double y1 = node.getCenterY(); + + double minY = hasArrow ? node.getMinY() - ARROW_OFFSET : node.getMinY(); + double maxY = hasArrow ? node.getMaxY() + ARROW_OFFSET : node.getMaxY(); + double minX = hasArrow ? node.getMinX() - ARROW_OFFSET : node.getMinX(); + double maxX = hasArrow ? node.getMaxX() + ARROW_OFFSET : node.getMaxX(); + + boolean rotated = false; + + if( rotated ) { + if(y1 > y0) + y0 += OFFSET; + else + y0 -= OFFSET; + if(node.getMinX() <= x0 && node.getMaxX() >= x0) { + if(y1 > y0) + return createLines(lines, true, y0, x0, minY); + else + return createLines(lines, true, y0, x0, maxY); + } + else { + if(x1 > x0) + return createLines(lines, true, y0, x0, y1, minX); + else + return createLines(lines, true, y0, x0, y1, maxX); + } + } + else { + if(x1 > x0) + x0 += OFFSET; + else + x0 -= OFFSET; + if(node.getMinY() <= y0 && node.getMaxY() >= y0) { + if(x1 > x0) + return createLines(lines, false, x0, y0, minX); + else + return createLines(lines, false, x0, y0, maxX); + } + else { + if(y1 > y0) + return createLines(lines, false, x0, y0, x1, minY); + else + return createLines(lines, false, x0, y0, x1, maxY); + } + } + + + } + + public static Path2D createLine(Path2D path, boolean vertical, double ... coordinates) { + if(vertical) + path.moveTo(coordinates[1], coordinates[0]); + else + path.moveTo(coordinates[0], coordinates[1]); + for(int i=2;i procedure) { + procedure.execute(graph, CLASS.newClassWith(false, new StaticObjectAdapter(elementType))); + } + + @Override + protected Resource getElementClassBaseType(AsyncReadGraph graph) { + return graph.getService(SysdynResource.class).FlowConnection; + } + + @Override + public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource connection, + final IElement element) throws DatabaseException { + + // Do we need this? + element.setHint(DiagramHints.ROUTE_ALGORITHM, new Router4(false)); + + IModelingRules modelingRules = diagram.getHint(DiagramModelHints.KEY_MODELING_RULES); + + IElement mappedElement = ElementUtils.getByData(diagram, connection); + if (mappedElement == null) + // FIXME: With undo this seems to happen, don't know why yet! + return; + + Color color = null; + DiagramResource DR = DiagramResource.getInstance(graph); + G2DResource G2D = G2DResource.getInstance(graph); + if (graph.isInstanceOf(connection, DR.ColorProvider)) { + Statement colorStatement = graph.getPossibleStatement(connection, G2D.HasColor); + if(colorStatement != null && !colorStatement.isAsserted(connection)) { + element.setHint(ElementHints.KEY_TEXT_COLOR, G2DUtils.getColor(graph, colorStatement.getObject())); + } else { + String colorString = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair(connection, SysdynDiagramPreferences.getColorPreferenceName(graph, connection)))); + if(colorString != null) { + RGB rgb = StringConverter.asRGB(colorString, null); + if(rgb != null) { + color = new Color(rgb.red, rgb.green, rgb.blue); + element.setHint(ElementHints.KEY_TEXT_COLOR, color); + } + } + + } + } + + RouteGraph rg = new RouteGraph(); + + Set nodes = new HashSet(); + Set links = new HashSet(); + Map nodeByData = new HashMap(); + + // Needed to support ConnectionEntity#getTerminalConnections + Set backendonnections = new HashSet(); + + // Load all route graph interior RouteNodes: route lines and points + for (Resource interiorNode : graph.getObjects(connection, DIA.HasInteriorRouteNode)) { + if (graph.isInstanceOf(interiorNode, DIA.RouteLine)) { + Boolean isHorizontal = graph.getRelatedValue(interiorNode, DIA.IsHorizontal, Bindings.BOOLEAN); + Double position = graph.getRelatedValue(interiorNode, DIA.HasPosition, Bindings.DOUBLE); + RouteLine line = rg.addLine(isHorizontal, position); + line.setData( RouteGraphConnection.serialize(graph, interiorNode) ); + + nodes.add( interiorNode ); + nodeByData.put( interiorNode, line ); + + for (Resource connectedTo : graph.getObjects(interiorNode, DIA.AreConnected)) { + links.add( new EdgeResource(interiorNode, connectedTo) ); + } + } else if (graph.isInstanceOf(interiorNode, DIA.RoutePoint)) { + // Not supported yet. Ignore. + } + } + + Rectangle2D bounds = new Rectangle2D.Double(); + + // Load all node terminal connections as RouteTerminals + for (Statement toConnector : graph.getStatements(connection, DIA.HasConnector)) { + Resource connector = toConnector.getObject(); + Resource attachmentRelation = toConnector.getPredicate(); + + Statement terminalStm = findTerminalStatement(graph, STR, connection, connector); + if (terminalStm == null) + // Ignore broken connector: attached to the connection but not to any terminal. + continue; + + Resource terminalElement = terminalStm.getObject(); + Resource terminalElementType = graph.getPossibleType(terminalElement, DIA.Element); + if (terminalElementType == null) + // Ignore non-element terminal elements + continue; + + Resource connectionRelation = graph.getInverse(terminalStm.getPredicate()); + + // Discover node and terminal this connector is connected to. + TerminalMap terminals = graph.syncRequest(DiagramRequests.elementTypeTerminals(terminalElementType), + TransientCacheListener. instance()); + Resource terminal = terminals.getTerminal(connectionRelation); + if (terminal == null) { + System.err.println(getClass().getSimpleName() + + ": Could not find terminal for connection point " + + NameUtils.getSafeName(graph, connectionRelation, true) + + " in element " + + NameUtils.getSafeName(graph, terminalElement, true)); + continue; + } + + double[] position = graph.getRelatedValue(connector, DIA.HasRelativeLocation, Bindings.DOUBLE_ARRAY); + if (position.length != 2) + position = new double[] { 0, 0 }; + + //System.out.println("terminalStm: " + NameUtils.toString(graph, terminalStm)); + AffineTransform terminalElementTr = getWorldTransform(graph, terminalElement); + + double x = terminalElementTr.getTranslateX(); + double y = terminalElementTr.getTranslateY(); + double minx = x-1, miny = y-1, maxx = x+1, maxy = y+1; + int direction = 0x0; + + // Use modelingRules to ascertain the proper attachmentRelation + // for this terminal connection, if available. + if (modelingRules != null) { + // Get attachmentRelation from modelingRules if possible. + IAttachmentRelationMap map = modelingRules.getAttachmentRelations(graph, connection); + Resource att = map.get(graph, new CPTerminal(terminalElement, terminal)); + if (att != null) { + //System.out.println("modeling rules attachment: " + NameUtils.getSafeLabel(graph, att)); + attachmentRelation = att; + } + } + //System.out.println("attachment: " + NameUtils.getSafeLabel(graph, attachmentRelation)); + + // Get element bounds to decide allowed terminal direction(s) + IElement te = graph.syncRequest(DiagramRequests.getElement(canvas, diagram, terminalElement, null)); + + // Fetch the flow width + float lw = FlowConnectionStyle.DEFAULT_LINE_WIDTH; + SysdynResource sr = SysdynResource.getInstance(graph); + Float width = graph.getPossibleRelatedValue(connection, sr.FlowConnection_width, Bindings.FLOAT); + if (width != null) + lw = width; + + if(te.getElementClass().containsClass(ValveSceneGraph.class)) { + // Valve behaves differently. The flow must start inside the valve bounds + ValveSceneGraph vs = te.getElementClass().getSingleItem(ValveSceneGraph.class); + Rectangle2D size = new Rectangle2D.Double(); + vs.getValveBounds(te, size); + Shape shp = org.simantics.g2d.utils.GeometryUtils.transformShape(size, terminalElementTr); + size = (Rectangle2D) shp; + bounds.setFrame(new Rectangle2D.Double(size.getCenterX() - (lw/2), size.getCenterY() - (lw/2), lw, lw)); + } else { + // Basic bounds + bounds = ElementUtils.getElementShape(te).getBounds2D(); + Shape shp = org.simantics.g2d.utils.GeometryUtils.transformShape(bounds, terminalElementTr); + bounds.setFrame(shp.getBounds2D()); + } + + x = bounds.getCenterX(); + y = bounds.getCenterY(); + + // Expand bounds by 4mm to make the connections enter the terminals + // at a straight angle and from a distance instead of coming in + // "horizontally". + //GeometryUtils.expandRectangle(bounds, 4); + + minx = bounds.getMinX(); + miny = bounds.getMinY(); + maxx = bounds.getMaxX(); + maxy = bounds.getMaxY(); + + Integer allowedDirections = graph.getPossibleRelatedValue(terminal, DIA.Terminal_AllowedDirections, Bindings.INTEGER); + + // Valve behaves differently. Allowed directions depend on the orientation of the valve + if(te.getElementClass().containsClass(ValveSceneGraph.class)) { + if(graph.hasStatement(terminalElement, sr.ValveSymbol_orientation, sr.Vertical)) { + allowedDirections = 10; // Directions up and down (1010) + } else { + allowedDirections = 5; // Directions left and right (0101) + } + } + if (allowedDirections != null) { + direction |= allowedDirections; + } else { + direction |= RouteGraphConnectionClass.shortestDirectionOutOfBounds(x, y, bounds); + } + + backendonnections.add( + new BackendConnection( + toEdgeEnd(graph, attachmentRelation, EdgeEnd.Begin), + terminalElement, + terminal) + ); + + if (direction == 0) + // Accept any horizontal/vertical direction if nothing is defined + direction = 0xf; + + //System.out.println("load line style: " + NameUtils.getSafeLabel(graph, attachmentRelation)); + ILineEndStyle endStyle = loadLineEndStyle(graph, te, attachmentRelation, color, lw); + + RouteTerminal routeTerminal = rg.addBigTerminal(/*x, y,*/ minx, miny, maxx, maxy, /*direction,*/ endStyle); + routeTerminal.setData( RouteGraphConnection.serialize(graph, connector) ); + + nodes.add( connector ); + nodeByData.put( connector, routeTerminal ); + + for (Resource connectedTo : graph.getObjects(connector, DIA.AreConnected)) { + links.add( new EdgeResource(connectedTo, connector) ); + } + } + + // Finish route graph loading by Linking route nodes together + for (EdgeResource link : links) { + RouteNode n1 = nodeByData.get(link.first()); + RouteNode n2 = nodeByData.get(link.second()); + if (n1 == null || n2 == null) { + System.err.println("Stray connection link found: " + link.toString(graph)); + continue; + } + rg.link(n1, n2); + } + + // Load connection line style + ConnectionStyle style = readConnectionStyle(graph, modelingRules, connection, element); + StyledRouteGraphRenderer renderer = new StyledRouteGraphRenderer(style); + + // Finish element load + element.setHint(RouteGraphConnectionClass.KEY_ROUTEGRAPH, rg); + element.setHint(RouteGraphConnectionClass.KEY_RENDERER, renderer); + element.setHint(RouteGraphConnectionClass.KEY_PICK_TOLERANCE, 0.5); + + // Initialize ConnectionEntity in element + // NOTE: MUST use the mapped element with class CE, not the connection (element) were loading into. + // GDS will synchronize element into mappedElement in a controlled manner. + element.setHint(ElementHints.KEY_CONNECTION_ENTITY, new CE(connection, mappedElement, backendonnections)); + + // Setup graph writeback support for route graph modifications + final Session session = graph.getSession(); + element.setHint(RouteGraphConnectionClass.KEY_RG_LISTENER, new IRouteGraphListener() { + @Override + public void routeGraphChanged(RouteGraphChangeEvent event) { + scheduleSynchronize(session, connection, event); + } + }); + + // A complicated-looking procedure for obtaining all HasProperties to properties map + final AtomicInteger ready = new AtomicInteger(1); + final ConcurrentSkipListMap> properties = new ConcurrentSkipListMap>(); + graph.forEachPredicate(connection, new SyncMultiProcedure() { + + @Override + public void exception(ReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(ReadGraph graph, final Resource property) { + + ready.incrementAndGet(); + Layer0 l0; + try { + l0 = Layer0.getInstance(graph.getSession()); + } catch (DatabaseException e) { + e.printStackTrace(); + return; + } + + graph.forIsSubrelationOf(property, l0.HasProperty, new AsyncProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, final Boolean isProperty) { + + if(isProperty) { + + graph.forPossibleRelatedValue(connection, property, new AsyncProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, final Object value) { + + Layer0 l0; + try { + l0 = Layer0.getInstance(graph.getSession()); + } catch (DatabaseException e) { + e.printStackTrace(); + return; + } + + graph.forPossibleRelatedValue(property, l0.HasName, Bindings.STRING, new AsyncProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, String name) { + + properties.put(name, Pair.make(property, value)); + if(ready.decrementAndGet() == 0) { + element.setHint(DiagramHints.PROPERTIES, new HashMap>(properties)); + } + + } + + }); + + } + + }); + + + } else { + + if(ready.decrementAndGet() == 0) { + element.setHint(DiagramHints.PROPERTIES, new HashMap>(properties)); + } + + } + + } + + }); + } + + @Override + public void finished(ReadGraph graph) { + + if(ready.decrementAndGet() == 0) { + element.setHint(DiagramHints.PROPERTIES, new HashMap(properties)); + } + + } + + }); + + } + + private EdgeEnd toEdgeEnd(ReadGraph graph, Resource attachmentRelation, EdgeEnd defaultValue) + throws DatabaseException { + if (graph.isSubrelationOf(attachmentRelation, DIA.IsTailConnectorOf)) + return EdgeEnd.Begin; + if (graph.isSubrelationOf(attachmentRelation, DIA.IsHeadConnectorOf)) + return EdgeEnd.End; + return defaultValue; + } + + private ConnectionStyle readConnectionStyle(ReadGraph graph, IModelingRules modelingRules, Resource connection, + IElement element) throws DatabaseException { + Resource connectionType = null; + if (modelingRules != null) + connectionType = modelingRules.getConnectionType(graph, connection); + if (connectionType == null) + connectionType = graph.getPossibleObject(connection, STR.HasConnectionType); + + ConnectionVisuals cv = null; + if (connectionType != null) + cv = graph.syncRequest(DiagramRequests.getConnectionVisuals(connectionType), + TransientCacheListener. instance()); + + + Color lineColor = element.getHint(ElementHints.KEY_TEXT_COLOR); + if (lineColor == null) + lineColor = (cv != null && cv.toColor() != null) ? cv.toColor() : Color.DARK_GRAY; + + Stroke lineStroke = cv != null ? cv.stroke : null; + if (lineStroke == null) + lineStroke = new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10, null, 0); + + return new FlowConnectionStyle( + lineColor, + lineStroke, + connection); + } + + /** + * @param graph + * @param STR + * @param connection + * @param connector + * @return connection relation statement from diagram connection connector + * to a node + * @throws DatabaseException + */ + private static Statement findTerminalStatement(ReadGraph graph, StructuralResource2 STR, Resource connection, + Resource connector) throws DatabaseException { + for (Statement stm : graph.getStatements(connector, STR.Connects)) { + if (connection.equals(stm.getObject())) + continue; + return stm; + } + return null; + } + + public ILineEndStyle loadLineEndStyle(ReadGraph graph, IElement te, Resource attachmentRelation, Color color, float lineWidth) + throws DatabaseException { + ILineEndStyle style; + // TODO: change bounds according to terminal type: Very small rectangle for Valves, Text box size for Stocks and Clouds + if(te.getElementClass().containsClass(ValveSceneGraph.class)) { + style = new FlowArrowLineStyle("none 0 0 0", color); + } else { + if (graph.isSubrelationOf(attachmentRelation, DIA.HasHeadConnector)) { + float arrowSize = lineWidth * 1.3f; + style = new FlowArrowLineStyle("fill " + arrowSize + " " + arrowSize + " 0", color); + } else { + style = new FlowArrowLineStyle("none 0 0 0", color); + } + } + return style; + } + + /** + * @param graph + * @param element + * @return + * @throws DatabaseException + */ + private static AffineTransform getWorldTransform(ReadGraph graph, Resource element) throws DatabaseException { + ModelingResources MOD = ModelingResources.getInstance(graph); + AffineTransform result = DiagramGraphUtil.getAffineTransform(graph, element); + while (true) { + Resource parentComponent = graph.getPossibleObject(element, MOD.HasParentComponent); + if (parentComponent == null) + return result; + element = graph.getPossibleObject(parentComponent, MOD.ComponentToElement); + if (element == null) + return result; + AffineTransform tr = DiagramGraphUtil.getAffineTransform(graph, element); + tr.setToTranslation(tr.getTranslateX(), tr.getTranslateY()); + result.preConcatenate(tr); + } + } + + + protected void scheduleSynchronize(Session session, Resource connection, RouteGraphChangeEvent event) { + session.asyncRequest(RouteGraphConnection.synchronizer(connection, event)); + } + + /** + * Must have this in order for {@link TopologicalSelectionExpander} to work. + * Otherwise this is pretty useless and should be deprecated altogether. + * + * @see ElementHints#KEY_CONNECTION_ENTITY + */ + static class CE implements ConnectionEntity { + + /** + * The connection instance resource in the graph backend. + */ + final Resource connection; + + /** + * The connection entity element which is a part of the diagram. + */ + final IElement connectionElement; + + /** + * @see #getTerminalConnections(Collection) + */ + final Set backendConnections; + + /** + * Cache. + */ + Set terminalConnections; + + CE(Resource connection, IElement connectionElement, Set backendConnections) { + this.connection = connection; + this.connectionElement = connectionElement; + this.backendConnections = backendConnections; + } + + @Override + public IElement getConnection() { + return connectionElement; + } + + public Object getConnectionObject() { + return connection; + } + + public IElement getConnectionElement() { + return connectionElement; + } + + @Override + public Collection getBranchPoints(Collection result) { + return result != null ? result : Collections. emptyList(); + } + + @Override + public Collection getSegments(Collection result) { + return result != null ? result : Collections. emptyList(); + } + + @Override + public Collection getTerminalConnections(Collection result) { + if (terminalConnections == null) + terminalConnections = calculateTerminalConnections(); + if (result == null) + result = new ArrayList(terminalConnections); + else + result.addAll(terminalConnections); + return terminalConnections; + } + + private Set calculateTerminalConnections() { + IDiagram diagram = connectionElement.getDiagram(); + DataElementMap dem = diagram.getDiagramClass().getSingleItem(DataElementMap.class); + Set result = new HashSet(); + ArrayList ts = new ArrayList(); + for (BackendConnection bc : backendConnections) { + IElement e = dem.getElement(diagram, bc.node); + if (e == null) + continue; + TerminalTopology tt = e.getElementClass().getSingleItem(TerminalTopology.class); + tt.getTerminals(e, ts); + for (Terminal t : ts) { + if (t instanceof ResourceTerminal) { + ResourceTerminal rt = (ResourceTerminal) t; + if (bc.terminal.equals(rt.getResource())) { + result.add(new Connection(connectionElement, bc.end, e, t)); + break; + } + } + } + } + return result; + } + + @Override + public void setListener(ConnectionListener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[resource=" + connection + ", connectionElement=" + connectionElement + + "]"; + } + + } + + public static class BackendConnection { + public final Resource node; + public final Resource terminal; + public final EdgeEnd end; + public BackendConnection(EdgeEnd end, Resource node, Resource terminal) { + assert end != null; + assert node != null; + assert terminal != null; + this.end = end; + this.node = node; + this.terminal = terminal; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof Connection)) + return false; + Connection other = (Connection) obj; + return other.terminal == terminal + && other.node == node + && other.end == end; + } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + end.hashCode(); + result = prime * result + ((node == null) ? 0 : node.hashCode()); + result = prime * result + ((terminal == null) ? 0 : terminal.hashCode()); + return result; + } + @Override + public String toString() { + return "BackendConnection[node=" + node + ", terminal=" + terminal + ", end=" + end + "]"; + } + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeClass.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeClass.java new file mode 100644 index 00000000..5061e738 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeClass.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import java.util.ArrayList; +import java.util.List; + +import org.simantics.diagram.connection.RouteGraph; +import org.simantics.diagram.connection.RouteGraphConnectionClass; +import org.simantics.diagram.connection.rendering.IRouteGraphRenderer; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.ElementHandler; +import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.nodes.connection.IRouteGraphListener; + + +public class RouteFlowEdgeClass extends RouteGraphConnectionClass { + + public static final ElementClass FLOW_CLASS = getElementClass(); + + + public static final ElementClass getElementClass() { + List oldList = CLASS.getAll(); + ArrayList list = new ArrayList(); + list.add(FlowConnectionSceneGraph.INSTANCE); + for(ElementHandler eh : oldList) { + if(!(eh instanceof SceneGraph)) { + list.add(eh); + } + } + return ElementClass.compile(list); + } + + + static final class FlowConnectionSceneGraph implements SceneGraph { + + public static final FlowConnectionSceneGraph INSTANCE = new FlowConnectionSceneGraph(); + + private static final long serialVersionUID = 1865920472882420644L; + + @Override + public void init(IElement connection, G2DParentNode parent) { + RouteGraph rg = connection.getHint(KEY_ROUTEGRAPH); + IRouteGraphRenderer renderer = connection.getHint(KEY_RENDERER); + if (rg == null || renderer == null) { + cleanup(connection); + } else { + RouteFlowNode rgn = ElementUtils.getOrCreateNode(connection, parent, KEY_RG_NODE, "flow_" + connection.hashCode(), RouteFlowNode.class); + rgn.setRouteGraph(rg); + rgn.setRenderer(renderer); + + IRouteGraphListener listener = connection.getHint(KEY_RG_LISTENER); + rgn.setRouteGraphListener(listener); + + Double tolerance = connection.getHint(KEY_PICK_TOLERANCE); + if (tolerance != null) + rgn.setPickTolerance(tolerance); + } + } + + @Override + public void cleanup(IElement connection) { + ElementUtils.removePossibleNode(connection, KEY_RG_NODE); + connection.removeHint(KEY_RG_NODE); + } + } + +} + + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeFactory.java new file mode 100644 index 00000000..97bb8452 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeFactory.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.procedure.AsyncProcedure; +import org.simantics.diagram.adapter.ElementFactoryAdapter; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.ElementClass; + +public class RouteFlowEdgeFactory extends ElementFactoryAdapter { + + private static final ElementClass CLASS = RouteFlowEdgeClass.FLOW_CLASS; + + @Override + public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, + AsyncProcedure procedure) { + procedure.execute(graph, CLASS); + } + + @Override + public void getClass(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource, + AsyncProcedure procedure) { + procedure.execute(graph, CLASS); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowNode.java new file mode 100644 index 00000000..4a75f082 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowNode.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import java.util.HashMap; + +import org.simantics.diagram.connection.rendering.ConnectionStyle; +import org.simantics.diagram.connection.rendering.StyledRouteGraphRenderer; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin; +import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphNode; +import org.simantics.sysdyn.ui.elements.LoopNode; +import org.simantics.sysdyn.ui.elements.LoopNode.ILoopComponentNode; +import org.simantics.sysdyn.ui.elements.SysdynElementHints; +import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils; + +/** + * Node for flow arrows. + * @author Tuomas Miettinen + * + */ +public class RouteFlowNode extends RouteGraphNode implements ILoopComponentNode { + + private static final long serialVersionUID = 2576929364910319487L; + boolean isLock = false; + private HashMap loopSelectionMap = new HashMap(); + + private boolean isLoopSelected() { + return loopSelectionMap.containsValue(true); + } + + @Override + protected boolean mouseDragged(MouseDragBegin e) { + // Disable dragging if LockSketch is ON + if (SysdynElementHints.LOCK_TOOL.equals(SysdynWorkbenchUtils.getSysdynToolMode())) + return false; + else + return super.mouseDragged(e); + } + + @Override + public void setLoopSelected(LoopNode loop, boolean selected) { + Boolean loopSelected = loopSelectionMap.get(loop); + if (loopSelected == null || loopSelected != selected) { + loopSelectionMap.put(loop, selected); + + // Here the FlowConnectionStyle takes care of drawing the flow, so + // find it and tell it to change the color accordingly + if (!(renderer instanceof StyledRouteGraphRenderer)) + return; + + StyledRouteGraphRenderer renderer = (StyledRouteGraphRenderer)this.renderer; + ConnectionStyle style = renderer.getStyle(); + if (!(style instanceof FlowConnectionStyle)) + return; + + FlowConnectionStyle fcs = (FlowConnectionStyle)style; + + fcs.setLoopColorOverride(isLoopSelected()); + repaint(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/SysdynConnectionClass.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/SysdynConnectionClass.java new file mode 100644 index 00000000..e9fc9702 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/SysdynConnectionClass.java @@ -0,0 +1,572 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.connections; + +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.awt.geom.Area; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.simantics.db.Resource; +import org.simantics.g2d.connection.ConnectionEntity; +import org.simantics.g2d.connection.ConnectionEntity.ConnectionEvent; +import org.simantics.g2d.connection.ConnectionEntity.ConnectionListener; +import org.simantics.g2d.connection.handler.ConnectionHandler; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy; +import org.simantics.g2d.diagram.handler.Topology.Connection; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.Children; +import org.simantics.g2d.element.handler.InternalSize; +import org.simantics.g2d.element.handler.Outline; +import org.simantics.g2d.element.handler.Pick; +import org.simantics.g2d.element.handler.Pick2; +import org.simantics.g2d.element.handler.SceneGraph; +import org.simantics.g2d.element.handler.SelectionOutline; +import org.simantics.g2d.element.handler.Transform; +import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; +import org.simantics.g2d.element.handler.impl.ParentImpl; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform; +import org.simantics.g2d.utils.GeometryUtils; +import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.scenegraph.g2d.IG2DNode; +import org.simantics.scenegraph.g2d.nodes.SingleElementNode; +import org.simantics.utils.datastructures.ListenerList; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; + +/** + * An element class for single connection entity elements. A sysdyn connection + * entity consists of a single edge. Sysdyn connections can't be branched. + * + * @author Tuukka Lehtonen + */ +public class SysdynConnectionClass { + + public static final ElementClass CLASS = + ElementClass.compile( + TextImpl.INSTANCE, + TextFontImpl.DEFAULT, + TextColorImpl.BLACK, + FixedTransform.INSTANCE, + ConnectionPick.INSTANCE, + ConnectionBounds.INSTANCE, + ConnectionSelectionOutline.INSTANCE, + ConnectionHandlerImpl.INSTANCE, + ConnectionChildren.INSTANCE, + ParentImpl.INSTANCE, + ConnectionSceneGraph.INSTANCE, + SimpleElementLayers.INSTANCE + ).setId(SysdynConnectionClass.class.getSimpleName()); + + private static class ThreadLocalList extends ThreadLocal> { + @Override + protected java.util.List initialValue() { + return new ArrayList(); + } + }; + + private static final ThreadLocal> perThreadSceneGraphList = new ThreadLocalList(); + private static final ThreadLocal> perThreadBoundsList = new ThreadLocalList(); + private static final ThreadLocal> perThreadShapeList = new ThreadLocalList(); + private static final ThreadLocal> perThreadPickList = new ThreadLocalList(); + + static class ConnectionHandlerImpl implements ConnectionHandler { + + public static final ConnectionHandlerImpl INSTANCE = new ConnectionHandlerImpl(); + + private static final long serialVersionUID = 3267139233182458330L; + + @Override + public Collection getBranchPoints(IElement connection, Collection result) { + ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (entity == null) + return Collections.emptySet(); + return entity.getBranchPoints(result); + } + + @Override + public Collection getChildren(IElement connection, Collection result) { + ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (entity == null) + return Collections.emptySet(); + result = entity.getSegments(result); + return entity.getBranchPoints(result); + } + + @Override + public Collection getSegments(IElement connection, Collection result) { + ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (entity == null) + return Collections.emptySet(); + return entity.getSegments(result); + } + + @Override + public Collection getTerminalConnections(IElement connection, Collection result) { + ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (entity == null) + return Collections.emptySet(); + return entity.getTerminalConnections(result); + } + } + + static final class ConnectionSceneGraph implements SceneGraph { + + public static final ConnectionSceneGraph INSTANCE = new ConnectionSceneGraph(); + + private static final long serialVersionUID = 4232871859964883266L; + + @Override + public void init(IElement connection, G2DParentNode parent) { + ConnectionEntity ce = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (ce == null) + return; + + // Painting is single-threaded, it is OK to use a single thread-local collection here. + List children = perThreadSceneGraphList.get(); + children.clear(); + ce.getSegments(children); + ce.getBranchPoints(children); + //new Exception("painting connection entity " + ce.hashCode() + " with " + children.size() + " segments and branch points").printStackTrace(); + if (children.isEmpty()) + return; + + Set tmp = new HashSet(); + + Map> properties = connection.getHint(DiagramHints.PROPERTIES); + + Font font = connection.getHint(ElementHints.KEY_FONT); + Color color = connection.getHint(ElementHints.KEY_TEXT_COLOR); + + int zIndex = 0; + for (IElement child : children) { + + ElementClass ec = child.getElementClass(); + + Transform transform = child.getElementClass().getSingleItem(Transform.class); + assert (transform != null); + AffineTransform at2 = transform.getTransform(child); + if (at2 == null) + continue; + + if(properties != null) + child.setHint(DiagramHints.PROPERTIES, properties); + + if(font != null) + child.setHint(ElementHints.KEY_FONT, font); + + if(color != null) + child.setHint(ElementHints.KEY_TEXT_COLOR, color); + + SingleElementNode holder = child.getHint(ElementHints.KEY_SG_NODE); + if (holder == null) { + holder = parent.addNode(ElementUtils.generateNodeId(child), SingleElementNode.class); + child.setHint(ElementHints.KEY_SG_NODE, holder); + } + holder.setZIndex(++zIndex); + + Composite composite = child.getHint(ElementHints.KEY_COMPOSITE); + + holder.setTransform((AffineTransform) at2.clone()); + holder.setComposite(composite); + holder.setVisible(true); + + // New node handler + for (SceneGraph n : ec.getItemsByClass(SceneGraph.class)) { + n.init(child, holder); + } + tmp.add(holder); + } + + // Hide unaccessed nodes (but don't remove) + for (IG2DNode node : parent.getNodes()) { + if (node instanceof SingleElementNode) { + if (!tmp.contains(node)) { + ((SingleElementNode)node).setVisible(false); + } + } else { + //System.out.println("WHAT IS THIS: "); + //NodeDebug.printSceneGraph(((Node) node)); + } + } + + // Don't leave dangling references behind. + children.clear(); + } + + @Override + public void cleanup(IElement e) { + } + } + + static final class ConnectionBounds implements InternalSize, Outline { + + public static final ConnectionBounds INSTANCE = new ConnectionBounds(); + + private static final long serialVersionUID = 4232871859964883266L; + + @Override + public Rectangle2D getBounds(IElement e, Rectangle2D size) { + ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (ce == null) + return size; + + Collection parts = perThreadBoundsList.get(); + parts.clear(); + parts = ce.getSegments(parts); + if (parts.isEmpty()) + return size; + + parts = ce.getBranchPoints(parts); + + Rectangle2D temp = null; + for (IElement part : parts) { + if (ElementUtils.isHidden(part)) + continue; + + // Using on-diagram coordinates because neither connections nor + // edges have a non-identity transform which means that + // coordinates are always absolute. Therefore branch point + // bounds also need to be calculated in absolute coordinates. + Rectangle2D bounds = ElementUtils.getElementBoundsOnDiagram(part, size); + if (bounds == null) + continue; + +// System.out.println("InternalSize BOUNDS: " + size + " for part " + part + " " + part.getElementClass()); + if (temp == null) { + temp = new Rectangle2D.Double(); + temp.setRect(bounds); + } else + Rectangle2D.union(temp, bounds, temp); + //System.out.println("InternalSize Combined BOUNDS: " + temp); + } + if (temp != null) { + if (size == null) + size = temp; + else + size.setRect(temp); + } + + // Don't leave dangling references behind. + parts.clear(); + + return size; + } + + private Shape getSelectionShape(IElement forPart) { + for (SelectionOutline so : forPart.getElementClass().getItemsByClass(SelectionOutline.class)) { + Shape shape = so.getSelectionShape(forPart); + if (shape != null) + return shape; + } + // Using on-diagram coordinates because neither connections nor + // edges have a non-identity transform which means that + // coordinates are always absolute. Therefore branch point + // shape also needs to be calculated in absolute coordinates. + Shape shape = ElementUtils.getElementShapeOrBoundsOnDiagram(forPart); + return shape; + //return shape.getBounds2D(); + } + + @Override + public Shape getElementShape(IElement e) { + ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (ce == null) + return new Rectangle2D.Double(); + + Collection parts = perThreadShapeList.get(); + parts.clear(); + parts = ce.getSegments(parts); + if (parts.isEmpty()) + return new Rectangle2D.Double(); + parts = ce.getBranchPoints(parts); + + if (parts.size() == 1) { + Shape shape = getSelectionShape(parts.iterator().next()); + //System.out.println("Outline SHAPE: " + shape); + //System.out.println("Outline BOUNDS: " + shape.getBounds2D()); + return shape; + } + + //System.out.println("Outline: " + e); + Area area = new Area(); + for (IElement part : parts) { + //System.out.println(part); + + Shape shape = getSelectionShape(part); + + Rectangle2D bounds = shape.getBounds2D(); +// System.out.println(" shape: " + shape); +// System.out.println(" bounds: " + bounds); + + if (bounds.isEmpty()) { + double w = bounds.getWidth(); + double h = bounds.getHeight(); + if (w <= 0.0 && h <= 0.0) + continue; + + // Need to expand shape in either width or height to make it visible. + final double exp = 0.1; + if (w <= 0.0) + shape = org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(bounds, 0, 0, exp, exp); + else if (h <= 0.0) + shape = org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(bounds, exp, exp, 0, 0); + } + + //System.out.println(" final shape: " + shape); + //shape = bounds; + + Area a = null; + if (shape instanceof Area) + a = (Area) shape; + else + a = new Area(shape); + area.add(a); + } + + // Don't leave dangling references behind. + parts.clear(); + + //System.out.println(" connection area outline: " + area); + //System.out.println(" connection area outline bounds: " + area.getBounds2D()); + return area; + } + } + + public static class ConnectionPick implements Pick2 { + + public final static ConnectionPick INSTANCE = new ConnectionPick(); + + private static final long serialVersionUID = 1L; + + @Override + public boolean pickTest(IElement e, Shape s, PickPolicy policy) { + ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (ce == null) + return false; + + // Primarily pick branch points and then edges. + Collection parts = perThreadPickList.get(); + parts.clear(); + parts = ce.getBranchPoints(parts); + parts = ce.getSegments(parts); + if (parts.isEmpty()) + return false; + + for (IElement part : parts) { + for (Pick pick : part.getElementClass().getItemsByClass(Pick.class)) { +// System.out.println("TESTING: " + part + " : " + s + " : " + policy); + if (pick.pickTest(part, s, policy)) { + //System.out.println(" HIT!"); + return true; + } + } + } + + parts.clear(); + + return false; + } + + @Override + public int pick(IElement e, Shape s, PickPolicy policy, Collection result) { + int oldResultSize = result.size(); + +// new Exception("SysdynConnectionClass.pick: " + e + " : " + s + " : " + policy).printStackTrace(); + + ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (ce == null) + return 0; + + // Primarily pick branch points and then edges. + List parts = perThreadPickList.get(); + parts.clear(); + + ce.getSegments(parts); + int edges = parts.size(); + ce.getBranchPoints(parts); + int branchPoints = parts.size() - edges; + + boolean singleEdge = branchPoints == 0 && edges == 1; + + if (parts.isEmpty()) + return 0; + + // See whether the whole connection is to be picked.. + boolean pickConnection = false; + wholeConnectionPick: + for (Outline outline : e.getElementClass().getItemsByClass(Outline.class)) { + Shape elementShape = outline.getElementShape(e); + if (elementShape == null) + continue; + + switch (policy) { + case PICK_CONTAINED_OBJECTS: + if (GeometryUtils.contains(s, elementShape)) { + pickConnection = true; + break wholeConnectionPick; + } + break; + case PICK_INTERSECTING_OBJECTS: + if (GeometryUtils.intersects(s, elementShape)) { + pickConnection = true; + break wholeConnectionPick; + } + break; + } + } + + ArrayList picks = null; + + // Pick connection segments + for (int i = 0; i < edges; ++i) { + IElement part = parts.get(i); + for (Pick pick : part.getElementClass().getItemsByClass(Pick.class)) { +// System.out.println("TESTING SEGMENT: " + part + " : " + s + " : " + policy); + if (pick.pickTest(part, s, policy)) { +// System.out.println(" HIT!"); + if (picks == null) + picks = new ArrayList(4); + picks.add(e); + break; + } + } + } + + // Pick the whole connection ? + if (pickConnection) { + if (picks == null) + picks = new ArrayList(4); + picks.add(e); + } + + // Pick branch/route points + for (int i = edges; i < parts.size(); ++i) { + IElement part = parts.get(i); + for (Pick pick : part.getElementClass().getItemsByClass(Pick.class)) { + //System.out.println("TESTING BRANCHPOINT: " + part + " : " + s + " : " + policy); + if (pick.pickTest(part, s, policy)) { + //System.out.println(" HIT!"); + if (picks == null) + picks = new ArrayList(4); + picks.add(part); + break; + } + } + } + + if (picks != null) { + // Add the discovered pickable children to the result after the + // parent to make the parent the primary pickable. + // Skip the children if there is only one child. + if (!singleEdge) { + result.addAll(picks); + } else { + result.add(e); + } + } + + parts.clear(); + +// System.out.println("pick result size = " + result.size()); + + return result.size() - oldResultSize; + } + } + + private static final Key CHILD_LISTENERS = new KeyOf(ListenerList.class, "CHILD_LISTENERS"); + + public static class ConnectionChildren implements Children, ConnectionListener { + + public final static ConnectionChildren INSTANCE = new ConnectionChildren(); + + private static final long serialVersionUID = 1L; + + @Override + public Collection getChildren(IElement element, Collection result) { + ConnectionEntity ce = element.getHint(ElementHints.KEY_CONNECTION_ENTITY); + if (ce == null) { + if (result == null) + result = new ArrayList(0); + return result; + } + result = ce.getSegments(result); + result = ce.getBranchPoints(result); + return result; + } + + @Override + public void addChildListener(IElement element, ChildListener listener) { + ListenerList ll = null; + synchronized (element) { + ll = element.getHint(CHILD_LISTENERS); + if (ll == null) { + ll = new ListenerList(ChildListener.class); + element.setHint(CHILD_LISTENERS, ll); + ConnectionEntity entity = element.getHint(ElementHints.KEY_CONNECTION_ENTITY); + entity.setListener(this); + } + } + ll.add(listener); + } + + @Override + public void removeChildListener(IElement element, ChildListener listener) { + synchronized (element) { + ListenerList ll = element.getHint(CHILD_LISTENERS); + if (ll == null) + return; + ll.remove(listener); + if (ll.isEmpty()) { + ConnectionEntity entity = element.getHint(ElementHints.KEY_CONNECTION_ENTITY); + entity.setListener(null); + } + } + } + + @Override + public void connectionChanged(ConnectionEvent event) { + fireChildrenChanged(event); + } + + private void fireChildrenChanged(ConnectionEvent event) { + ListenerList ll = event.connection.getHint(CHILD_LISTENERS); + if (ll == null) + return; + ChildEvent ce = new ChildEvent(event.connection, event.removedParts, event.addedParts); + for (ChildListener cl : ll.getListeners()) { + cl.elementChildrenChanged(ce); + } + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/IssueDecorationStyle.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/IssueDecorationStyle.java new file mode 100644 index 00000000..e3db689f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/IssueDecorationStyle.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.profiles; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleTypedParent; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.diagram.profile.StyleBase; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.issues.common.ErrorIssues; +import org.simantics.issues.common.FatalIssues; +import org.simantics.issues.common.WarningIssues; +import org.simantics.issues.ontology.IssueResource; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.g2d.nodes.SVGNode; +import org.simantics.scenegraph.profile.EvaluationContext; +import org.simantics.scenegraph.profile.common.ProfileVariables; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.utils.datastructures.map.Tuple; + +/** + * Issue Decorations. Display an issue icon on + * a diagram element depending on the type of the issue + * . + * @author Teemu Lempinen + * + */ +public class IssueDecorationStyle extends StyleBase { + + private static final String DECORATION_NODE_NAME = "issueDecorations"; + + @Override + public IssueResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + + // Find a component for the element + Resource component = graph.getPossibleObject(element, MOD.ElementToComponent); + + // If component is shadow, find the original component + if (component != null && graph.isInstanceOf(component, SR.Shadow)) { + component = graph.getPossibleObject(component, SR.Shadow_original); + } + + if (component == null) + return null; + + // Get the current transform of the element to be able to move the decoration with the element + AffineTransform transform = DiagramGraphUtil.getAffineTransform(graph, element); + + // Find the model of the component + Resource model = graph.syncRequest(new PossibleTypedParent(component, SimulationResource.getInstance(graph).Model)); + if (model == null) + return null; + + // Project + Resource project = graph.getPossibleObject(model, L0.PartOf); + if (project == null) + return null; + + IssueResult result = null; + + /* + * Search for issues. Start from fatal and move to + * less important issues. This way the most important + * issue will be displayed. + * + * The issue is returned immediately after it is found. + */ + + Set fatals = graph.syncRequest(new FatalIssues(project, true)); + result = getIssue(graph, IssueResult.Severity.FATAL, fatals, component, transform); + if(result != null) return result; + + Set errors = graph.syncRequest(new ErrorIssues(project, true)); + result = getIssue(graph, IssueResult.Severity.ERROR, errors, component, transform); + if(result != null) return result; + + Set warnings = graph.syncRequest(new WarningIssues(project, true)); + result = getIssue(graph, IssueResult.Severity.WARNING, warnings, component, transform); + if(result != null) return result; + + // No issue was found + return null; + } + + /** + * See if a set of issue variables concern this component + * + * @param graph ReadGraph + * @param severity IssueResult.Severity of the issue + * @param issues Collection of issues of type severity + * @param component The component that is evaluated for issues + * @param transform AffineTransform of the diagram element + * @return IssueResult containing the severity and transform of the issue or null if no issue concerned component + * @throws DatabaseException + */ + private IssueResult getIssue(ReadGraph graph, IssueResult.Severity severity, Set issues, Resource component, AffineTransform transform) throws DatabaseException { + IssueResource ISSUE = IssueResource.getInstance(graph); + Resource list, issueResource; + for(Variable issue : issues) { + issueResource = issue.getRepresents(graph); + list = graph.getPossibleObject(issueResource, ISSUE.Issue_HasContexts); + List contexts = ListUtils.toList(graph, list); + if(!contexts.isEmpty()) { + if(ListUtils.toList(graph, list).subList(0, 1).contains(component)) { + return new IssueResult(severity, transform); + } + } + } + return null; + } + + @Override + public void applyStyleForNode(EvaluationContext observer, INode node, IssueResult result) { + + // If result == null, remove possible issue decoration + if (result == null) { + ProfileVariables.denyChild(node, "", DECORATION_NODE_NAME); + return; + } + + // Create issue decoration node + SVGNode svgNode = ProfileVariables.claimChild(node, "", DECORATION_NODE_NAME, SVGNode.class, observer); + + // Move the decoration to the upper right corner of the element + Rectangle2D bounds = NodeUtil.getLocalBounds(node, Collections.singleton(svgNode)); + double tx = bounds.getMaxX(); + double ty = bounds.getY(); + svgNode.setZIndex( Integer.MAX_VALUE ); + svgNode.setTransform( AffineTransform.getTranslateInstance(tx-1, ty-1)); + svgNode.getTransform().scale(0.5, 0.5); + + + // Apply the corresponding svg graphics to the node + IssueResult.Severity sev = result.getSeverity(); + if (IssueResult.Severity.FATAL.equals(sev)) + svgNode.setData(Activator.FATAL_SVG_TEXT); + else if (IssueResult.Severity.ERROR.equals(sev)) + svgNode.setData(Activator.ERROR_SVG_TEXT); + else if (IssueResult.Severity.WARNING.equals(sev)) + svgNode.setData(Activator.WARNING_SVG_TEXT); + } + + @Override + protected void cleanupStyleForNode(INode node) { + ProfileVariables.denyChild(node, "", DECORATION_NODE_NAME); + } + +} + +/** + * This is needed to keep the issue decoration up-to-date when its parent + * element moves. + */ +class IssueResult extends Tuple { + + public enum Severity{FATAL, ERROR, WARNING}; + + public IssueResult(Severity severity, AffineTransform transform) { + super(severity, transform); + } + public Severity getSeverity() { + return (Severity) getField(0); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/ShadowStyle.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/ShadowStyle.java new file mode 100644 index 00000000..5e5f981c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/ShadowStyle.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.profiles; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.diagram.elements.TextNode; +import org.simantics.diagram.profile.StyleBase; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.modeling.ModelingResources; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.g2d.nodes.ShapeNode; +import org.simantics.scenegraph.g2d.nodes.SingleElementNode; +import org.simantics.scenegraph.profile.EvaluationContext; +import org.simantics.scenegraph.profile.common.ProfileVariables; +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements.profiles.ShadowResult.Style; +import org.simantics.utils.datastructures.map.Tuple; + +public class ShadowStyle extends StyleBase { + + private static String SHADOW_DECORATION_NODE = "SHADOW_DECORATION_NODE"; + private static Stroke SHADOW_DECORATION_STROKE = new BasicStroke(0.2f); + + @Override + public ShadowResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException { + ModelingResources MOD = ModelingResources.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + + AffineTransform transform = DiagramGraphUtil.getAffineTransform(graph, element); + + Resource component = graph.getPossibleObject(element, MOD.ElementToComponent); + + Resource original = graph.getPossibleObject(component, SR.Shadow_original); + Collection shadows = graph.getObjects(component, SR.Shadow_original_Inverse); + + for(Resource r : graph.getObjects(runtimeDiagram, SR.ConfigurationDiagram_selection)) { + Resource selection = graph.getPossibleObject(r, MOD.ElementToComponent); + if(original != null) { + Collection otherShadows = graph.getObjects(original, SR.Shadow_original_Inverse); + otherShadows.remove(component); + if(selection.equals(original) || otherShadows.contains(selection)) { + return new ShadowResult(Style.SHADOW, transform); + } + } + + if(shadows.contains(selection)) { + return new ShadowResult(Style.ORIGINAL, transform); + } + } + + return new ShadowResult(Style.NONE, transform); + } + + public void applyStyleForNode(EvaluationContext observer, INode _node, ShadowResult result) { + + if(result == null || result.getStyle() == Style.NONE) { + cleanupStyleForNode(_node); + return; + } + // Create a node that will show the style effect + A node = ProfileVariables.claimChild(_node, "", SHADOW_DECORATION_NODE, A.class, observer); + if (node == null) + return; + + AffineTransform at = result.getTransform(); + + // Create a node for the style + INode n = NodeUtil.getNearestChildByClass((SingleElementNode)_node, TextNode.class); + Rectangle2D expandedElementBounds = GeometryUtils.expandRectangle( NodeUtil.getLocalElementBounds(n), 0.0); + node.setFill(false); + node.setColor(result.getStyle() == Style.SHADOW ? Color.BLUE : Color.MAGENTA); + node.setStroke(SHADOW_DECORATION_STROKE); + node.setValue("shape", expandedElementBounds); + node.setTransform(at); + + // Find z-index for the TextNode associated with the element and place the style node just below that text node + int zIndex = -1; + if(n != null) { + at = ((TextNode)n).getTransform(); + zIndex = ((TextNode)n).getZIndex() - 1; + } else { + n = _node; + } + node.setZIndex(zIndex); + + } + + @Override + protected void cleanupStyleForNode(INode node) { + ProfileVariables.denyChild(node, "", SHADOW_DECORATION_NODE); + } + + /** + * Dummy class for displaying the style + * + * @author Teemu Lempinen + * + */ + public static class A extends ShapeNode { + + private static final long serialVersionUID = -5273246617906214956L; + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + + @Override + public Rectangle2D getBoundsInLocal(boolean b) { + return null; + } + + @Override + public Rectangle2D getBounds() { + return null; + } + + } + +} + +/** + * This is needed to keep the issue decoration up-to-date when its parent + * element moves. + */ +class ShadowResult extends Tuple { + + public enum Style{NONE, ORIGINAL, SHADOW}; + + public ShadowResult(Style style, AffineTransform transform) { + super(style, transform); + } + public Style getStyle() { + return (Style) getField(0); + } + + public AffineTransform getTransform() { + return (AffineTransform) getField(1); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/SimulationPlaybackStyle.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/SimulationPlaybackStyle.java new file mode 100644 index 00000000..35516ae8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/SimulationPlaybackStyle.java @@ -0,0 +1,316 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements.profiles; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.diagram.G2DUtils; +import org.simantics.diagram.elements.TextNode; +import org.simantics.diagram.profile.StyleBase; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.modeling.ModelingResources; +import org.simantics.project.IProject; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.g2d.nodes.ShapeNode; +import org.simantics.scenegraph.g2d.nodes.SingleElementNode; +import org.simantics.scenegraph.profile.EvaluationContext; +import org.simantics.scenegraph.profile.Observer; +import org.simantics.scenegraph.profile.common.ProfileVariables; +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.scl.runtime.tuple.Tuple2; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.Functions; +import org.simantics.sysdyn.adapter.VariableRVIUtils; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Triple; +import org.simantics.utils.ui.color.Color; +import org.simantics.utils.ui.color.ColorGradient; +import org.simantics.utils.ui.color.ColorValue; + +/** + * Profile style definition for simulation playback mode. Works only with SimulationPlaybackExperiment + * + * @author Teemu Lempinen + * + */ +public class SimulationPlaybackStyle extends StyleBase> { + + Resource gradientResource; + ColorGradient cg; + byte[] gradient; + + /** + * Determine if style needs to be redrawn and return objects that are needed to redraw the style. + * + * @return All necessary components that are needed to draw this style + */ + @Override + public Triple calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException { + + // Find SimulationPlaybackExperiment + IProject project = SimanticsUI.getProject(); + IExperimentManager em = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = em.getActiveExperiment(); + if(!(experiment instanceof SysdynPlaybackExperiment)) + return null; + + ModelingResources mr = ModelingResources.getInstance(graph); + DiagramResource dr = DiagramResource.getInstance(graph); + + ColorGradient cg = null; + + Resource component = graph.getPossibleObject(element, mr.ElementToComponent); + if (component == null) + return null; + + try { + + // Find Variable for this component + String dv = graph.getPossibleRelatedValue(runtimeDiagram, dr.RuntimeDiagram_HasVariable); + Variable rootVariable = graph.getPossibleAdapter(graph.getRootLibrary(), Variable.class); + if (rootVariable == null) + return null; + Variable diagramVariable = rootVariable.browsePossible(graph, dv.substring(6)); + if(diagramVariable == null) + return null; + + Variable var = diagramVariable.browsePossible(graph, component); + if(var == null) + return null; + + // Get simulation result values for this component + // Get values + Variable dsVariable = var.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#"); + Object object = null; + if(dsVariable != null) + object = dsVariable.getValue(graph); + if(object == null || !(object instanceof ArrayList)) + return null; + + ArrayList datasets = new ArrayList(); + + for(Object o : (ArrayList)object) { + if(o instanceof SysdynDataSet) + datasets.add((SysdynDataSet)o); + } + + if(datasets.size() == 0) + return null; + + if(datasets.size() > 1) { + String range = datasets.get(0).name.substring( + datasets.get(0).name.indexOf('[') + 1, + datasets.get(0).name.indexOf(']')); + int size = range.split(",").length; + String[] filter = new String[size]; + for(int i = 0; i < size; i++) + filter[i] = "Sum"; + + ArrayList result2 = VariableRVIUtils.getDataset(datasets, filter); + if(result2 != null) { + datasets = result2; + } + + } + + // The datasets list should always be size == 1 + SysdynDataSet dataset = datasets.get(0); + + // Get values (or sum of values) + double[] va = dataset.values; + if(va.length < 2) + return null; + + // Get simulation timesteps for this component + double[] ta = dataset.times; + if(ta == null || ta.length < 2) + return null; + + if(va.length == 0 || va.length == 2) + return null; + + // Get playback time from the experiment run + Double time = null; + if(diagramVariable != null) { + Variable timeVar = diagramVariable.browsePossible(graph, "#" + Functions.TIME + "#"); + if(timeVar != null) + time = timeVar.getValue(graph, Bindings.DOUBLE); + } + + if(time == null) + return null; + + // Find minimum and maximum values for this variable + double min = va[0], max = va[0]; + for(double d : va) { + if(d < min) + min = d; + if(d > max) + max = d; + } + + // Find the index in time and value arrays for this time + // (time steps may vary, we need to loop to find the correct time) + int index = 0; + if(ta[ta.length - 1] - time > ta[ta.length / 2] ) { + index = ta.length - 1; + while(ta[index] > time && index > 0) + index--; + } else { + while(ta[index] < time && index < ta.length - 1) + index++; + } + + double value = va[index]; + + // Calculate where the value is located between min and max values [0..1]. + double multiplier = (value - min) / (max - min); + + + // Get the transform of this element + AffineTransform at = (AffineTransform) DiagramGraphUtil.getAffineTransform(graph, element, G2DResource.getInstance(graph).HasTransform, true).clone(); + + // Find the gradient used to draw this style + G2DResource g2d = G2DResource.getInstance(graph); + Resource gradient = graph.getPossibleObject(experiment.getResource(), g2d.HasColorGradient); + if(this.gradientResource == null || !this.gradientResource.equals(gradient)) { + ArrayList colorValues = new ArrayList(); + for(Resource placement : graph.syncRequest(new ObjectsWithType(gradient, g2d.HasColorPlacement, g2d.ColorPlacement))) { + Double position = graph.getPossibleRelatedValue(placement, g2d.HasGradientPosition, Bindings.DOUBLE); + Resource rColor = graph.getPossibleObject(placement, g2d.HasColor); + if (rColor != null) { + colorValues.add(new ColorValue(new Color((java.awt.Color) G2DUtils.getObject(graph, rColor)), position)); + } + } + cg = new ColorGradient(colorValues, ColorGradient.HSV); + } else { + cg = this.cg; + } + + return new Triple(at, multiplier, cg); + + } catch(Exception ignore) { + ignore.printStackTrace(); + } + return null; + } + + @Override + public void styleResultChanged(Observer observer, Resource runtimeDiagram, Resource element, Triple result) { + if (result != null) + values.put(new Tuple2(runtimeDiagram, element), result); + else + values.remove(new Tuple2(runtimeDiagram, element)); + observer.update(); + } + + /** + * Apply style + */ + @Override + public void applyStyleForNode(EvaluationContext observer, INode _node, Triple result) { + Double multiplier; + if (result != null && (multiplier = result.second) != null && !multiplier.isNaN()) { + + // Create a node that will show the style effect + A node = ProfileVariables.claimChild(_node, "", "playbackColour", A.class, observer); + if (node == null) + return; + + AffineTransform at = result.first; + + if(this.cg == null || !this.cg.equals(result.third)) { + this.cg = result.third; + this.gradient = cg.getGradientArray(101); + } + + // Get integer values for red, green and blue + int i = (int)(multiplier * 100); + int r = (int)(gradient[i * 3 + 0] & 0xff); + int g = (int)(gradient[i * 3 + 1] & 0xff); + int b = (int)(gradient[i * 3 + 2] & 0xff); + // Get color with r, g and b + java.awt.Color c = new java.awt.Color(r, g, b, 200); + + // Create a node for the style + INode n = NodeUtil.getNearestChildByClass((SingleElementNode)_node, TextNode.class); + Rectangle2D expandedElementBounds = GeometryUtils.expandRectangle( NodeUtil.getLocalElementBounds(n), 0.0); + node.setFill(true); + node.setColor(c); + node.setStroke(null); + node.setValue("shape", expandedElementBounds); + node.setTransform(at); + + // Find z-index for the TextNode associated with the element and place the style node just below that text node + int zIndex = -1; + if(n != null) { + at = ((TextNode)n).getTransform(); + zIndex = ((TextNode)n).getZIndex() - 1; + } else { + n = _node; + } + node.setZIndex(zIndex); + + + } else { + cleanupStyleForNode(_node); + } + } + + @Override + protected void cleanupStyleForNode(INode node) { + ProfileVariables.denyChild(node, "", "playbackColour"); + } + + + /** + * Dummy class for displaying the style + * + * @author Teemu Lempinen + * + */ + public static class A extends ShapeNode { + + private static final long serialVersionUID = -5273246617906214956L; + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + + @Override + public Rectangle2D getBoundsInLocal(boolean b) { + return null; + } + + @Override + public Rectangle2D getBounds() { + return null; + } + + } +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/function/ModulesSearchFunction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/function/ModulesSearchFunction.java new file mode 100644 index 00000000..3caae72c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/function/ModulesSearchFunction.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.function; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ui.IWorkbenchPage; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.layer0.genericrelation.Dependencies; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.operation.Layer0X; +import org.simantics.scl.runtime.function.FunctionImpl5; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.handlers.FindSearchTrim; +import org.simantics.sysdyn.ui.handlers.FindSearchTrim.Scope; +import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils; +import org.simantics.workbench.search.NameAndTypeRow; +import org.simantics.workbench.search.NamedResource; +import org.simantics.workbench.search.SearchQuery; +import org.simantics.workbench.search.SearchResult; +import org.simantics.workbench.search.Searching; + +/** + * modulesSearchFunction: + * (IProgressMonitor, ReadGraph, model : Resource, query : String, maxResults : Integer) -> QueryResult + * + * @author Tuukka Lehtonen + * @author Tuomas Miettinen + */ +public class ModulesSearchFunction extends FunctionImpl5 { + + private final int MAX_RESULTS = 50000; + + @Override + public SearchResult apply(IProgressMonitor monitor, ReadGraph graph, Resource model, SearchQuery query, Integer maxResults) { + try { + // Check whether only currently open diagram is searched + String filteredQuery = query.getQuery("Name","Types"); + Collection> results = Searching.performSearch(graph, Layer0X.getInstance(graph).Dependencies, model, filteredQuery, MAX_RESULTS); + + if (!query.getSearchParams().contains(FindSearchTrim.CURRENT_DIAGRAM_OPTION)) + return generateSearchResults(graph, results, Scope.ALL_MODELS); + else + return generateSearchResults(graph, results, Scope.CURRENT_DIAGRAM); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + return null; + } + + private static boolean resourceFoundInCurrentDiagram(ReadGraph graph, Resource diagram) throws ManyObjectsForFunctionalRelationException, ServiceException { + + IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor(); + DiagramEditor editor = (DiagramEditor)page.getActiveEditor(); + if (editor != null) { + Resource inputResource = editor.getInputResource(); + ModelingResources MOD = ModelingResources.getInstance(graph); + Resource editorResource = graph.getPossibleObject(inputResource, MOD.DiagramToComposite); + if (diagram.equalsResource(editorResource)) + return true; + } + return false; + } + + private static final SearchResult generateSearchResults(ReadGraph graph, + Collection> results, Scope scope) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + DiagramResource DIA = DiagramResource.getInstance(graph); + SysdynResource SYSDYN = SysdynResource.getInstance(graph); + + SearchResult result = new SearchResult(NameAndTypeRow.columns); + Set processed = new HashSet(); + + for (Map r : results) { + Resource resource = (Resource) r.get(Dependencies.FIELD_RESOURCE); + + // Only Auxiliary, Stock, Valve, Input, and Module + if (!(graph.isInstanceOf(resource, SYSDYN.IndependentVariable) + || graph.isInstanceOf(resource, SYSDYN.Input) + || graph.isInstanceOf(resource, SYSDYN.Module))) + continue; + + // Prevent index corruption from producing duplicate results. + if (!processed.add(resource)) + continue; + + // Prevent diagram elements from being collected into the results. + Collection typeResources = graph.getTypes(resource); + if (typeResources.contains(DIA.Element)) + continue; + + // Check if the result is found in the open diagram. + Resource parent = (Resource) r.get(Dependencies.FIELD_PARENT); + if (scope == Scope.CURRENT_DIAGRAM && + !resourceFoundInCurrentDiagram(graph, parent)) + continue; + + String name = (String) r.get(Dependencies.FIELD_NAME); + NameAndTypeRow rst = new NameAndTypeRow(); + rst.resource = NamedResource.of(graph, resource, name); + rst.parent = NamedResource.of(graph, parent); + + Collection principalTypeResources = graph.getPrincipalTypes(resource); + if (!typeResources.isEmpty()) { + rst.types = new ArrayList(typeResources.size()); + rst.principalTypes = new ArrayList(principalTypeResources.size()); + for (Resource t : typeResources) { + String aprosName = graph.getPossibleRelatedValue(t, L0.HasName, Bindings.STRING); + if (aprosName == null) + aprosName = NameUtils.getSafeLabel(graph, t); + NamedResource nr = NamedResource.of(graph, t, aprosName); + rst.types.add(nr); + if (principalTypeResources.contains(t)) + rst.principalTypes.add(nr); + } + } + + result.addRow(rst); + } + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ChartPanelOrientationHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ChartPanelOrientationHandler.java new file mode 100644 index 00000000..2d32ce84 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ChartPanelOrientationHandler.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.menus.UIElement; +import org.simantics.jfreechart.ChartPanel; +import org.simantics.sysdyn.ui.Activator; + +/** + * This handler changes the orientation of a {@link ChartPanel} + * + * @author Teemu Lempinen + * + */ +public class ChartPanelOrientationHandler extends AbstractHandler implements IElementUpdater { + + private static String COMMAND = "org.simantics.sysdyn.ui.chartPanelOrientation"; + + /** + * Read chart panel settings from IDialogSettings and change the orientation accordingly. + * Finally order the element to update its appearance. + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchPart part = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getActivePart(); + if(part instanceof ChartPanel) { + IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(ChartPanel.CHART_PANEL_SETTINGS); + if (settings == null) { + settings = Activator.getDefault().getDialogSettings().addNewSection(ChartPanel.CHART_PANEL_SETTINGS); + } + + String orientation = settings.get(ChartPanel.CHART_PANEL_ORIENTATION); + if(orientation == null) + settings.put(ChartPanel.CHART_PANEL_ORIENTATION, ChartPanel.CHART_PANEL_HORIZONTAL); + + if(ChartPanel.CHART_PANEL_VERTICAL.equals(orientation)) + orientation = ChartPanel.CHART_PANEL_HORIZONTAL; + else + orientation = ChartPanel.CHART_PANEL_VERTICAL; + + settings.put(ChartPanel.CHART_PANEL_ORIENTATION, orientation); + ((ChartPanel)part).setOrientation(orientation); + + ICommandService commandService = + (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + commandService.refreshElements(COMMAND, null); + } + + return null; + } + + /** + * Update the icon of the element. The new icon and text are always opposite to the current situation. + */ + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + if(parameters == null) + return; + + IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(ChartPanel.CHART_PANEL_SETTINGS); + if(settings == null) + return; + + String orientation = settings.get(ChartPanel.CHART_PANEL_ORIENTATION); + if(orientation == null) + return; + + // Show the opposite icon and text to indicate change when the button is pressed + if(ChartPanel.CHART_PANEL_HORIZONTAL.equals(orientation)) { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/page_white_text.png"))); + element.setTooltip("Vertical Orientation"); + } else if (ChartPanel.CHART_PANEL_VERTICAL.equals(orientation)) { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/page_white_text_width.png"))); + element.setTooltip("Horizontal Orientation"); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.java new file mode 100644 index 00000000..7f4a2515 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.java @@ -0,0 +1,67 @@ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.handlers.RadioState; +import org.simantics.g2d.canvas.Hints; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.IToolMode; +import org.simantics.sysdyn.ui.elements.SysdynElementHints; +import org.simantics.utils.threads.ThreadUtils; + +public class DiagramToolHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + final ICanvasContext context = (ICanvasContext)HandlerUtil.getActiveEditor(event).getAdapter(ICanvasContext.class); + if (context == null) { + throw new ExecutionException("Could not get context from editor"); + } + + String value = (String)event.getCommand().getState(RadioState.STATE_ID).getValue(); + + final IToolMode mode; + if ("pointer".equals(value)) { + mode = Hints.POINTERTOOL; + } + else if ("dependency".equals(value)) { + mode = SysdynElementHints.DEPENDENCY_TOOL; + } + else if ("flow".equals(value)) { + mode = SysdynElementHints.FLOW_TOOL; + } + else if ("lock".equals(value)) { + mode = SysdynElementHints.LOCK_TOOL; + } + else { + return null; + } + + ThreadUtils.syncExec(context.getThreadAccess(), new Runnable() { + @Override + public void run() { + if (mode.equals(SysdynElementHints.DEPENDENCY_TOOL) + || mode.equals(SysdynElementHints.FLOW_TOOL)) { + // if one of the connection modes is selected, use the + // default connection tool as the base and indicate the + // desired connection type in another hint (this is done + // to make sure all features of the connection tool work + // as expected) + context.getDefaultHintContext().setHint(Hints.KEY_TOOL, Hints.CONNECTTOOL); + context.getDefaultHintContext().setHint(SysdynElementHints.SYSDYN_KEY_TOOL, mode); + } else if (mode.equals(SysdynElementHints.LOCK_TOOL)) { + context.getDefaultHintContext().setHint(Hints.KEY_TOOL, Hints.POINTERTOOL); + context.getDefaultHintContext().setHint(SysdynElementHints.SYSDYN_KEY_TOOL, mode); + } else { + context.getDefaultHintContext().setHint(Hints.KEY_TOOL, mode); + context.getDefaultHintContext().removeHint(SysdynElementHints.SYSDYN_KEY_TOOL); + } + } + }); + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DisposeExperiment.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DisposeExperiment.java new file mode 100644 index 00000000..83ef73bb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DisposeExperiment.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.ui.utils.HandlerUtils; +import org.simantics.ui.SimanticsUI; + +public class DisposeExperiment extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + HandlerUtils.saveBeforeExperimentRun(event); + + IProject project = SimanticsUI.getProject(); + IExperimentManager manager = + project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if (experiment != null) + experiment.shutdown(); + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/EnumerationPasteHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/EnumerationPasteHandler.java new file mode 100644 index 00000000..a37cb37c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/EnumerationPasteHandler.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; + +public class EnumerationPasteHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection sel = HandlerUtil.getCurrentSelection(event); + System.out.println("PASTE " + sel); + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ExtendedCopyPasteHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ExtendedCopyPasteHandler.java new file mode 100644 index 00000000..1295e087 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ExtendedCopyPasteHandler.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import java.util.Set; + +import org.eclipse.jface.action.IStatusLineManager; +import org.simantics.diagram.elements.TextElementNoBounds; +import org.simantics.diagram.elements.TextNode; +import org.simantics.diagram.handler.CopyPasteHandler; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.element.IElement; +import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; +import org.simantics.scenegraph.g2d.events.command.CommandEvent; +import org.simantics.scenegraph.g2d.events.command.Commands; +import org.simantics.sysdyn.ui.editor.participant.SysdynCopyPasteStrategy; + +/** + * ExtendedCopyPasteHandler is a canvas handler for Commands.CUT, Commands.COPY, + * Commands.PASTE, and Commands.RENAME commands for an IDiagram. + * + *

+ * The handler attempts to copy/paste the current selection for pointer 0, + * meaning {@link Selection#SELECTION0}. + *

+ * + *

+ * The handler logic follows the specifications at UC:Copy Item + * and UC:Cut + * Item. + *

+ * + * @see Selection current diagram selection source + * + * @author Tuomas Miettinen + * + */ +public class ExtendedCopyPasteHandler extends CopyPasteHandler { + + @Dependency + private Selection sel; + + public ExtendedCopyPasteHandler(IStatusLineManager statusLine) { + super(new SysdynCopyPasteStrategy(), statusLine); + } + + @EventHandler(priority = 0) + public boolean handleCommand(CommandEvent e) { + if (e.command.equals( Commands.RENAME) ) { + initiateRename(e); + return true; + } + else return super.handleCommand(e); + } + + private boolean initiateRename(CommandEvent e) { + int selectionId = 0; + Set ss = sel.getSelection(selectionId); + + ICanvasContext ctx = getContext(); + if (ctx == null) + return false; + IElement ie = null; + TextNode node = null; + + //If multiple selected, just pick one + for (IElement temp : ss){ + if (temp != null) { + node = (TextNode)temp.getHint(TextElementNoBounds.SG_NODE); + if (node != null){ + ie = temp; + break; + } + } + } + if (ie != null) { + if (node != null && Boolean.TRUE.equals(node.setEditMode(true))) { + node.activateEdit(0, ie, ctx); + node.repaint(); + return true; + } + } + return false; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceDialog.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceDialog.java new file mode 100644 index 00000000..f467523d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceDialog.java @@ -0,0 +1,107 @@ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.simantics.sysdyn.ui.handlers.FindSearchTrim.Scope; + +/** + * Find dialog for finding variables in diagrams. + * @author Tuomas Miettinen + * + */ +public class FindReplaceDialog extends Dialog { + + private FindSearchTrim search; + + private Button scopeButtonAllModels; + private Button scopeButtonCurrentDiagram; + private Scope scope; + private boolean diagramOpen; + + protected FindReplaceDialog(Shell parentShell, Scope scope, boolean diagramOpen) { + super(parentShell); + setBlockOnOpen(false); + this.scope = scope; + this.diagramOpen = diagramOpen; + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = ( Composite )super.createDialogArea(parent); + composite.getShell().setText("Find"); + GridLayoutFactory.fillDefaults().margins(5, 5).numColumns(2).applyTo(composite); + + Label label = new Label(composite, SWT.NONE); + label.setText("Find: "); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).hint(40, SWT.DEFAULT).applyTo(label); + + search = new FindSearchTrim(composite); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(search); + + Group scopeGroup = new Group(composite, SWT.SHADOW_NONE); + scopeGroup.setText("Scope"); + GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(scopeGroup); + GridLayoutFactory.fillDefaults().margins(5, 5).applyTo(scopeGroup); + + Composite scopeComposite = new Composite(scopeGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(scopeComposite); + GridLayoutFactory.fillDefaults().applyTo(scopeComposite); + + scopeButtonCurrentDiagram = new Button(scopeComposite, SWT.RADIO); + scopeButtonCurrentDiagram.setText("Current Diagram"); + scopeButtonCurrentDiagram.setSelection(scope == Scope.CURRENT_DIAGRAM); + scopeButtonCurrentDiagram.setEnabled(diagramOpen); + GridDataFactory.fillDefaults().applyTo(scopeButtonCurrentDiagram); + + scopeButtonAllModels = new Button(scopeComposite, SWT.RADIO); + scopeButtonAllModels.setText("All Models"); + scopeButtonAllModels.setSelection(scope == Scope.ALL_MODELS); + GridDataFactory.fillDefaults().applyTo(scopeButtonAllModels); + + return composite; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + // Replace "OK" with "Find". + createButton(parent, IDialogConstants.OK_ID, "Find", + true); + createButton(parent, IDialogConstants.CANCEL_ID, + "Close", false); + } + + @Override + protected void cancelPressed() { + setReturnCode(CANCEL); + close(); + } + + @Override + protected void okPressed() { + if (scopeButtonAllModels.getSelection()) + scope = Scope.ALL_MODELS; + else if (scopeButtonCurrentDiagram.getSelection()) + scope = Scope.CURRENT_DIAGRAM; + else + scope = Scope.ALL_MODELS; + search.findNameAndTypeQuery(scope); + setReturnCode(OK); + close(); + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceHandler.java new file mode 100644 index 00000000..5239aec0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceHandler.java @@ -0,0 +1,61 @@ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.sysdyn.ui.browser.SysdynBrowser; +import org.simantics.sysdyn.ui.editor.DiagramViewer; +import org.simantics.sysdyn.ui.handlers.FindSearchTrim.Scope; + +/** + * Handler for Ctrl+F + * @author Tuomas Miettinen + * + */ +public class FindReplaceHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + IEditorPart editor = (IEditorPart)HandlerUtil.getActiveEditor(event); + IWorkbenchPart workbenchPart = (IWorkbenchPart)HandlerUtil.getActivePart(event); + + Shell shell = HandlerUtil.getActiveShell(event); + if(shell == null) + return null; + + // If there is something else in the diagram view, do not allow search in current diagram + if (!(editor instanceof DiagramEditor) || !(((DiagramEditor) editor).getViewer() instanceof DiagramViewer)) { + if (workbenchPart != null && workbenchPart instanceof SysdynBrowser) { + // If focus is on model browser, allow search in all models. + FindReplaceDialog dialog = new FindReplaceDialog(shell, Scope.ALL_MODELS, false); + dialog.open(); + } + return null; + } + + final DiagramViewer viewer = (DiagramViewer) ((DiagramEditor) editor).getViewer(); + if (viewer == null) + return null; + + Object d = viewer.getAdapter(IDiagram.class); + if (workbenchPart != null && workbenchPart instanceof SysdynBrowser) { + // If focus is on model browser, default search in all models, allow also current diagram. + FindReplaceDialog dialog = new FindReplaceDialog(shell, Scope.ALL_MODELS, true); + dialog.open(); + } else if (d != null && d instanceof IDiagram && workbenchPart instanceof DiagramEditor) { + // If focus is on diagram editor, default search in current diagram, allow also all models. + FindReplaceDialog dialog = new FindReplaceDialog(shell, Scope.CURRENT_DIAGRAM, true); + dialog.open(); + } + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindSearchTrim.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindSearchTrim.java new file mode 100644 index 00000000..502410ca --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindSearchTrim.java @@ -0,0 +1,49 @@ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.simantics.workbench.internal.contributions.search.SearchTrim; +import org.simantics.workbench.search.ISearchService; +import org.simantics.workbench.search.SearchQuery; + +public class FindSearchTrim extends SearchTrim { + + public static enum Scope { + CURRENT_DIAGRAM, + ALL_MODELS + } + + public static final String CURRENT_DIAGRAM_OPTION = "@Current_diagram"; + + public FindSearchTrim(Composite parent) { + super(parent); + GridDataFactory.fillDefaults().hint(160, SWT.DEFAULT).grab(true, true).applyTo(searchText); + } + + public void findNameAndTypeQuery(Scope scope) { + + String originalQuery = searchText.getText(); + String query = originalQuery; + + // Don't allow empty queries + if (query.trim().isEmpty()) + return; + +// query = filter(query); +// query = "Name:" + query + " OR Types:" + query; + + // Add option for showing only findings in currently open diagram +// if (scope == Scope.CURRENT_DIAGRAM) +// query += " " + CURRENT_DIAGRAM_OPTION; +// SearchQuery searchQuery = new SearchQuery(originalQuery,query); + SearchQuery searchQuery = new SearchQuery(originalQuery); + searchQuery.setSearchFlag("Name", "on"); + searchQuery.setSearchFlag("Types", "on"); + if (scope == Scope.CURRENT_DIAGRAM) + searchQuery.setSearchParam(CURRENT_DIAGRAM_OPTION); + performQuery(searchQuery, ISearchService.ResultBrowser.VIEW); + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialDialog.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialDialog.java new file mode 100644 index 00000000..a593b186 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialDialog.java @@ -0,0 +1,85 @@ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * Paste special dialog for copying variables in diagram. Default method is to add a number to the end of the variable name. + * Special paste enables users to define their own prefix and/or suffix to the copied variable name(s). + * @author Teemu Lempinen + * + */ +public class PasteSpecialDialog extends Dialog { + + private Text prefixText, suffixText; + private String prefix, suffix; + + protected PasteSpecialDialog(Shell parentShell) { + super(parentShell); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = ( Composite )super.createDialogArea(parent); + composite.getShell().setText("Paste Special"); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + Label label = new Label(composite, SWT.NONE); + label.setText("Prefix will be added to the beginning of\nthe copied variables, suffix to the end."); + GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(label); + + + label = new Label(composite, SWT.NONE); + label.setText("Prefix: "); + label.setToolTipText("Text added to the beginning of a copied variable name"); + GridDataFactory.fillDefaults().applyTo(label); + + prefixText = new Text(composite, SWT.BORDER); + prefixText.setToolTipText("Text added to the beginning of a copied variable name"); + GridDataFactory.fillDefaults().applyTo(prefixText); + + label = new Label(composite, SWT.NONE); + label.setText("Suffix: "); + label.setToolTipText("Text added to the end of a copied variable name"); + GridDataFactory.fillDefaults().applyTo(label); + + suffixText = new Text(composite, SWT.BORDER); + suffixText.setToolTipText("Text added to the end of a copied variable name"); + GridDataFactory.fillDefaults().applyTo(suffixText); + + return composite; + } + + public String getPrefix() { + return prefix; + } + + public String getSuffix() { + return suffix; + } + + @Override + protected void cancelPressed() { + prefix = ""; + suffix = ""; + setReturnCode(CANCEL); + close(); + } + + @Override + protected void okPressed() { + prefix = prefixText.getText(); + suffix = suffixText.getText(); + setReturnCode(OK); + close(); + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialHandler.java new file mode 100644 index 00000000..9ed9bde5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialHandler.java @@ -0,0 +1,86 @@ +package org.simantics.sysdyn.ui.handlers; + +import java.util.Set; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.Simantics; +import org.simantics.db.layer0.util.ClipboardUtils; +import org.simantics.db.layer0.util.SimanticsClipboard.Representation; +import org.simantics.diagram.handler.CopyPasteHandler; +import org.simantics.diagram.handler.DiagramSelection; +import org.simantics.diagram.handler.DiagramSelectionRepresentation; +import org.simantics.diagram.synchronization.SynchronizationHints; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.modeling.mapping.ElementCopyAdvisor; +import org.simantics.modeling.mapping.MappedElementCopyAdvisor; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.scenegraph.g2d.events.command.Commands; +import org.simantics.sysdyn.ui.editor.DiagramViewer; +import org.simantics.sysdyn.ui.editor.participant.SysdynSpecialComponentCopyAdvisor; + +/** + * Handler for copying variables with custom prefix and/or suffix + * @author Teemu Lempinen + * + */ +public class PasteSpecialHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + IEditorPart editor = (IEditorPart)HandlerUtil.getActiveEditor(event); + if (!(editor instanceof DiagramEditor)) + return null; + final DiagramViewer viewer = (DiagramViewer) ((DiagramEditor) editor).getViewer(); + if (viewer == null) + return null; + + Object d = viewer.getAdapter(IDiagram.class); + if(d != null && d instanceof IDiagram) { + IDiagram diagram = (IDiagram) d; + MappedElementCopyAdvisor standardCopyAdvisor = diagram.getHint(SynchronizationHints.COPY_ADVISOR); + + Shell shell = viewer.getComposite().getShell(); + if(shell == null) + return null; + + PasteSpecialDialog dialog = new PasteSpecialDialog(shell); + if(dialog.open() == Window.CANCEL) + return null; + + String prefix = dialog.getPrefix(); + String suffix = dialog.getSuffix(); + + diagram.setHint(SynchronizationHints.COPY_ADVISOR, new MappedElementCopyAdvisor(new ElementCopyAdvisor(), new SysdynSpecialComponentCopyAdvisor(prefix, suffix))); + + Object v = viewer.getAdapter(ICanvasContext.class); + if(v != null && v instanceof ICanvasContext) { + ICanvasContext ctx = (ICanvasContext) v; + CopyPasteHandler handler = ctx.getAtMostOneItemOfClass(CopyPasteHandler.class); + if(handler != null) { + handler.paste(Commands.PASTE, getClipboardDiagramSelection()); + } + } + + diagram.setHint(SynchronizationHints.COPY_ADVISOR, standardCopyAdvisor); + + } + return null; + } + + public DiagramSelection getClipboardDiagramSelection() { + for (Set content : Simantics.getClipboard().getContents()) { + DiagramSelection sel = ClipboardUtils.accept(content, DiagramSelectionRepresentation.KEY_DIAGRAM_SELECTION); + if (sel != null) + return sel; + } + return DiagramSelection.EMPTY; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RemoveNodeHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RemoveNodeHandler.java new file mode 100644 index 00000000..e2ee3669 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RemoveNodeHandler.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.CancelTransactionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ui.ExceptionUtils; + +/** + * @author Tuukka Lehtonen + */ +public class RemoveNodeHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShellChecked(event); + ISelection sel = HandlerUtil.getCurrentSelection(event); + Resource[] resources = ResourceAdaptionUtils.toResources(sel); + if (resources.length == 0) + return null; + + MessageDialog dialog = new MessageDialog(shell, "Remove Item", null, "Are you sure?", 0, + new String[] { "OK", "Cancel" }, 0); + dialog.create(); + if (dialog.open() == 0) + deleteItem(resources); + + return null; + } + + public static void deleteItem(final Resource[] resources) { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException { + for (Resource r : resources) + RemoverUtil.remove(graph, r); + } + }); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + } + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameNodeHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameNodeHandler.java new file mode 100644 index 00000000..4cb78c8e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameNodeHandler.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.browsing.ui.GraphExplorer; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.utils.ui.ISelectionUtils; + +public class RenameNodeHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection sel = HandlerUtil.getCurrentSelection(event); + NodeContext ctx = ISelectionUtils.filterSingleSelection(sel, NodeContext.class); + if (ctx == null) + return null; + + IWorkbenchPart part = HandlerUtil.getActivePart(event); + if (part == null) + return null; + + GraphExplorer graphExplorer = (GraphExplorer) part.getAdapter(GraphExplorer.class); + if (graphExplorer != null) + graphExplorer.startEditing(ctx, ColumnKeys.SINGLE); + + return null; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RunBasicExperiment.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RunBasicExperiment.java new file mode 100644 index 00000000..1eba038f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RunBasicExperiment.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IDynamicExperiment; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynExperiment; +import org.simantics.sysdyn.ui.utils.HandlerUtils; +import org.simantics.ui.SimanticsUI; + +public class RunBasicExperiment extends AbstractHandler implements IElementUpdater { + + public static final String COMMAND = "org.simantics.sysdyn.ui.run"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + HandlerUtils.saveBeforeExperimentRun(event); + + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment instanceof IDynamicExperiment) + ((IDynamicExperiment)experiment).simulate(true); + return null; + } + + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment instanceof SysdynExperiment) { + ExperimentState state = experiment.getState(); + if(state == ExperimentState.RUNNING) { + this.setBaseEnabled(false); + } else { + this.setBaseEnabled(true); + } + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveResultsHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveResultsHandler.java new file mode 100644 index 00000000..616f835c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveResultsHandler.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.simulation.experiment.IDynamicExperiment; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.ui.utils.HandlerUtils; +import org.simantics.ui.SimanticsUI; + +public class SaveResultsHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + HandlerUtils.saveBeforeExperimentRun(event); + + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment instanceof IDynamicExperiment) { + ((IDynamicExperiment)experiment).saveState(); + } + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ShowModuleHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ShowModuleHandler.java new file mode 100644 index 00000000..0514909f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ShowModuleHandler.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.modeling.ComponentUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.editor.DiagramViewer; +import org.simantics.sysdyn.ui.editor.SysdynEditorInput; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ui.workbench.WorkbenchUtils; + + +public class ShowModuleHandler extends AbstractHandler { + + private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection s = HandlerUtil.getCurrentSelectionChecked(event); + final Resource resources[] = ResourceAdaptionUtils.toResources(s); + IEditorPart editor = (IEditorPart)HandlerUtil.getActiveEditor(event); + if (!(editor instanceof DiagramEditor)) + return null; + final DiagramViewer viewer = (DiagramViewer) ((DiagramEditor) editor).getViewer(); + if (viewer == null) + return null; + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + + DiagramResource dr = DiagramResource.getInstance(graph); + Resource runtime = viewer.getRuntime(); + String uri = graph.getPossibleRelatedValue(runtime, dr.RuntimeDiagram_HasVariable, Bindings.STRING); + Variable parent = Variables.getVariable(graph, uri); + final Resource model = Variables.getModel(graph, parent); + + for(Resource element : resources) { + + ModelingResources mr = ModelingResources.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 st = StructuralResource2.getInstance(graph); + + final Resource component = graph.getPossibleObject(element, mr.ElementToComponent); + final Resource componentType = graph.getPossibleType(component, sr.Module); + final Resource configuration = graph.getPossibleObject(componentType, st.IsDefinedBy); + final Resource diagram = ComponentUtils.getPossibleCompositeDiagram(graph, configuration); + + Variable variable; + String rvi = ""; + try { + variable = parent.browse(graph, component); + rvi = Variables.getRVI(graph, variable); + } catch (MissingVariableException e ) { + variable = Variables.getVariable(graph, graph.getURI(component)); + } + final String finalRvi = rvi; + + + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + try { + String editorId = EDITOR_ID; + WorkbenchUtils.openEditor(editorId, new SysdynEditorInput(editorId, diagram, model, finalRvi)); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + }); + + } + + } + }); + + return null; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SysdynExperimentActivator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SysdynExperimentActivator.java new file mode 100644 index 00000000..f4a52dfb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SysdynExperimentActivator.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import java.util.concurrent.Semaphore; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.AdaptionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.message.MessageService; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.model.ExperimentLoadingFailed; +import org.simantics.simulation.project.IExperimentActivationListener; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.ui.listeners.SysdynExperimentManagerListener; +import org.simantics.utils.DataContainer; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.ExceptionUtils; +import org.simantics.utils.ui.dialogs.ShowMessage; + +public class SysdynExperimentActivator { + /** + * @param project + * @param experimentManager + * @param experiment + */ + public static void scheduleActivation(RequestProcessor processor, final IProject project, final IExperimentManager experimentManager, final Resource experiment) { + String jobName = "Activate Experiment"; + String experimentName = getName(processor, experiment); + if (experimentName != null) + jobName += " '" + experimentName + "'"; + /* + // Shut down the previous active experiment + IExperiment activeExperiment = experimentManager.getActiveExperiment(); + if (experiment != null) + activeExperiment.shutdown(); + */ + // Activate a new experiment + scheduleActivation(jobName, project, experimentManager, experiment); + } + + /** + * @param project + * @param experimentManager + * @param experiment + */ + public static void scheduleActivation(String jobName, final IProject project, final IExperimentManager experimentManager, final Resource experiment) { + new Job(jobName) { + @Override + protected IStatus run(final IProgressMonitor monitor) { + return SysdynExperimentActivator.activate(monitor, project, experimentManager, experiment); + } + }.schedule(); + } + + public static IStatus activate(IProgressMonitor monitor, IProject project, IExperimentManager experimentManager, Resource experiment) { + return new SysdynExperimentActivator().activateExperiment(monitor, project, experimentManager, experiment); + } + + private static String getName(RequestProcessor processor, final Resource resource) { + try { + return processor.syncRequest(new Read() { + @Override + public String perform(ReadGraph graph) throws DatabaseException { + try { + return graph.adapt(resource, String.class); + } catch (AdaptionException e) { + return NameUtils.getSafeName(graph, resource); + } + } + }); + } catch (DatabaseException e) { + ErrorLogger.defaultLogWarning(e); + return null; + } + } + + private IStatus activateExperiment(final IProgressMonitor monitor, final IProject project, final IExperimentManager manager, final Resource experimentResource) { + monitor.beginTask("Activating experiment", IProgressMonitor.UNKNOWN); + try { + SysdynExperimentManagerListener.listenManager(manager); + IExperiment[] experiments = manager.getExperiments(); + for(IExperiment e : experiments) + if(e.getState() != ExperimentState.DISPOSED) + e.shutdown(); + + final Semaphore activated = new Semaphore(0); + final DataContainer problem = new DataContainer(); + manager.startExperiment(experimentResource, new IExperimentActivationListener() { + + @Override + public void onExperimentActivated(final IExperiment experiment) { + MessageService.defaultLog(new org.eclipse.core.runtime.Status(IStatus.INFO, "org.simantics.simulation.ui", 0, "Activated experiment " + experiment.getIdentifier() , null)); + activated.release(); + } + @Override + public void onFailure(Throwable e) { + problem.set(e); + activated.release(); + } + @Override + public void onMessage(IStatus message) { + MessageService.getDefault().log(message); + /*ILogger logger = MessageService.getDefault(); + MultiStatus init = new MultiStatus(Activator.PLUGIN_ID, 0, "Activating experiment", null); + for (String msg : messages) { + init.add(new Status(IStatus.INFO, Activator.PLUGIN_ID, msg)); + } + logger.log(init);*/ + } + }, true); + try { + activated.acquire(); + Throwable t = problem.get(); + if (t != null) { + if (t instanceof ExperimentLoadingFailed) { + ErrorLogger.defaultLogError(t); + ShowMessage.showError("Experiment Activation Failed", t.getMessage()); + } else { + ExceptionUtils.logAndShowError(t); + } + } + + return Status.OK_STATUS; + //return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Experiment activation failed, see exception for details.", problem.get()); + } catch (InterruptedException e) { + return Status.CANCEL_STATUS; + } + } finally { + monitor.done(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultActivation.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultActivation.java new file mode 100644 index 00000000..024c6cbc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultActivation.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +public class ToggleResultActivation extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection sel = HandlerUtil.getCurrentSelection(event); + Resource[] resources = ResourceAdaptionUtils.toResources(sel); + if (resources.length == 0) + return null; + + toggleActivation(resources); + + return null; + } + + public static void toggleActivation(final Resource[] resources) { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource r : resources) { + if(graph.isInstanceOf(r, sr.Result)) { + if (graph.hasStatement(r, sr.Result_showResult)) { + graph.denyStatement(r, sr.Result_showResult, r); + } else { + graph.claim(r, sr.Result_showResult, r); + } + } + } + } + + }); + } catch (DatabaseException e) { + + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultSetActivation.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultSetActivation.java new file mode 100644 index 00000000..a667a8c0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultSetActivation.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import java.util.Collection; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +public class ToggleResultSetActivation extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection sel = HandlerUtil.getCurrentSelection(event); + Resource[] resources = ResourceAdaptionUtils.toResources(sel); + if (resources.length == 0) + return null; + + toggleActivation(resources); + + return null; + } + + public static void toggleActivation(final Resource[] resources) { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource r : resources) { + // If there is at least one result which shown, clear them all. + // If not one result is shown, show them all. + boolean resultShown = false; + Collection results = graph.getObjects(r, sr.Experiment_result); + for (Resource result : results) { + if (graph.hasStatement(result, sr.Result_showResult)) { + resultShown = true; + break; + } + } + for (Resource result : results) { + if (resultShown) { + graph.denyStatement(result, sr.Result_showResult, result); + } else { + graph.claim(result, sr.Result_showResult, result); + } + } + } + } + + }); + } catch (DatabaseException e) { + + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleSimulation.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleSimulation.java new file mode 100644 index 00000000..79fa0ffd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleSimulation.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.State; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynExperiment; +import org.simantics.sysdyn.ui.utils.HandlerUtils; +import org.simantics.ui.SimanticsUI; + +public class ToggleSimulation extends AbstractHandler implements IElementUpdater { + + public static final String COMMAND = "org.simantics.sysdyn.ui.toggleSimulation"; + public static final String STATE = "org.simantics.sysdyn.ui.toggleSimulation.state"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + Command command = service.getCommand(COMMAND); + State state = command.getState(STATE); + Boolean value = (Boolean) state.getValue(); + value = !value; + state.setValue(value); + service.refreshElements(RunBasicExperiment.COMMAND, null); + + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment instanceof SysdynExperiment) { + if(getState()) { + ((SysdynExperiment)experiment).toggleSimulation(true); + } else { + ((SysdynExperiment)experiment).toggleSimulation(false); + } + } + + HandlerUtils.saveBeforeExperimentRun(event); + + return null; + } + + public static Boolean getState() { + ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + Command command = service.getCommand(COMMAND); + State state = command.getState(STATE); + return (Boolean)state.getValue(); + } + + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + ICommandService commandService = + (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + Command command = commandService.getCommand(COMMAND); + boolean checked = (Boolean) command.getState(STATE).getValue(); + element.setChecked(checked); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/UnlinkNodeHandler2.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/UnlinkNodeHandler2.java new file mode 100644 index 00000000..46890720 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/UnlinkNodeHandler2.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers; + +import java.util.Set; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.model.nodetypes.NodeType; +import org.simantics.modeling.ui.modelBrowser.handlers.DeleteNodeHandler; +import org.simantics.utils.ui.ISelectionUtils; + +public class UnlinkNodeHandler2 extends DeleteNodeHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShellChecked(event); + ISelection sel = HandlerUtil.getCurrentSelection(event); + + Set ctxs = ISelectionUtils.filterSetSelection(sel, NodeContext.class); + + NodeType previousNodeType = null; + for (NodeContext ctx : ctxs) { + NodeType nodeType = ctx.getConstant(NodeType.TYPE); + if(previousNodeType == null) { + previousNodeType = nodeType; + } else if(!previousNodeType.equals(nodeType)) { + MessageDialog dialog = new MessageDialog(shell, "Unable to remove", null, "Only items of same type can be removed at the same time.", 0, + new String[] { "OK" }, 0); + dialog.create(); + dialog.open(); + return null; + } + } + + MessageDialog dialog = new MessageDialog(shell, "Remove Item", null, "Are you sure?", 0, + new String[] { "OK", "Cancel" }, 0); + dialog.create(); + if (dialog.open() == 0) { + super.execute(event); + } + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportExternalFunctionFilesHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportExternalFunctionFilesHandler.java new file mode 100644 index 00000000..fe9d1934 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportExternalFunctionFilesHandler.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.exports; + +import java.io.FileOutputStream; +import java.io.IOException; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +/** + * Exports external function files from SysdynModelicaFunctions + * + * @author Teemu Lempinen + * + */ +public class ExportExternalFunctionFilesHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // Find shell and resources to be exported + Shell shell = HandlerUtil.getActiveShellChecked(event); + ISelection sel = HandlerUtil.getCurrentSelection(event); + final Resource[] resources = ResourceAdaptionUtils.toResources(sel); + if (resources.length < 1) + return null; + + return exportFiles(shell, resources); + } + + /** + * Exports selected file resources to files on disk. Assumes all resources are external files. + * + * @param shell SWT Shell + * @param resources External file resources + * @return null + */ + public static Object exportFiles(Shell shell, final Resource[] resources) { + + // Select a path where to export the files + DirectoryDialog dd = new DirectoryDialog(shell); + dd.setFilterPath(Platform.getLocation().toOSString()); + dd.setText("Export files to..."); + dd.setMessage("Select a directory"); + final String dir = dd.open(); + if (dir == null) { + return null; + } + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + // Get byte arrays from each resource and write them to disk + for(Resource r : resources) { + try { + String name = NameUtils.getSafeName(graph, r); + FileOutputStream fos = new FileOutputStream(dir + "\\" + name); + byte[] fileBArray = graph.getPossibleRelatedValue(r, sr.ExternalFunctionFile_externalFile, Bindings.BYTE_ARRAY); + fos.write(fileBArray); + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + }); + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportFunctionLibrary.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportFunctionLibrary.java new file mode 100644 index 00000000..002abbbd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportFunctionLibrary.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2007, 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.exports; + +import java.io.File; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.primitiverequest.PossibleRelatedValue; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest; +import org.simantics.db.layer0.util.TransferableGraphConfiguration2; +import org.simantics.db.request.Read; +import org.simantics.graph.db.TransferableGraphSource; +import org.simantics.graph.db.TransferableGraphs; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +/** + * Exports a function library + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ExportFunctionLibrary extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + final Resource functionLibrary = ResourceAdaptionUtils.toSingleResource(sel); + if(functionLibrary == null) return null; + + String name = null; + try { + name = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + if (!graph.hasStatement(functionLibrary, Layer0.getInstance(graph).PartOf)) + return null; + Layer0 l0 = Layer0.getInstance(graph); + String name = graph.syncRequest(new PossibleRelatedValue(functionLibrary, l0.HasName, Bindings.STRING )); + return name; + + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + // Do not export if the resource has no name + if(name == null) return null; + + // Find a location (and name) for the exported library using FileDialog + Shell shell = HandlerUtil.getActiveShellChecked(event); + FileDialog fd = new FileDialog(shell, SWT.SAVE); + fd.setText("Export Function Library"); + fd.setFileName(name); + String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTFUNCTIONLIBRARYPATH); + if(path.isEmpty() || !(new File(path).exists())) + path = Platform.getLocation().toOSString(); + fd.setFilterPath(path); + String[] filterExt = {"*.tg"}; + fd.setFilterExtensions(filterExt); + fd.setOverwrite(true); + final String selected = fd.open(); + if(selected == null) return null; + + // Save location to preference store + Activator.getDefault().getPreferenceStore().setValue(ImportUtilsUI.IMPORTFUNCTIONLIBRARYPATH, (new File(selected)).getParent()); + + // Asynchronously create the file using transferable graph + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, functionLibrary); + TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf)); + try { + TransferableGraphs.writeTransferableGraph(graph, "sysdynFunctionLibrary", 1, s,new File(selected)); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelAsButtonHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelAsButtonHandler.java new file mode 100644 index 00000000..57a6cb42 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelAsButtonHandler.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.exports; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.db.Resource; + +/** + * Exports a selected model asking the location. + * Model determination is based on any resource of the model. + * + * @author Tuomas Miettinen + * + */ +public class ExportModelAsButtonHandler extends ExportModelButtonHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + final Resource model = determineModel(event); + if (model == null) + return null; + + String selected = getAbsolutePath(model, event, true); + + if (selected != null) + createFile(model, selected); + + return null; + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelButtonHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelButtonHandler.java new file mode 100644 index 00000000..a9ee8a32 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelButtonHandler.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.exports; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.platform.PropertyPageView; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.db.request.Read; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Exports a selected model without asking the location. + * Model determination is based on any resource of the model. + * + * @author Tuomas Miettinen + * + */ +public class ExportModelButtonHandler extends ExportModelHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + final Resource model = determineModel(event); + if (model == null) + return null; + + String selected = getAbsolutePath(model, event, false); + + if (selected != null) + createFile(model, selected); + + return null; + } + + @Override + protected Resource determineModel(ExecutionEvent event) { + ISelection sel = HandlerUtil.getCurrentSelection(event); + if (sel == null) { + // No selection, this is true e.g. in PropertyPageView + IWorkbenchPart activePart = HandlerUtil.getActivePart(event); + // In such a case get the selection the PropertyPageView point to. + if (activePart instanceof PropertyPageView) + sel = ((PropertyPageView)activePart).getLastSelection(); + } + + // Get the Resource of the selection + Resource inputResource = ResourceAdaptionUtils.toSingleResource(sel); + if (inputResource == null) { + // Coner case for when export is called when some folder in model browser is selected. + if (sel instanceof IStructuredSelection) { + IStructuredSelection iss = (IStructuredSelection) sel; + if (iss.size() == 1) { + Object element = iss.getFirstElement(); + AbstractNode a = AdaptionUtils.adaptToSingle(element, AbstractNode.class); + if (a != null) + inputResource = (Resource)a.data; + } + } + } + + // When the selection doesn't have a resource, use the currently active diagram. + if (inputResource == null) { + IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor(); + DiagramEditor editor = (DiagramEditor)page.getActiveEditor(); + if (editor != null && editor instanceof DiagramEditor) { + inputResource = editor.getInputResource(); + } else { + return null; + } + } + + // Now that we finally have determined which Resource is selected, we just need + // to get the model of that Resource. + Resource model; + final Resource resource = inputResource; + try { + model = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return graph.sync(new PossibleModel(resource)); + } + + }); + if(model == null) return null; + } catch (DatabaseException e1) { + e1.printStackTrace(); + return null; + } + return model; + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java new file mode 100644 index 00000000..ee0efbb9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.exports; + +import java.io.File; +import java.util.HashMap; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.primitiverequest.PossibleRelatedValue; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus; +import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest; +import org.simantics.db.layer0.util.TransferableGraphConfiguration2; +import org.simantics.db.request.Read; +import org.simantics.graph.db.TransferableGraphSource; +import org.simantics.graph.db.TransferableGraphs; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +/** + * Exports a selected model + * Model determination is based on the very Resource of the model. + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ExportModelHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + final Resource model = determineModel(event); + if (model == null) + return null; + + String selected = getAbsolutePath(model, event, true); + + if (selected != null) + createFile(model, selected); + + return null; + } + + /** + * Create the export file. + * @param model Model which is exported. + * @param fileName Full name of the file. + */ + protected void createFile(final Resource model, final String fileName) { + + // Asynchronously create the file using transferable graph + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + HashMap map = new HashMap(); + + Resource relation = graph.getPossibleResource("http://www.simantics.org/Documentation-1.1/createdBy"); + if(relation != null) { + Resource createdBy = graph.getPossibleObject(model, relation); + if(createdBy != null) + map.put(createdBy, ExtentStatus.EXCLUDED); + } + + TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model); + conf.preStatus.putAll(map); + + TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf)); + try { + TransferableGraphs.writeTransferableGraph(graph, "sysdynModel", 1, s,new File(fileName)); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + /** + * Get the model Resource based on the event. + * @param event + * @return model Resource which the event refers to. + */ + protected Resource determineModel(ExecutionEvent event) { + // Just get the selected model. + ISelection sel = HandlerUtil.getCurrentSelection(event); + final Resource model = ResourceAdaptionUtils.toSingleResource(sel); + return model; + } + + /** + * Get the absolute save path for the export file and save it to the database. + * @param model Model Resource which is exported. + * @param event + * @param saveAs true if save as... functionality is used; otherwise save + * functionality is used. + * @return The full path name of the exported model. + * @throws ExecutionException + */ + protected String getAbsolutePath(final Resource model, ExecutionEvent event, boolean saveAs) throws ExecutionException { + + // Determine the default path. + String path = null; + try { + //If the model has been exported earlier, use that path. + path = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + if (!graph.hasStatement(model, Layer0.getInstance(graph).PartOf)) + return null; + SysdynResource SR = SysdynResource.getInstance(graph); + String path = graph.syncRequest(new PossibleRelatedValue(model, SR.SysdynModel_lastExportFilePath, Bindings.STRING )); + return path; + + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + // If this is the initial save: + if (path == null) { + if (saveAs == false) { + // Save == Save as... when there has been no earlier save. + return getAbsolutePath(model, event, true); + } + // Use import default path. + path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODELTPATH); + } + if(path.isEmpty() || !(new File(path).exists())) + path = Platform.getLocation().toOSString(); + + // Determine the default name + // FIXME: Model browser doesn't change its selection even if the selected object is removed, + // so you can try to export a removed model + String name = null; + try { + name = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + if (!graph.hasStatement(model, Layer0.getInstance(graph).PartOf)) + return null; + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + // If the model has been exported earlier, use that name. + // When mere Save has progressed here, there is always be the name in the database. + String name = graph.syncRequest(new PossibleRelatedValue(model, SR.SysdynModel_lastExportFileName, Bindings.STRING )); + if (name == null) { + // If not, use the model name. + name = graph.syncRequest(new PossibleRelatedValue(model, l0.HasName, Bindings.STRING )); + } + return name; + + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + // Do not export if the resource has no name + if(name == null) return null; + + final String selected; + String fullPath = null; + if (saveAs == true) { + // Find a location (and name) for the exported library using FileDialog + Shell shell = HandlerUtil.getActiveShellChecked(event); + FileDialog fd = new FileDialog(shell, SWT.SAVE); + fd.setText("Export Model"); + fd.setFileName(name); + + fd.setFilterPath(path); + String[] filterExt = {"*.tg"}; + fd.setFilterExtensions(filterExt); + fd.setOverwrite(true); + fullPath = fd.open(); + } + else { + // Save to the earlier location. + fullPath = path; + if (path.charAt(path.length() - 1) != '\\') + fullPath += "\\"; // Saving to C:\ would otherwise add excess backslashes. + fullPath += name; + } + selected = fullPath; + + if(selected == null) return null; + + // Save location to preference store + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + graph.deny(model, SR.SysdynModel_lastExportFilePath); + graph.deny(model, SR.SysdynModel_lastExportFileName); + graph.addLiteral(model, SR.SysdynModel_lastExportFilePath, SR.SysdynModel_lastExportFilePath_Inverse, l0.String, new File(selected).getParent(), Bindings.STRING); + graph.addLiteral(model, SR.SysdynModel_lastExportFileName, SR.SysdynModel_lastExportFilePath_Inverse, l0.String, new File(selected).getName(), Bindings.STRING); + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + return selected; + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModuleHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModuleHandler.java new file mode 100644 index 00000000..7d7e7fcf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModuleHandler.java @@ -0,0 +1,276 @@ +/******************************************************************************* + * Copyright (c) 2007, 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.exports; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.primitiverequest.PossibleRelatedValue; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest; +import org.simantics.db.layer0.util.TransferableGraphConfiguration2; +import org.simantics.db.request.Read; +import org.simantics.graph.db.TransferableGraphSource; +import org.simantics.graph.db.TransferableGraphs; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.datastructures.Pair; + +/** + * Exports a selected module + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ExportModuleHandler extends AbstractHandler { + + /** + * Temporary exception. At this phase, the system will not support exporting modules + * that depend on other modules. + * + * @author Teemu Lempinen + * + */ + class ContainsDependenciesException extends DatabaseException { + private static final long serialVersionUID = -1533706136673146020L; + + private final Collection dependencies; + + ContainsDependenciesException(Collection dependencies) { + this.dependencies = dependencies; + } + + public Collection getDependencies() { + return this.dependencies; + } + + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + final Resource modulesymbol = ResourceAdaptionUtils.toSingleResource(sel); + if(modulesymbol == null) return null; + + String name = null; + try { + name = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + ModelingResources mr = ModelingResources.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + // Start checking for module dependencies + Resource component = graph.getPossibleObject(modulesymbol, mr.SymbolToComponentType); + if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf)) + return null; + + Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy); + if (configuration == null) + return null; + + ArrayList dependencies = null; + for(Resource r : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Module))) { + if(dependencies == null) + dependencies = new ArrayList(); + String name = NameUtils.getSafeName(graph, r); + String instanceOf = NameUtils.getSafeName(graph, graph.getSingleObject(r, l0.InstanceOf)); + dependencies.add(name + " : " + instanceOf); + } + if(dependencies != null && !dependencies.isEmpty()) + throw new ContainsDependenciesException(dependencies); + // End checking for module dependencies. If dependencies were found, an exception was thrown + + String name = graph.getPossibleRelatedValue(component, l0.HasName, Bindings.STRING); + return name; + + } + + }); + } catch (ContainsDependenciesException e1) { + Shell shell = HandlerUtil.getActiveShellChecked(event); + MessageBox mb = new MessageBox(shell, SWT.OK); + StringBuilder sb = new StringBuilder(); + sb.append("This version does not support exporting modules with other module instances.\n\n"); + sb.append("Dependencies:\n"); + for(String s : e1.getDependencies()) + sb.append(" " + s + "\n"); + mb.setMessage(sb.toString()); + mb.setText("Module contains dependencies."); + mb.open(); + return null; + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + // Do not export if the resource has no name + if(name == null) return null; + + // Find a location (and name) for the exported library using FileDialog + Shell shell = HandlerUtil.getActiveShellChecked(event); + FileDialog fd = new FileDialog(shell, SWT.SAVE); + fd.setText("Export Module"); + fd.setFileName(name); + String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODULETPATH); + if(path.isEmpty() || !(new File(path).exists())) + path = Platform.getLocation().toOSString(); + fd.setFilterPath(path); + String[] filterExt = {"*.tg"}; + fd.setFilterExtensions(filterExt); + fd.setOverwrite(true); + final String selected = fd.open(); + if(selected == null) return null; + + // Save location to preference store + Activator.getDefault().getPreferenceStore().setValue(ImportUtilsUI.IMPORTMODULETPATH, (new File(selected)).getParent()); + + // Asynchronously create the file using transferable graph + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + + final Resource component = graph.getPossibleObject(modulesymbol, mr.SymbolToComponentType); + if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf)) + return; + String name = graph.syncRequest(new PossibleRelatedValue(component, l0.HasName, Bindings.STRING )); + final ArrayList> roots = new ArrayList>(); + roots.add(Pair.make(component, name)); + + graph.asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + + Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy); + if (!graph.hasStatement(configuration, l0.PartOf, component)&& + !graph.hasStatement(modulesymbol, l0.PartOf, component)) { + // Make sure that configuration and symbol are included. + // In old versions, they were attached to model, not to module. + Resource previousPartof = graph.getSingleObject(configuration, l0.PartOf); + + graph.deny(configuration, l0.PartOf); + graph.deny(modulesymbol, l0.PartOf); + graph.claim(configuration, l0.PartOf, l0.ConsistsOf, component); + graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, component); + + export(graph, selected, roots, component); + + graph.deny(configuration, l0.PartOf); + graph.deny(modulesymbol, l0.PartOf); + graph.claim(configuration, l0.PartOf, l0.ConsistsOf, previousPartof); + graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, previousPartof); + } else { + // Normal export + export(graph, selected, roots, component); + } + } + }); + + } + }); + + return null; + } + + /** + * Export module (without dependencies to other modules) and write it to file. + * Disable existing enumeration replacement for during export. + * + * @param graph WriteGraph + * @param path Path for the exported file + * @param roots + * @param component Module + */ + private void export(WriteGraph graph, final String path, ArrayList> roots, final Resource component) { + + // FIXME: Enumeration replacement handling like this is not suitable. + try { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + + Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy); + ArrayList> replacements = new ArrayList>(); + + for(Resource enumeration : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) { + if(graph.hasStatement(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) { + for(Resource replacement : graph.getObjects(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) { + replacements.add(new Pair(enumeration, replacement)); + } + } + } + + for(Pair replacement : replacements) + graph.deny(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second); + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, component); + TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf)); + try { + TransferableGraphs.writeTransferableGraph(graph, "sysdynModule", 1, s,new File(path)); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + + for(Pair replacement : replacements) + graph.claim(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second); + + } catch (RuntimeBindingConstructionException e) { + e.printStackTrace(); +// } catch (IOException e) { +// e.printStackTrace(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/ReloadGameExperimentHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/ReloadGameExperimentHandler.java new file mode 100644 index 00000000..de0c36ab --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/ReloadGameExperimentHandler.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.game; + +import java.util.Map; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.menus.UIElement; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynGameExperiment; +import org.simantics.sysdyn.ui.handlers.RunBasicExperiment; +import org.simantics.ui.SimanticsUI; + +/** + * Handler for initializing and reloading game experiments. + * + * @author Teemu Lempinen + * + */ +public class ReloadGameExperimentHandler extends RunBasicExperiment { + + private boolean started = false; + private boolean initialized = false; + + + public static final String COMMAND = "org.simantics.sysdyn.ui.reloadGame"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + SysdynGameExperiment game = getGameExperiment(); + if(game != null) + game.simulate(true); + return null; + } + + /** + * Find currently active game experiment + * @return Currently active game experiment or null if game experiment not active + */ + private SysdynGameExperiment getGameExperiment() { + // Find active experiment + IProject project = SimanticsUI.peekProject(); + if (project == null) + return null; + + IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + + IExperiment active = manager.getActiveExperiment(); + if (!(active instanceof SysdynGameExperiment)) + return null; + + return (SysdynGameExperiment) active; + } + + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + // Disable button while initializign a model + super.updateElement(element, parameters); + + + // Change tooltip according to the current status + SysdynGameExperiment game = getGameExperiment(); + + if(game == null) { + started = false; + initialized = false; + return; + } + + ExperimentState state = game.getState(); + + if(state==ExperimentState.INITIALIZING) { + started = false; + initialized = false; + } else if(state==ExperimentState.RUNNING) { + started = true; + initialized = false; + } else if(state==ExperimentState.STOPPED) { + if(started && !initialized) { + initialized = true; + } + } + + + if(initialized) { + element.setTooltip("Reload Game"); + } else { + element.setTooltip("Initialize Game"); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/StepHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/StepHandler.java new file mode 100644 index 00000000..6164c97a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/StepHandler.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.game; + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynGameExperiment; +import org.simantics.sysdyn.ui.utils.HandlerUtils; +import org.simantics.ui.SimanticsUI; + +/** + * Handler for stepping game simulations + * @author Teemu Lempinen + * + */ +public class StepHandler extends AbstractHandler implements IElementUpdater { + + public static String COMMAND = "org.simantics.sysdyn.ui.step"; + + private boolean started = false; + private boolean initialized = false; + private boolean running = false; + + private SysdynGameExperiment getGameExperiment() { + // Find active experiment + IProject project = SimanticsUI.peekProject(); + if (project == null) + return null; + + IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + + IExperiment active = manager.getActiveExperiment(); + if (!(active instanceof SysdynGameExperiment)) + return null; + + return (SysdynGameExperiment) active; + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + HandlerUtils.saveBeforeExperimentRun(event); + + SysdynGameExperiment game = getGameExperiment(); + if(game != null) + game.simulateDuration(game.getStepDuration()); + return null; + } + + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + + // Disable button when model has not been initialized and change tooltip accordingly + SysdynGameExperiment game = getGameExperiment(); + + if(game == null) { + started = false; + initialized = false; + return; + } + + ExperimentState state = game.getState(); + + if(state==ExperimentState.INITIALIZING) { + started = false; + initialized = false; + running = false; + } else if(state==ExperimentState.RUNNING) { + started = true; + initialized = initialized == true ? true : false; + running = true; + } else if(state==ExperimentState.STOPPED) { + if(started && !initialized) { + initialized = true; + } + running = false; + } + + if(initialized) { + if(!running) + this.setBaseEnabled(true); + else + this.setBaseEnabled(false); + element.setTooltip("Step"); + } else { + this.setBaseEnabled(false); + element.setTooltip("Initialize Game First"); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportExternalFunctionFilesHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportExternalFunctionFilesHandler.java new file mode 100644 index 00000000..50277c1c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportExternalFunctionFilesHandler.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.imports; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; + +/** + * Imports external functions to SysdynModelicaFunctions using FileDialog. + * + * @author Teemu Lempinen + * + */ +public class ImportExternalFunctionFilesHandler extends AbstractHandler { + + public static final String[] C_EXTENSIONS = {"*.c","*.h","*.a","*.o"}; + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShellChecked(event); + Pair selected = importFiles(shell, "Import...", C_EXTENSIONS); + if(selected.second == null || selected.second.length < 1) return null; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + // TODO: include files to database + } + }); + + return null; + } + + /** + * Opens a {@link FileDialog} to select the imported files. + * + * @param shell SWT Shell + * @param text Header text for the FileDialog + * @param filter Filters for the FileDialog + * @return File names and paths for the files to be imported + */ + public static Pair importFiles(Shell shell, String text, String[] filter) { + FileDialog fd = new FileDialog(shell, SWT.OPEN); + fd.setText(text); + fd.setFilterPath(Platform.getLocation().toOSString()); + fd.setFilterExtensions(filter); + fd.open(); + return new Pair(fd.getFilterPath(), fd.getFileNames()); + } + + + /** + * Saves the given files as byte arrays to a function + * + * @param graph WriteGraph + * @param function Function where the files are to be added + * @param files Files to be added + * @throws DatabaseException + */ + public static void addFilesToFunction(WriteGraph graph, Resource function, Pair files) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + if(!graph.isInstanceOf(function, sr.SysdynModelicaFunction)) + return; + + for(String filename : files.second) { + File file = new File(files.first, filename); + + String name = file.getName(); + + Resource externalFile = GraphUtils.create2(graph, + sr.ExternalFunctionFile, + l0.PartOf, function, + l0.HasName, name); + + try { + byte[] fileBArray = new byte[(int)file.length()]; + FileInputStream fis = new FileInputStream(file); + fis.read(fileBArray); + graph.claimLiteral(externalFile, sr.ExternalFunctionFile_externalFile, fileBArray, Bindings.BYTE_ARRAY); + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportFunctionLibrary.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportFunctionLibrary.java new file mode 100644 index 00000000..cdd40a04 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportFunctionLibrary.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.imports; + +import java.io.File; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.DatabaseJob; +import org.simantics.db.Resource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder; +import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Imports an exported function library (or shared function library) transferable graph. + * @author Teemu Lempinen + * + */ +public class ImportFunctionLibrary extends AbstractHandler { + + /** + * Called from a functions folder node + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection sel = HandlerUtil.getCurrentSelection(event); + Resource r = ResourceAdaptionUtils.toSingleResource(sel); + if(r == null) { + FunctionsFolder mn = AdaptionUtils.adaptToSingle(sel, FunctionsFolder.class); + r = mn.data; + } + if(r == null) return null; + + final Resource functionLibrary = r; + + + // Get a transferable graph file + Shell shell = HandlerUtil.getActiveShellChecked(event); + FileDialog fd = new FileDialog(shell, SWT.OPEN); + fd.setText("Import Function Library"); + + String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTFUNCTIONLIBRARYPATH); + if(path.isEmpty() || !(new File(path).exists())) + path = Platform.getLocation().toOSString(); + fd.setFilterPath(path); + String[] filterExt = {"*.tg"}; + fd.setFilterExtensions(filterExt); + final String selected = fd.open(); + if(selected == null) return null; + + Job job = new DatabaseJob("Import function") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + IStatus status = ImportUtilsUI.importFunctionLibrary(functionLibrary, selected, monitor); + return status; + } + }; + + job.setUser(true); + job.schedule(); + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java new file mode 100644 index 00000000..2ce39ec6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.imports; + +import java.io.File; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.mdlImport.MdlParser; +import org.simantics.sysdyn.mdlImport.mdlElements.Model; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.ui.SimanticsUI; + +/** + * Class for importing Vensim models (.mdl) to Simantics SysDyn using MdlParser + * + * @author Teemu Lempinen + * + */ +public class ImportMdlHandler extends AbstractHandler { + + public static String IMPORTMDLTPATH = "IMPORT_MDL_PATH"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + final Resource project = SimanticsUI.getProject().get(); + if(project == null) return null; + + // Get the .mdl file + Shell shell = HandlerUtil.getActiveShellChecked(event); + FileDialog fd = new FileDialog(shell, SWT.OPEN); + fd.setText("Import .mdl"); + String path = Activator.getDefault().getPreferenceStore().getString(IMPORTMDLTPATH); + if(path.isEmpty() || !(new File(path).exists())) + path = Platform.getLocation().toOSString(); + fd.setFilterPath(path); + String[] filterExt = {"*.mdl"}; + fd.setFilterExtensions(filterExt); + String selected = fd.open(); + if(selected == null) return null; + + File file = new File(selected); + if(!file.isFile()) return null; + + Activator.getDefault().getPreferenceStore().setValue(IMPORTMDLTPATH, (new File(selected)).getParent()); + + // Convert Vensim model to Simantics SysDyn format using MdlParser + final Model model = MdlParser.parse(file); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + model.write(graph, project); + } + }); + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java new file mode 100644 index 00000000..daba04a4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.imports; + +import java.io.File; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.DatabaseJob; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; + +/** + * Imports models from exported transferable graph files. + * + * @author Teemu Lempinen + * + */ +public class ImportModelHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + // Get imported transferable graph file using FileDialog + Shell shell = HandlerUtil.getActiveShellChecked(event); + FileDialog fd = new FileDialog(shell, SWT.OPEN); + fd.setText("Import Model"); + + String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODELTPATH); + if(path.isEmpty() || !(new File(path).exists())) + path = Platform.getLocation().toOSString(); + fd.setFilterPath(path); + String[] filterExt = {"*.tg"}; + fd.setFilterExtensions(filterExt); + final String selected = fd.open(); + if(selected == null) return null; + + Job job = new DatabaseJob("Import model") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + IStatus status = ImportUtilsUI.importModelFile(selected, monitor); + return status; + } + }; + job.setUser(true); + job.schedule(); + + return null; + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModuleHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModuleHandler.java new file mode 100644 index 00000000..e4645106 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModuleHandler.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.imports; + +import java.io.File; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.DatabaseJob; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Imports modules from exported transferable graph files. + * + * @author Teemu Lempinen + * + */ +public class ImportModuleHandler extends AbstractHandler { + + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection sel = HandlerUtil.getCurrentSelection(event); + + @SuppressWarnings("unchecked") + AbstractNode node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class); + if (node == null) + return null; + + final Resource model = node.data; + + // Get imported transferable graph file using FileDialog + Shell shell = HandlerUtil.getActiveShellChecked(event); + FileDialog fd = new FileDialog(shell, SWT.OPEN); + fd.setText("Import Module"); + + String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODULETPATH); + if(path.isEmpty() || !(new File(path).exists())) + path = Platform.getLocation().toOSString(); + fd.setFilterPath(path); + String[] filterExt = {"*.tg"}; + fd.setFilterExtensions(filterExt); + final String selected = fd.open(); + if(selected == null) return null; + + Job job = new DatabaseJob("Import model") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + IStatus status = ImportUtilsUI.importModuleFile(model, selected, monitor); + return status; + } + }; + job.setUser(true); + job.schedule(); + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewBarChartHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewBarChartHandler.java new file mode 100644 index 00000000..88aa7eb7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewBarChartHandler.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.util.Collections; +import java.util.UUID; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Handler for creating a new Bar Chart + * @author Teemu Lempinen + * + */ +public class NewBarChartHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class); + if (node == null) + return null; + + final Resource model = node.data; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + JFreeChartResource jfree = JFreeChartResource.getInstance(g); + G2DResource g2d = G2DResource.getInstance(g); + + Resource jfreechart = GraphUtils.create2(g, jfree.Chart, + l0.HasName, "BarChart" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(g, "Bar Chart", model), + l0.PartOf, model, + jfree.Chart_visibleBorder, true, + jfree.Chart_borderWidth, 3, + jfree.Chart_visibleLegend, false + ); + + g.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1}); + + GraphUtils.create2(g, jfree.TextTitle, + l0.HasName, "TextTitle" + UUID.randomUUID().toString(), + l0.HasLabel, "Bar Chart Title", + jfree.Title_position, jfree.Top, + l0.PartOf, jfreechart); + + Resource domainAxis = GraphUtils.create2(g, jfree.CategoryAxis, + l0.HasName, "CategoryAxis" + UUID.randomUUID().toString()); + + Resource rangeAxis = GraphUtils.create2(g, jfree.NumberAxis, + l0.HasName, "NumberAxis" + UUID.randomUUID().toString()); + + Resource renderer = GraphUtils.create2(g, jfree.BarRenderer); + + Resource dataset = GraphUtils.create2(g, jfree.CategoryDataset, + l0.HasName, "CategoryDataset" + UUID.randomUUID().toString(), + jfree.Dataset_mapToDomainAxis, domainAxis, + jfree.Dataset_mapToRangeAxis, rangeAxis, + jfree.Dataset_seriesList, ListUtils.create(g, Collections.emptyList()), + jfree.Dataset_renderer, renderer); + + GraphUtils.create2(g, jfree.CategoryPlot, + l0.HasName, "Category plot" + UUID.randomUUID().toString(), + l0.PartOf, jfreechart, + jfree.Plot_domainAxis, domainAxis, + jfree.Plot_rangeAxis, rangeAxis, + jfree.Plot_rangeAxisList, ListUtils.create(g, Collections.singletonList(rangeAxis)), + l0.ConsistsOf, dataset, + l0.ConsistsOf, domainAxis, + l0.ConsistsOf, rangeAxis); + } + + }); + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewEnumerationNodeHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewEnumerationNodeHandler.java new file mode 100644 index 00000000..6801225c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewEnumerationNodeHandler.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.util.ArrayList; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Creates a new Enumeration node to a configuration or module + * + * @author Teemu Lempinen + * + */ +public class NewEnumerationNodeHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + final Resource resource = AdaptionUtils.adaptToSingle(sel, Resource.class); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + + // Find the actual configuration. Possible cases for resource are sr.Configuration, sr.ModuleSymbol or sr.Module. + Resource configuration = null; + if(g.isInstanceOf(resource, sr.Configuration)) { + configuration = resource; + } else if(g.isInheritedFrom(resource, sr.ModuleSymbol)) { + Resource module = g.getPossibleObject(resource,ModelingResources.getInstance(g).SymbolToComponentType); + configuration = g.getPossibleObject(module, StructuralResource2.getInstance(g).IsDefinedBy); + } else { + Resource instanceOf = g.getSingleObject(resource, l0.InstanceOf); + if(g.isInheritedFrom(instanceOf, sr.Module)) { + configuration = g.getPossibleObject(instanceOf, StructuralResource2.getInstance(g).IsDefinedBy); + } else { + return; + } + } + + // Create the enumeartion + + String name = NameUtils.findFreshName(g, "Enum", configuration, l0.ConsistsOf, "%s%d"); + + GraphUtils.create2(g, + sr.Enumeration, + l0.HasName, name, + sr.Enumeration_enumerationIndexList, ListUtils.create(g, new ArrayList()), + l0.PartOf, configuration); + } + }); + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewExperimentNodeHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewExperimentNodeHandler.java new file mode 100644 index 00000000..0ddf1a3b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewExperimentNodeHandler.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.util.UUID; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Creates a new normal SysDyn experiment + * + * @author Teemu Lempinen + * + */ +public class NewExperimentNodeHandler extends AbstractHandler { + + /** + * Assumes that it is called from a node that has a SysDyn model as its resource. + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection sel = HandlerUtil.getCurrentSelection(event); + + ExperimentsFolder node = AdaptionUtils.adaptToSingle(sel, ExperimentsFolder.class); + if (node == null) + return null; + + final Resource model = node.data; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + String label = NameUtils.findFreshName(g, getNameSuggestion(), model, l0.ConsistsOf, l0.HasLabel, "%s%d"); + Resource experiment = GraphUtils.create2(g, getExperimentType(g), + l0.HasName, UUID.randomUUID().toString(), + l0.HasLabel, label, + l0.PartOf, model); + configureExperiment(g, experiment); + } + }); + return null; + } + + /** + * Override to do experiment-specific alterations + */ + protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException { + + } + + /** + * Get the type of this experiment. + * + * @param g ReadGraph + * @return The type resource of this experiment + */ + protected Resource getExperimentType(ReadGraph g) { + return SysdynResource.getInstance(g).BasicExperiment; + } + + /** + * Returns the suggested name for this experiment. + * If the name has already been taken, appropriate prefix needs to be added. + * + * @return Suggested name for this experiment. + */ + protected String getNameSuggestion() { + return "Experiment"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionHandler.java new file mode 100644 index 00000000..7acab21e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionHandler.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Creates a new function to a SysdynModel or Library. + * + * @author Teemu Lempinen + * + */ +public class NewFunctionHandler extends AbstractHandler { + + /** + * Assumes to be called from a node with SysdynModel, Library or SysdynModelicaFunction as its resource + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + @SuppressWarnings("unchecked") + AbstractNode node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class); + if (node == null) + return null; + + final Resource data = node.data; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + SysdynResource sr = SysdynResource.getInstance(g); + + // Library can be either SysdynModel or L0.Library. + Resource library = null; + if(g.isInstanceOf(data, sr.SysdynModel) || g.isInstanceOf(data, l0.Library)) + library = data; + else if (g.isInstanceOf(data, sr.SysdynModelicaFunction)) + library = g.getPossibleObject(data, l0.PartOf); + + if(library == null) + return; + + + String name = NameUtils.findFreshName(g, "Function", library, l0.ConsistsOf, "%s%d"); + + GraphUtils.create2(g, sr.SysdynModelicaFunction, + l0.HasName, name, + l0.HasDescription, "", + sr.SysdynModelicaFunction_modelicaFunctionCode, "", + l0.PartOf, library); + } + }); + + return null; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionLibraryHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionLibraryHandler.java new file mode 100644 index 00000000..bf62f3ef --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionLibraryHandler.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Creates a new function library to a model or other library. + * + * @author Teemu Lempinen + * + */ +public class NewFunctionLibraryHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + @SuppressWarnings("unchecked") + AbstractNode node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class); + if (node == null) + return null; + + createLibrary(node.data, false); + return null; + } + + /** + * Create function library. Shared libraries are created to root, local libraries to the model. + * Shared libraries can be used in other models in the project. + * + * @param model The initial location of the command + * @param shared Shared libraries are created to root, local libraries to the model. + */ + protected void createLibrary(final Resource model, final boolean shared) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + SysdynResource sr = SysdynResource.getInstance(g); + + if(!(g.isInstanceOf(model, sr.SysdynModel) || + g.isInstanceOf(model, sr.SysdynModelicaFunctionLibrary) || + g.isInstanceOf(model, sr.SharedFunctionOntology))) + return; + + Resource root = model; + + String name = "FunctionLibrary"; + Resource libraryType = sr.SysdynModelicaFunctionLibrary; + + if(shared) { + + try { + root = g.getResource("http://SharedOntologies"); + } catch (ResourceNotFoundException e) { + root = g.getResource("http:/"); + root = GraphUtils.create2(g, l0.Library, + l0.HasName, "SharedOntologies", + l0.PartOf, root); + } + + name = "Shared" + name; + libraryType = sr.SharedFunctionOntology; + } + + name = NameUtils.findFreshName(g, name, root, l0.ConsistsOf, "%s%d"); + + Resource functionLibrary = GraphUtils.create2(g, libraryType, + l0.HasName, name, + l0.HasDescription, "", + l0.PartOf, root); + + if(shared) + g.claim(model, l0.IsLinkedTo, functionLibrary); + } + }); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewGameExperimentNodeHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewGameExperimentNodeHandler.java new file mode 100644 index 00000000..7d759c34 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewGameExperimentNodeHandler.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynGameExperiment; + +/** + * Handler for creating a new Game Experiment + * @author Teemu Lempinen + * + */ +public class NewGameExperimentNodeHandler extends NewExperimentNodeHandler { + + protected Resource getExperimentType(ReadGraph g) { + return SysdynResource.getInstance(g).GameExperiment; + } + + /** + * Override to do experiment-specific alterations + */ + protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + graph.claimLiteral(experiment, sr.GameExperiment_stepDuration, SysdynGameExperiment.DEFAULT_STEP_DURATION); + graph.claimLiteral(experiment, sr.GameExperiment_stepLength, SysdynGameExperiment.DEFAULT_STEP_LENGTH); + } + + protected String getNameSuggestion() { + return "Game Experiment"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewHistoryDataHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewHistoryDataHandler.java new file mode 100644 index 00000000..d97b6845 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewHistoryDataHandler.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.util.UUID; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Handler for creating new history dataset + * @author Teemu Lempinen + * + */ +public class NewHistoryDataHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + final Resource experiment = AdaptionUtils.adaptToSingle(sel, Resource.class); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + if(!g.isInstanceOf(experiment, sr.Experiment)) + return; // Not called from an experiment + + Resource model = g.getPossibleObject(experiment, l0.PartOf); + // Create the history dataset + GraphUtils.create2(g, + sr.HistoryDataset, + l0.HasName, "HistoryDataset" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(g, "History Dataset", experiment), + sr.Experiment_result_Inverse, experiment, + sr.HistoryDataset_columns, Boolean.TRUE, + l0.PartOf, model); + } + }); + return null; + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModelHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModelHandler.java new file mode 100644 index 00000000..6ed6858e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModelHandler.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.simantics.DatabaseJob; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.utils.ModelUtils; +import org.simantics.ui.SimanticsUI; + +/** + * Creates a new SysDyn model. + * + * @author Teemu Lempinen + * + */ +public class NewModelHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + + Job job = new DatabaseJob("Creating System Dynamics Model") { + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + // Use ModelUtils to keep all model creations up-to-date + ModelUtils.createModel(graph); + } + }); + return Status.OK_STATUS; + } catch (DatabaseException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, getName() + " failed.", e); + } + } + }; +// job.setUser(true); + job.schedule(); + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModuleNodeHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModuleNodeHandler.java new file mode 100644 index 00000000..60170f7e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModuleNodeHandler.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.Template; +import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.operation.Layer0X; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.actions.newActions.NewModuleTypeAction; +import org.simantics.sysdyn.ui.browser.nodes.ModulesNode; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.datastructures.ArrayMap; + +/** + * Creates a new module node for a model. + * + * @author Teemu Lempinen + * + */ +public class NewModuleNodeHandler extends AbstractHandler { + + /** + * Assumes to be called from a node that has a SysDyn model as its resource. + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + ModulesNode node = AdaptionUtils.adaptToSingle(sel, ModulesNode.class); + if (node == null) + return null; + + final Resource model = node.data; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + Layer0X L0X = Layer0X.getInstance(g); + ModelingResources mr = ModelingResources.getInstance(g); + StructuralResource2 sr2 = StructuralResource2.getInstance(g); + + String name = NameUtils.findFreshName(g, "ModuleType", model, l0.ConsistsOf, "%s%d"); + + Resource moduleType = g.newResource(); + g.claimLiteral(moduleType, l0.HasName, name); + g.claim(moduleType, l0.Inherits, sr.Module); + g.claim(moduleType, l0.PartOf, model); + + + + Resource configuration = GraphUtils.create2(g, + sr.Configuration, + l0.HasName, name + "Configuration", + l0.PartOf, moduleType); + + g.claim(moduleType, sr2.IsDefinedBy , configuration); + + Resource diagram = g.newResource(); + g.adapt(sr.ConfigurationDiagramTemplate, Template.class).apply(g, + ArrayMap + .keys("", "diagram", "name") + .values(configuration, diagram, "Diagrammi") + ); + + + // Remove default mapping and add sysdyn mapping + for(Resource trigger : g.getObjects(diagram, L0X.HasTrigger)) { + if(g.isInstanceOf(trigger, mr.DiagramToCompositeMapping)) { + g.deny(diagram, L0X.HasTrigger, trigger); + } + } + + Resource mapping = g.newResource(); + g.claim(mapping, l0.InstanceOf, null, sr.DiagramToCompositeMapping); + g.claim(diagram, L0X.HasTrigger, mapping); + + Resource moduleSymbol = g.newResource(); + g.claimLiteral(moduleSymbol, l0.HasName, name + " Symbol"); + g.claimLiteral(moduleSymbol, l0.HasLabel, name + " Symbol"); + g.claim(moduleSymbol, l0.Inherits, sr.ModuleSymbol); + g.claim(moduleSymbol, mr.SymbolToComponentType, moduleType); + g.claim(moduleSymbol, l0.PartOf, moduleType); + + Resource terminal = g.newResource(); + g.claim(terminal, l0.InstanceOf, sr.SysdynTerminal); + Resource relation = NewModuleTypeAction.createTerminalRelation(g, moduleSymbol, sr.IsHeadOfTerminal, sr.Variable_isHeadOf); + DiagramGraphUtil.addConnectionPoint(g, moduleSymbol, terminal, relation); + + Resource terminal2 = g.newResource(); + g.claim(terminal2, l0.InstanceOf, sr.SysdynTerminal); + relation = NewModuleTypeAction.createTerminalRelation(g, moduleSymbol, sr.IsTailOfTerminal, sr.Variable_isTailOf); + DiagramGraphUtil.addConnectionPoint(g, moduleSymbol, terminal2, relation); + + g.claim(moduleSymbol, sr2.IsDefinedBy, OrderedSetUtils.create(g, sr2.Composite, terminal, terminal2)); + + + } + }); + return null; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPieChartHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPieChartHandler.java new file mode 100644 index 00000000..3f17f995 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPieChartHandler.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.util.Collections; +import java.util.UUID; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Handler for craeting a new Pie Chart + * @author Teemu Lempinen + * + */ +public class NewPieChartHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class); + if (node == null) + return null; + + final Resource model = node.data; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + JFreeChartResource jfree = JFreeChartResource.getInstance(g); + G2DResource g2d = G2DResource.getInstance(g); + + Resource jfreechart = GraphUtils.create2(g, jfree.Chart, + l0.HasName, "PieChart" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(g, "Pie Chart", model), + l0.PartOf, model, + jfree.Chart_visibleBorder, true, + jfree.Chart_borderWidth, 3); + g.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1}); + + GraphUtils.create2(g, jfree.TextTitle, + l0.HasName, "TextTitle" + UUID.randomUUID().toString(), + l0.HasLabel, "Pie Chart Title", + jfree.Title_position, jfree.Top, + l0.PartOf, jfreechart); + + Resource dataset = GraphUtils.create2(g, jfree.PieDataset, + l0.HasName, "CategoryDataset" + UUID.randomUUID().toString(), + jfree.Dataset_seriesList, ListUtils.create(g, Collections.emptyList()) + ); + + GraphUtils.create2(g, jfree.PiePlot, + l0.HasName, "PiePlot" + UUID.randomUUID().toString(), + l0.PartOf, jfreechart, + l0.ConsistsOf, dataset + ); + } + + }); + + return null; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPlaybackExperimentNodeHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPlaybackExperimentNodeHandler.java new file mode 100644 index 00000000..a54ce36f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPlaybackExperimentNodeHandler.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.awt.Color; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; + +/** + * Creates a new playback experiment. + * + * @author Teemu Lempinen + * + */ +public class NewPlaybackExperimentNodeHandler extends NewExperimentNodeHandler { + + protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException { + G2DResource g2d = G2DResource.getInstance(graph); + Resource defaultGradient = GraphUtils.create2(graph, g2d.ColorGradient); + graph.claim(experiment, g2d.HasColorGradient, defaultGradient); + + Resource placement = GraphUtils.create2(graph, g2d.ColorPlacement, + g2d.HasGradientPosition, 0.0); + graph.claimLiteral(placement, g2d.HasColor, g2d.Color, new Color(0, 62, 133).getColorComponents(new float[4])); + graph.claim(defaultGradient, g2d.HasColorPlacement, placement); + + placement = GraphUtils.create2(graph, g2d.ColorPlacement, + g2d.HasGradientPosition, 1.0); + graph.claimLiteral(placement, g2d.HasColor, g2d.Color, new Color(255, 230, 0).getColorComponents(new float[4])); + graph.claim(defaultGradient, g2d.HasColorPlacement, placement); + } + + protected Resource getExperimentType(ReadGraph g) { + return SysdynResource.getInstance(g).PlaybackExperiment; + } + + protected String getNameSuggestion() { + return "Playback Experiment"; + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityAnalysisExperimentNodeHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityAnalysisExperimentNodeHandler.java new file mode 100644 index 00000000..1a8ae7a9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityAnalysisExperimentNodeHandler.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.util.ArrayList; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; + +/** + * Creates a new sensitivity analysis experiment. + * + * @author Tuomas Miettinen + * + */ +public class NewSensitivityAnalysisExperimentNodeHandler extends NewExperimentNodeHandler { + + @Override + protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + + Resource method = GraphUtils.create2(graph, sr.RandomGenerator); + graph.claim(experiment, sr.SensitivityAnalysisExperiment_method, method); + + Resource distribution = GraphUtils.create2(graph, sr.UniformDistribution, + sr.UniformDistribution_minValue, 0.0, + sr.UniformDistribution_maxValue, 10.0); + + Resource parameter = GraphUtils.create2(graph, sr.SensitivityAnalysisExperiment_Parameter, + sr.SensitivityAnalysisExperiment_Parameter_propabilityDistribution, distribution, + sr.SensitivityAnalysisExperiment_Parameter_variable, ChartUtils.emptyVariableName, + L0.PartOf, experiment); + + ArrayList parameterList = new ArrayList(); + parameterList.add(parameter); + + graph.claim(experiment, sr.SensitivityAnalysisExperiment_parameterList, ListUtils.create(graph, parameterList)); + } + + @Override + protected Resource getExperimentType(ReadGraph g) { + return SysdynResource.getInstance(g).SensitivityAnalysisExperiment; + } + + @Override + protected String getNameSuggestion() { + return "Sensitivity Experiment"; + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityChartHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityChartHandler.java new file mode 100644 index 00000000..013c5602 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityChartHandler.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Collections; +import java.util.UUID; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +public class NewSensitivityChartHandler extends AbstractHandler { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class); + if (node == null) + return null; + + final Resource model = node.data; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + JFreeChartResource jfree = JFreeChartResource.getInstance(g); + G2DResource g2d = G2DResource.getInstance(g); + SysdynResource SR = SysdynResource.getInstance(g); + + Resource jfreechart = GraphUtils.create2(g, jfree.Chart, + l0.HasName, "SensitivityChart" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(g, "SensitivityChart", model), + l0.PartOf, model, + jfree.Chart_visibleBorder, true, + jfree.Chart_borderWidth, 3); + g.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1}); + + GraphUtils.create2(g, jfree.TextTitle, + l0.HasName, "TextTitle" + UUID.randomUUID().toString(), + l0.HasLabel, "Chart Title", + jfree.Title_position, jfree.Top, + l0.PartOf, jfreechart); + + Resource domainAxis = GraphUtils.create2(g, jfree.NumberAxis, + l0.HasName, "NumberAxis" + UUID.randomUUID().toString(), + jfree.variableRVI, "/time", + l0.HasLabel, "Time"); + Resource rangeAxis = GraphUtils.create2(g, jfree.NumberAxis, + l0.HasName, "NumberAxis" + UUID.randomUUID().toString(), + l0.HasLabel, ""); + + Resource renderer = GraphUtils.create2(g, jfree.DeviationRenderer); + + Color[] colors = { + new Color(255, 255, 64), + new Color(0, 255, 0), + new Color(0, 0, 255), + new Color(128, 128, 128), + new Color(192, 192, 192) + }; + + float[] colorContainer = new float[] {0, 0, 0, 1}; + + ArrayList confidenceBounds = new ArrayList(); + confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound, + SR.Charts_SensitivityDataset_ConfidenceBound_percent, 25.0 + )); + g.claimLiteral(confidenceBounds.get(0), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[0].getColorComponents(colorContainer)); + + + confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound, + SR.Charts_SensitivityDataset_ConfidenceBound_percent, 50.0 + )); + g.claimLiteral(confidenceBounds.get(1), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[1].getColorComponents(colorContainer)); + + confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound, + SR.Charts_SensitivityDataset_ConfidenceBound_percent, 75.0 + )); + g.claimLiteral(confidenceBounds.get(2), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[2].getColorComponents(colorContainer)); + + confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound, + SR.Charts_SensitivityDataset_ConfidenceBound_percent, 100.0 + )); + g.claimLiteral(confidenceBounds.get(3), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[3].getColorComponents(colorContainer)); + + confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound + )); + g.claimLiteral(confidenceBounds.get(4), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[4].getColorComponents(colorContainer)); + + + Resource dataset = GraphUtils.create2(g, SR.Charts_SensitivityDataset, + l0.HasName, "SensitivityDataset" + UUID.randomUUID().toString(), + jfree.Dataset_mapToDomainAxis, domainAxis, + jfree.Dataset_mapToRangeAxis, rangeAxis, + jfree.Dataset_seriesList, ListUtils.create(g, new ArrayList()), + jfree.Dataset_renderer, renderer, + SR.Charts_SensitivityDataset_confidenceBounds, ListUtils.create(g, confidenceBounds) + ); + + ChartUtils.createSeries(g, dataset, null); + + + + + GraphUtils.create2(g, SR.Charts_SensitivityPlot, + l0.HasName, "SensitivityPlot" + UUID.randomUUID().toString(), + l0.PartOf, jfreechart, + jfree.Plot_domainAxis, domainAxis, + jfree.Plot_rangeAxis, rangeAxis, + jfree.Plot_rangeAxisList, ListUtils.create(g, Collections.singletonList(rangeAxis)), + l0.ConsistsOf, dataset, + l0.ConsistsOf, domainAxis, + l0.ConsistsOf, rangeAxis); + } + + }); + + + + return null; + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSharedFunctionLibraryHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSharedFunctionLibraryHandler.java new file mode 100644 index 00000000..ab79d1f8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSharedFunctionLibraryHandler.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Creates a new shared function library. + * + * @author Teemu Lempinen + * + */ +public class NewSharedFunctionLibraryHandler extends NewFunctionLibraryHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + @SuppressWarnings("unchecked") + AbstractNode node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class); + if (node == null) + return null; + + createLibrary(node.data, true); + return null; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSpreadSheetHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSpreadSheetHandler.java new file mode 100644 index 00000000..3a64607a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSpreadSheetHandler.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.utils.SheetUtils; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +/** + * Creates a new spreadsheet sheet to a book. + * @author Teemu Lempinen + * + */ +public class NewSpreadSheetHandler extends AbstractHandler { + + /** + * Called from a node that has a book as its resource. + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection sel = HandlerUtil.getCurrentSelection(event); + final Resource book = ResourceAdaptionUtils.toSingleResource(sel); + if(book == null) return null; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SheetUtils.createSheet(graph, book, null, new String[] {}, new int[] {50}); + } + }); + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewXYLineChartHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewXYLineChartHandler.java new file mode 100644 index 00000000..2f06ce81 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewXYLineChartHandler.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.newComponents; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.UUID; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Handler for creating a new XYLineChart in model browser + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class NewXYLineChartHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + + ISelection sel = HandlerUtil.getCurrentSelection(event); + + ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class); + if (node == null) + return null; + + final Resource model = node.data; + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + JFreeChartResource jfree = JFreeChartResource.getInstance(g); + G2DResource g2d = G2DResource.getInstance(g); + + Resource jfreechart = GraphUtils.create2(g, jfree.Chart, + l0.HasName, "Chart" + UUID.randomUUID().toString(), + l0.HasLabel, NameUtils.findFreshLabel(g, "Chart", model), + l0.PartOf, model, + jfree.Chart_visibleBorder, true, + jfree.Chart_borderWidth, 3); + g.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1}); + + GraphUtils.create2(g, jfree.TextTitle, + l0.HasName, "TextTitle" + UUID.randomUUID().toString(), + l0.HasLabel, "Chart Title", + jfree.Title_position, jfree.Top, + l0.PartOf, jfreechart); + + Resource domainAxis = GraphUtils.create2(g, jfree.NumberAxis, + l0.HasName, "NumberAxis" + UUID.randomUUID().toString(), + jfree.variableRVI, "/time", + l0.HasLabel, "Time"); + Resource rangeAxis = GraphUtils.create2(g, jfree.NumberAxis, + l0.HasName, "NumberAxis" + UUID.randomUUID().toString(), + l0.HasLabel, "Y-axis"); + + Resource renderer = GraphUtils.create2(g, jfree.XYLineRenderer); + + Resource dataset = GraphUtils.create2(g, jfree.XYDataset, + l0.HasName, "XYDataset" + UUID.randomUUID().toString(), + jfree.Dataset_mapToDomainAxis, domainAxis, + jfree.Dataset_mapToRangeAxis, rangeAxis, + jfree.Dataset_seriesList, ListUtils.create(g, new ArrayList()), + jfree.Dataset_renderer, renderer); + + GraphUtils.create2(g, jfree.XYPlot, + l0.HasName, "XYPlot" + UUID.randomUUID().toString(), + l0.PartOf, jfreechart, + jfree.Plot_domainAxis, domainAxis, + jfree.Plot_rangeAxis, rangeAxis, + jfree.Plot_rangeAxisList, ListUtils.create(g, Collections.singletonList(rangeAxis)), + l0.ConsistsOf, dataset, + l0.ConsistsOf, domainAxis, + l0.ConsistsOf, rangeAxis); + } + + }); + + + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/RunSensitivityAnalysisExperiment.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/RunSensitivityAnalysisExperiment.java new file mode 100644 index 00000000..a6602763 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/RunSensitivityAnalysisExperiment.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.sensitivityAnalysis; + + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IDynamicExperiment; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynExperiment; +import org.simantics.sysdyn.ui.utils.HandlerUtils; +import org.simantics.ui.SimanticsUI; + +/** + * Handler for starting a sensitivity analysis simulation + * @author Tuomas Miettinen + * + */ +public class RunSensitivityAnalysisExperiment extends AbstractHandler implements IElementUpdater { + + public static final String COMMAND = "org.simantics.sysdyn.ui.runSensitivityAnalysis"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // Current functionality is normal run experiment + + HandlerUtils.saveBeforeExperimentRun(event); + + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment instanceof IDynamicExperiment) + ((IDynamicExperiment)experiment).simulate(true); + return null; + } + + // What does this method do, is this needed? + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment instanceof SysdynExperiment) { + ExperimentState state = experiment.getState(); + if(state == ExperimentState.RUNNING) { + this.setBaseEnabled(false); + } else { + this.setBaseEnabled(true); + } + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/SaveResultsHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/SaveResultsHandler.java new file mode 100644 index 00000000..dab71d2b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/SaveResultsHandler.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.sensitivityAnalysis; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.simulation.experiment.IDynamicExperiment; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.ui.utils.HandlerUtils; +import org.simantics.ui.SimanticsUI; + +/** + * Save the results of a sensitivity analysis experiment + * @author Tuomas Miettinen + * + */ +public class SaveResultsHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // Current functionality is normal run experiment + + HandlerUtils.saveBeforeExperimentRun(event); + + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment instanceof IDynamicExperiment) { + ((IDynamicExperiment)experiment).saveState(); + } + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/ToggleSimulation.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/ToggleSimulation.java new file mode 100644 index 00000000..f90605c4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/ToggleSimulation.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.sensitivityAnalysis; + + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.State; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynExperiment; +import org.simantics.sysdyn.ui.utils.HandlerUtils; +import org.simantics.ui.SimanticsUI; + +/** + * Handle for the Toggle Simulation button. When the button is down, the + * simulation is run every time the model is changed. + * @author Tuomas Miettinen + * + */ +public class ToggleSimulation extends AbstractHandler implements IElementUpdater { + + public static final String COMMAND = "org.simantics.sysdyn.ui.toggleSensitivityAnalysisSimulation"; + public static final String STATE = "org.simantics.sysdyn.ui.toggleSensitivityAnalysisSimulation.state"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // Current functionality is normal run experiment + HandlerUtils.saveBeforeExperimentRun(event); + + ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + Command command = service.getCommand(COMMAND); + State state = command.getState(STATE); + Boolean value = (Boolean) state.getValue(); + value = !value; + state.setValue(value); + service.refreshElements(RunSensitivityAnalysisExperiment.COMMAND, null); + + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment instanceof SysdynExperiment) { + if(getState()) { + ((SysdynExperiment)experiment).toggleSimulation(true); + } else { + ((SysdynExperiment)experiment).toggleSimulation(false); + } + } + + return null; + } + + public static Boolean getState() { + ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + Command command = service.getCommand(COMMAND); + State state = command.getState(STATE); + return (Boolean)state.getValue(); + } + + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + ICommandService commandService = + (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + Command command = commandService.getCommand(COMMAND); + boolean checked = (Boolean) command.getState(STATE).getValue(); + element.setChecked(checked); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/FastSpeedHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/FastSpeedHandler.java new file mode 100644 index 00000000..d98a44ec --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/FastSpeedHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; + +public class FastSpeedHandler extends SpeedHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setPlaybackSpeed(SysdynPlaybackExperiment.DURATION_FAST); + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/NormalSpeedHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/NormalSpeedHandler.java new file mode 100644 index 00000000..b2ece4d6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/NormalSpeedHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; + +public class NormalSpeedHandler extends SpeedHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setPlaybackSpeed(SysdynPlaybackExperiment.DURATION_NORMAL); + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackExperimentHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackExperimentHandler.java new file mode 100644 index 00000000..72ae6ec7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackExperimentHandler.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.ui.SimanticsUI; + +public class PlaybackExperimentHandler extends AbstractHandler implements IElementUpdater { + + public static final String COMMAND = "org.simantics.sysdyn.ui.playback"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return null; + SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + if(!spe.isPlaybackRunning()) + spe.startPlayback(); + else + spe.stopPlayback(); + return null; + } + + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return; + SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + + ExperimentState state = experiment.getState(); + if(state == ExperimentState.RUNNING && !spe.isPlaybackRunning()) { + // RUNNING == simulation, not playback + this.setBaseEnabled(false); + } else { + this.setBaseEnabled(true); + } + + if(spe.isPlaybackRunning()) { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_pause.png"))); + element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_pause_blue.png"))); + } else { + long duration = spe.getPlaybackDuration(); + if(duration == SysdynPlaybackExperiment.DURATION_SLOW) { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_step.png"))); + element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_step_blue.png"))); + } else if(duration == SysdynPlaybackExperiment.DURATION_FAST) { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_fastforward.png"))); + element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_fastforward_blue.png"))); + } else { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_play.png"))); + element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_play_blue.png"))); + } + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackReloadHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackReloadHandler.java new file mode 100644 index 00000000..75cc05ac --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackReloadHandler.java @@ -0,0 +1,27 @@ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.sysdyn.ui.utils.HandlerUtils; +import org.simantics.ui.SimanticsUI; + +public class PlaybackReloadHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + HandlerUtils.saveBeforeExperimentRun(event); + + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return null; + SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + spe.simulate(true); + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackResetHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackResetHandler.java new file mode 100644 index 00000000..e4155b67 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackResetHandler.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.ui.SimanticsUI; + +public class PlaybackResetHandler extends AbstractHandler implements IElementUpdater { + + public static final String COMMAND = "org.simantics.sysdyn.ui.playbackReset"; + + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return null; + SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + spe.resetPlayback(); + return null; + } + + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return; + SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + + ExperimentState state = experiment.getState(); + if(state == ExperimentState.RUNNING && !spe.isPlaybackRunning()) { + // RUNNING == simulation, not playback + this.setBaseEnabled(false); + } else { + this.setBaseEnabled(true); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SlowSpeedHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SlowSpeedHandler.java new file mode 100644 index 00000000..6ebeba33 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SlowSpeedHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; + +public class SlowSpeedHandler extends SpeedHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setPlaybackSpeed(SysdynPlaybackExperiment.DURATION_SLOW); + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SpeedHandler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SpeedHandler.java new file mode 100644 index 00000000..4fe96910 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SpeedHandler.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.ui.SimanticsUI; + +abstract class SpeedHandler extends AbstractHandler { + + protected void setPlaybackSpeed(long duration) { + + + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return; + final SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + + if(spe.getPlaybackDuration() == duration) + return; + + + spe.setPlaybackDuration(duration); + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + ICommandService commandService = + (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + commandService.refreshElements(PlaybackExperimentHandler.COMMAND, null); + } + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java new file mode 100644 index 00000000..87bccb75 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.listeners; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.State; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.contexts.IContextActivation; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperimentListener; +import org.simantics.sysdyn.ui.handlers.RunBasicExperiment; +import org.simantics.sysdyn.ui.handlers.ToggleSimulation; +import org.simantics.sysdyn.ui.handlers.game.ReloadGameExperimentHandler; +import org.simantics.sysdyn.ui.handlers.game.StepHandler; +import org.simantics.sysdyn.ui.handlers.simulationPlayback.PlaybackExperimentHandler; +import org.simantics.sysdyn.ui.handlers.simulationPlayback.PlaybackResetHandler; + +public class SysdynExperimentListener implements IExperimentListener { + + IContextActivation contextActivation; + + @Override + public void stateChanged(final ExperimentState state) { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + ICommandService commandService = + (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + Command command = commandService.getCommand(ToggleSimulation.COMMAND); + State buttonState = command.getState(ToggleSimulation.STATE); + + switch(state) { + case DISPOSED: + buttonState.setValue(false); + break; + } + commandService.refreshElements(command.getId(), null); + commandService.refreshElements(RunBasicExperiment.COMMAND, null); + commandService.refreshElements(PlaybackExperimentHandler.COMMAND, null); + commandService.refreshElements(PlaybackResetHandler.COMMAND, null); + commandService.refreshElements(StepHandler.COMMAND, null); + commandService.refreshElements(ReloadGameExperimentHandler.COMMAND, null); + } + + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java new file mode 100644 index 00000000..d9c50e81 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.listeners; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.contexts.IContextActivation; +import org.eclipse.ui.contexts.IContextService; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.simulation.project.IExperimentManagerListener; +import org.simantics.sysdyn.manager.SysdynExperiment; +import org.simantics.sysdyn.manager.SysdynGameExperiment; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.sysdyn.manager.SysdynSensitivityAnalysisExperiment; + +public class SysdynExperimentManagerListener implements IExperimentManagerListener{ + + public static final String BASIC_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.basicExperiment"; + public static final String PLAYBACK_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.playbackExperiment"; + public static final String GAME_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.gameExperiment"; + public static final String SENSITIVITY_ANALYSIS_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.sensitivityAnalysisExperiment"; + + static Set managers = + new HashSet(); + + IExperimentManager manager; + + Collection contextActivations = + new ArrayList(); + + public SysdynExperimentManagerListener(IExperimentManager manager) { + this.manager = manager; + } + + public static void listenManager(IExperimentManager manager) { + synchronized(managers) { + if(managers.contains(manager)) + return; + SysdynExperimentManagerListener listener = + new SysdynExperimentManagerListener(manager); + manager.addListener(listener); + managers.add(manager); + } + } + + @Override + public void activeExperimentLoaded(final IExperiment experiment) { + experiment.addListener(new SysdynExperimentListener()); + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + IContextService contextService = + (IContextService)PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getService(IContextService.class); + synchronized(contextActivations) { + if(experiment instanceof SysdynPlaybackExperiment) { + contextActivations.add(contextService.activateContext(PLAYBACK_EXPERIMENT_CONTEXT)); + experiment.addListener(new SysdynPlaybackExperimentListener((SysdynPlaybackExperiment)experiment)); + } else if(experiment instanceof SysdynGameExperiment) { + contextActivations.add(contextService.activateContext(GAME_EXPERIMENT_CONTEXT)); + // TODO: some listener? + } else if(experiment instanceof SysdynSensitivityAnalysisExperiment) { + contextActivations.add(contextService.activateContext(SENSITIVITY_ANALYSIS_EXPERIMENT_CONTEXT)); + // TODO: some listener? + } else if(experiment instanceof SysdynExperiment) { + contextActivations.add(contextService.activateContext(BASIC_EXPERIMENT_CONTEXT)); + } + } + } + + }); + } + + @Override + public void activeExperimentUnloaded() { + + synchronized(contextActivations) { + final Collection oldContextActivations = + contextActivations; + + contextActivations = new ArrayList(); + + final IWorkbench workbench = PlatformUI.getWorkbench(); + workbench.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if (workbench.isClosing()) + return; + + IContextService contextService = + (IContextService)workbench.getActiveWorkbenchWindow().getService(IContextService.class); + contextService.deactivateContexts(oldContextActivations); + } + + }); + } + + } + + @Override + public void managerDisposed() { + synchronized(managers) { + managers.remove(manager); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java new file mode 100644 index 00000000..e527a7f9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java @@ -0,0 +1,266 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.listeners; + +import java.util.HashMap; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.simantics.Simantics; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.diagram.profile.Profiles; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.experiment.IExperimentListener; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.sysdyn.ui.editor.DiagramViewer; +import org.simantics.ui.SimanticsUI; + +/** + * Listener for playback simulations. This listener activates and reverts the playback + * profile when a playback simlation is activated or disposed. + * @author Teemu Lempinen + * + */ +public class SysdynPlaybackExperimentListener implements IExperimentListener { + + private Resource model; + private Resource previousProfile; + + public SysdynPlaybackExperimentListener(SysdynPlaybackExperiment experiment) { + this.model = experiment.getModel(); + activatePlaybackProfile(); + } + + @Override + public void stateChanged(final ExperimentState state) { + switch(state) { + case DISPOSED: + revertPlaybackProfiles(); + break; + } + } + + class DiagramInfo { + public Resource model = null; + public Resource previousProfile = null; + } + + HashMap previousRuntimeDiagramsAndModelUris = new HashMap(); + + private void activatePlaybackProfile() { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + previousRuntimeDiagramsAndModelUris.clear(); + previousRuntimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos(); + activatePlaybackProfileRequest(previousRuntimeDiagramsAndModelUris); + } + }); + } + + private void revertPlaybackProfiles() { + + IProject project = SimanticsUI.getProject(); + if(project == null) + return; + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + + if(experiment != null && experiment instanceof SysdynPlaybackExperiment && this.model.equals(experiment.getModel())) + return; + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + final HashMap runtimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos(); + + VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class); + Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + + Resource model = SysdynPlaybackExperimentListener.this.model; + if(model == null) + return; + + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource defaultProfile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.DefaultProfile)); + if(defaultProfile == null) + return; + + setProfileForModel(graph, model, previousProfile == null ? defaultProfile : previousProfile); + + HashMap infos = getRuntimesForModel(graph, runtimeDiagramsAndModelUris, model); + for(Resource runtimeDiagram : infos.keySet()) { + Resource previous = null; + if(previousRuntimeDiagramsAndModelUris.containsKey(runtimeDiagram)) { + previous = previousRuntimeDiagramsAndModelUris.get(runtimeDiagram).previousProfile; + } + setProfileForDiagram(graph, runtimeDiagram, previous == null ? defaultProfile : previous); + } + } + }); + + } + }); + } + + /** + * Run in display thread. + * + * @return + */ + private HashMap getCurrentRuntimeDiagramInfos() { + HashMap runtimeDiagramsAndModelUris = new HashMap(); + IWorkbench workBench = PlatformUI.getWorkbench(); + IWorkbenchWindow window = workBench.getActiveWorkbenchWindow(); + IWorkbenchPage[] pages = window.getPages(); + for(IWorkbenchPage page : pages) { + for(IEditorReference reference : page.getEditorReferences()) { + IEditorPart iep = reference.getEditor(false); + if(iep instanceof DiagramEditor) { + DiagramEditor editor = (DiagramEditor) iep; + if (editor.getViewer() instanceof DiagramViewer) { + DiagramViewer viewer = (DiagramViewer) editor.getViewer(); + Resource runtime = viewer.getRuntime(); + Resource model = viewer.getResourceInput2().getModel(null); + DiagramInfo info = new DiagramInfo(); + info.model = model; + runtimeDiagramsAndModelUris.put(runtime, info); + } + } + } + } + return runtimeDiagramsAndModelUris; + } + + + private HashMap getRuntimesForModel(WriteGraph graph, HashMap allInfos, Resource model) throws DatabaseException { + HashMap runtimeDiagramsAndModelUris = new HashMap(); + for(Resource runtimeDiagram : allInfos.keySet()) { + DiagramInfo di = allInfos.get(runtimeDiagram); + if(di == null) + continue; + Resource m = di.model; + if(m == null || !model.equals(m)) + continue; + + runtimeDiagramsAndModelUris.put(runtimeDiagram, di); + } + return runtimeDiagramsAndModelUris; + } + + private void activatePlaybackProfileRequest(final HashMap allDiagramInfos) { + VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class); + Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + + Resource model = SysdynPlaybackExperimentListener.this.model; + if(model == null) + return; + + Resource profile = getSimulationPlaybackProfile(graph, model); + if(profile == null) + return; + + DiagramResource DIA = DiagramResource.getInstance(graph); + + Resource current = graph.getPossibleObject(model, DIA.HasActiveProfile); + previousProfile = current; + + if(!profile.equals(current)) { + setProfileForModel(graph, model, profile); + } + + HashMap infos = getRuntimesForModel(graph, allDiagramInfos, model); + for(Resource runtimeDiagram : infos.keySet()) { + DiagramInfo di = infos.get(runtimeDiagram); + current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile); + di.previousProfile = current; + if(profile.equals(current)) + continue; + setProfileForDiagram(graph, runtimeDiagram, profile); + } + } + }); + } + + + private void setProfileForDiagram(WriteGraph graph, Resource runtimeDiagram, Resource profile) throws DatabaseException { + DiagramResource DIA = DiagramResource.getInstance(graph); + + Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile); + if(profile.equals(current)) return; + + if(current != null) + graph.deny(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, current); + graph.claim(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, profile); + + // Set this profile as the default profile for this diagram + Resource configuration = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasConfiguration); + graph.deny(configuration, DIA.HasActiveProfile); + graph.claim(configuration, DIA.HasActiveProfile, profile); + } + + private void setProfileForModel(WriteGraph graph, Resource model, Resource profile) throws DatabaseException { + DiagramResource DIA = DiagramResource.getInstance(graph); + + // Set this profile as the default profile for this model + graph.deny(model, DIA.HasActiveProfile); + graph.claim(model, DIA.HasActiveProfile, profile); + } + + private Resource getSimulationPlaybackProfile(WriteGraph graph, Resource model) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + + Resource profile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.SimulationPlaybackProfile)); + if(profile == null) { + profile = Profiles.createProfile(graph, "Simulation Playback", sr.Profiles_SimulationPlaybackColours); + graph.deny(profile, l0.InstanceOf); + graph.claim(profile, l0.InstanceOf, null, sr.SimulationPlaybackProfile); + graph.claim(model, l0.ConsistsOf, profile); + } + + if(!graph.hasStatement(profile, SIMU.IsActive)) { + graph.claim(profile, SIMU.IsActive, sr.Profiles_SimulationPlaybackColours); + } + + return profile; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/FontContextMenuContribution.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/FontContextMenuContribution.java new file mode 100644 index 00000000..9f69f7b3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/FontContextMenuContribution.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.menu; + +import java.awt.Color; +import java.awt.Font; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.G2DUtils; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.sysdyn.ui.properties.widgets.CustomFontDialog; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.contribution.DynamicMenuContribution; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +/** + * Context menu contribution for modifying fonts and font colors in diagram elements + * + * @author Teemu Lempinen + * + */ +public class FontContextMenuContribution extends DynamicMenuContribution { + + @Override + protected IContributionItem[] getContributionItems(final ReadGraph graph, + Object[] selection) throws DatabaseException { + if (selection.length == 0) + return new IContributionItem[0]; + + return new IContributionItem[] { new ContributionItem() { + + @Override + public void fill(Menu menu, int index) { + + G2DResource G2D = G2DResource.getInstance(graph); + + Object[] selections = getSelectedObjects(); + + Font font = null; + Color color = null; + + /* + * Find a common font and color for the selected elements. + * + * If a common font or color is not found, the initial value in dialog is empty. + */ + try { + for(Object o : selections) { + Resource element = ResourceAdaptionUtils + .adaptToResource(o); + if(element != null) { + Resource fontResource = graph.getPossibleObject(element, G2D.HasFont); + if(fontResource != null) { + Font newFont = G2DUtils.getFont(graph, fontResource); + if(font == null) { + font = newFont; + } + + if(font != null && !font.equals(newFont)) { + font = null; + break; + } + } + } + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + + try { + for(Object o : selections) { + Resource element = ResourceAdaptionUtils + .adaptToResource(o); + if(element != null) { + Resource colorResource = graph.getPossibleObject(element, G2D.HasColor); + if(colorResource != null ) { + Color newColor = G2DUtils.getColor(graph, colorResource); + if(color == null) + color = newColor; + + if(color != null && !color.equals(newColor)) { + color = null; + break; + } + } + } + } + } catch (DatabaseException e) { + } + + // Create the menu item with a selection listener + MenuItem item; + item = new MenuItem(menu, SWT.PUSH); + + item.setText("Font..."); + + item.addSelectionListener(new FontSelectionListener(selections, font, color)); + } + } + }; + + } + + /** + * Selection listener for font context menu action + * @author Teemu Lempinen + * + */ + class FontSelectionListener implements SelectionListener { + + private Font font; + private Color color; + private Object[] selections; + + /** + * Font selection listener for context menu action in diagram + * + * @param selections Selected elements + * @param font Possible common font for the selected elements + * @param color Possible common color for the selected elements + */ + public FontSelectionListener(Object[] selections, Font font, Color color) { + this.selections = selections; + this.font = font; + this.color = color; + } + + @Override + public void widgetSelected(SelectionEvent e) { + // Create the dialog + CustomFontDialog dialog = new CustomFontDialog(e.widget.getDisplay().getActiveShell(), "Sample"); + + // Set possible font and color defaults + if(font != null) + dialog.setAWTFont(font); + + if(color != null) + dialog.setColor(color); + + // Open dialog + dialog.open(); + + // Get results + final Font resultFont = dialog.getAWTFont(); + final Color resultColor = dialog.getAWTColor(); + + // Apply results to all selected elements + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + G2DResource G2D = G2DResource.getInstance(graph); + + for(Object o : selections) { + Resource element = ResourceAdaptionUtils + .adaptToResource(o); + if(resultFont != null) { + graph.deny(element, G2D.HasFont); + graph.claim(element, G2D.HasFont, G2DUtils.createFont(graph, resultFont)); + } + + if(resultColor != null) { + graph.deny(element, G2D.HasColor); + graph.claim(element, G2D.HasColor, G2DUtils.createColor(graph, resultColor)); + } + } + } + }); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/GameStepDurationContribution.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/GameStepDurationContribution.java new file mode 100644 index 00000000..4281055f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/GameStepDurationContribution.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.menu; + +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.ui.actions.CompoundContributionItem; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.management.ISessionContext; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynGameExperiment; +import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.validators.DoubleValidator; + + +/** + * Contribution for adding a text field to menu bar. The text field is used + * to set the duration of one simulation step. This duration is different from + * the step length the simulator uses. Simulator steps as many steps that fit into + * the simulation duration determined in this field. + * + * @author Teemu Lempinen + * + */ +public class GameStepDurationContribution extends CompoundContributionItem { + + private TrackedText stepDuration; + private int width = 40; + private ToolItem ti; + + public static String COMMAND = "org.simantics.sysdyn.ui.gameStepDuration"; + + public GameStepDurationContribution() { + super(COMMAND); + } + + @Override + protected IContributionItem[] getContributionItems() { + return new IContributionItem[0]; + } + + @Override + public void fill(final ToolBar parent, final int index) { + IProject project = SimanticsUI.peekProject(); + if (project == null) + return; + + // Find game experiment + IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + + IExperiment active = manager.getActiveExperiment(); + if (!(active instanceof SysdynGameExperiment)) + return; + + final SysdynGameExperiment game = (SysdynGameExperiment) active; + + // Create the text + + ti = new ToolItem(parent, SWT.SEPARATOR, index); + ti.setText("Step Duration"); + ti.setToolTipText("Step Duration"); + + ISessionContext context = SimanticsUI.getSessionContext(); + WidgetSupportImpl support = new WidgetSupportImpl(); // Dummy widget support for using tracked text + + stepDuration = new TrackedText(parent, support, SWT.BORDER); + ResourceManager resourceManager = new LocalResourceManager(JFaceResources.getResources(), stepDuration.getWidget()); + stepDuration.setColorProvider(new SysdynBasicColorProvider(resourceManager)); + stepDuration.setInputValidator(new DoubleValidator()); + stepDuration.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.GameExperiment_stepDuration)); + stepDuration.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.GameExperiment_stepDuration)); + + support.fireInput(context, game.getResource()); + + ti.setWidth(width); + ti.setControl(stepDuration.getWidget()); + + } + + @Override + public boolean isDynamic() { + return true; + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java new file mode 100644 index 00000000..27e3b551 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.menu; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; + +import org.eclipse.jface.action.ToolBarContributionItem; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Slider; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.ui.SimanticsUI; + +/** + * Contribution to the main toolbar. PlaybackSliderContribution contains a slider + * that can be used to control the time in a playback experiment + * + * @author Teemu Lempinen + * + */ +public class PlaybackSliderContribution extends ToolBarContributionItem { + + Runnable timeListener; + SysdynPlaybackExperiment spe; + Slider s; + Double startTime, endTime; + boolean ignoreChange = false; + + @Override + public void fill(ToolBar parent, int index) + { + if (parent != null) { + + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return; + spe = (SysdynPlaybackExperiment)experiment; + + Double[] numbers = new Double[2]; + try { + numbers = SimanticsUI.getSession().syncRequest(new Read() { + @Override + public Double[] perform(ReadGraph graph) throws DatabaseException { + Double[] numbers = new Double[2]; + Resource model = spe.getModel(); + SysdynResource sr = SysdynResource.getInstance(graph); + numbers[0] = graph.getRelatedValue(model, sr.SysdynModel_startTime); + numbers[1] = graph.getRelatedValue(model, sr.SysdynModel_stopTime); + return numbers; + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + // Separator ToolItem can contain a composite. Add a composite with a slider to this item + ToolItem ti = new ToolItem(parent, SWT.SEPARATOR); + + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().margins(3, SWT.DEFAULT).numColumns(2).applyTo(composite); + GridDataFactory.fillDefaults().applyTo(composite); + + s = new Slider(composite, SWT.NONE); + s.setMinimum(0); + s.setMaximum(100); + s.setIncrement(1); + s.setPageIncrement(1); + s.setThumb(1); + + final Label label = new Label(composite, SWT.NONE); + GridDataFactory.fillDefaults().hint(70, SWT.DEFAULT).applyTo(label); + label.setText("0.0"); + + ti.setWidth(270); + ti.setControl(composite); + + startTime = numbers[0]; + endTime = numbers[1]; + + // Create a DesimalFormat for rounding the time + final DecimalFormat format = new DecimalFormat(); + format.setMinimumFractionDigits(0); + format.setMaximumFractionDigits(2); + DecimalFormatSymbols symbols = new DecimalFormatSymbols(); + symbols.setDecimalSeparator('.'); + symbols.setGroupingSeparator(' '); + format.setDecimalFormatSymbols(symbols); + + // Selection listener for the slider + s.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + Slider s = (Slider)e.widget; + Double time = s.getSelection() / 99.0 * (endTime - startTime) + startTime; + spe.setTimeAndContinue(time); + if(!label.isDisposed()) { + label.setText(format.format(time)); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + if(timeListener != null) { + spe.removeTimeListener(timeListener); + } + + // Time listener for setting the time in the slider if the time is changed somewhere else + timeListener = new Runnable() { + + @Override + public void run() { + s.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(!startTime.equals(spe.getStartTime()) || !endTime.equals(spe.getEndTime())) { + startTime = spe.getStartTime(); + endTime = spe.getEndTime(); + } + int value = (int) Math.round(((spe.getTime() - startTime) / (endTime - startTime) * 99)); + s.setSelection(value); + label.setText(format.format(spe.getTime())); + } + }); + + } + + }; + spe.addTimeListener(timeListener); + } + } + + @Override + public void dispose() { + if(this.timeListener != null && spe != null) { + spe.removeTimeListener(timeListener); + this.timeListener = null; + } + super.dispose(); + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/ModelicaSourceViewerConfiguration.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/ModelicaSourceViewerConfiguration.java new file mode 100644 index 00000000..84c0055f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/ModelicaSourceViewerConfiguration.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.modelica; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; + +public class ModelicaSourceViewerConfiguration extends SourceViewerConfiguration { + + @Override + public IPresentationReconciler getPresentationReconciler( + ISourceViewer sourceViewer) { + PresentationReconciler pr = new PresentationReconciler(); + DefaultDamagerRepairer ddr = new DefaultDamagerRepairer( + new RuleBasedScanner() { + { + setRules(new IRule[] {new IRule() { + + @Override + public IToken evaluate(ICharacterScanner scanner) { + int ch; + try { + scanner.unread(); + ch = scanner.read(); + } catch (Throwable t) { + ch = -1; + } + if (ch <= 0 || !isIdentifierChar((char) ch)) { + ch = scanner.read(); + if(isIdentifierChar((char)ch)) { + StringBuilder b = new StringBuilder(); + do { + b.append((char)ch); + ch = scanner.read(); + } while(isIdentifierChar((char) ch)); + String str = b.toString(); + if(keywords.contains(str)) + return getModelicaKeywordToken(); + } + scanner.unread(); + } + return Token.UNDEFINED; + } + + }}); + } + } + ); + pr.setRepairer(ddr, IDocument.DEFAULT_CONTENT_TYPE); + pr.setDamager(ddr, IDocument.DEFAULT_CONTENT_TYPE); + return pr; + } + + static boolean isIdentifierChar(char c) { + return + (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') || c == '_'; + } + + // Includes also tokens that are strictly speaking not keywords + // but should be handled in (almost) a similar fashion. + public static final Set keywords = new HashSet(); + + static { + keywords.add("algorithm"); + keywords.add("discrete"); + keywords.add("false"); + keywords.add("model"); + keywords.add("redeclare"); + keywords.add("and"); + keywords.add("each"); + keywords.add("final"); + keywords.add("not"); + keywords.add("replaceable"); + keywords.add("annotation"); + keywords.add("else"); + keywords.add("flow"); + keywords.add("operator"); + keywords.add("return"); + keywords.add("assert"); + keywords.add("elseif"); + keywords.add("for"); + keywords.add("or"); + keywords.add("stream"); + keywords.add("block"); + keywords.add("elsewhen"); + keywords.add("function"); + keywords.add("outer"); + keywords.add("then"); + keywords.add("break"); + keywords.add("encapsulated"); + keywords.add("if"); + keywords.add("output"); + keywords.add("true"); + keywords.add("class"); + keywords.add("end"); + keywords.add("import"); + keywords.add("package"); + keywords.add("type"); + keywords.add("connect"); + keywords.add("enumeration"); + keywords.add("in"); + keywords.add("parameter"); + keywords.add("when"); + keywords.add("connector"); + keywords.add("equation"); + keywords.add("initial"); + keywords.add("partial"); + keywords.add("while"); + keywords.add("constant"); + keywords.add("expandable"); + keywords.add("inner"); + keywords.add("protected"); + keywords.add("within"); + keywords.add("constrainedby"); + keywords.add("extends"); + keywords.add("input"); + keywords.add("public"); + keywords.add("der"); + keywords.add("external"); + keywords.add("loop"); + keywords.add("record"); + keywords.add("time"); + keywords.add("pure"); + keywords.add("impure"); + keywords.add("Real"); + keywords.add("Boolean"); + keywords.add("Integer"); + keywords.add("String"); + } + + static IToken modelicaKeywordToken = null; + public IToken getModelicaKeywordToken() { + if(modelicaKeywordToken == null) { + modelicaKeywordToken = + new Token( + new TextAttribute( + new Color(null, 127, 0, 85), + new Color(null, 255, 255, 255), + SWT.BOLD + )); + } + return modelicaKeywordToken; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/SysdynModelicaEditor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/SysdynModelicaEditor.java new file mode 100644 index 00000000..7d15f3ee --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/SysdynModelicaEditor.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.modelica; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.PaintManager; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.jface.text.source.AnnotationPainter; +import org.eclipse.jface.text.source.DefaultCharacterPairMatcher; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.MatchingCharacterPainter; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.editors.text.TextEditor; +import org.eclipse.ui.texteditor.AbstractDocumentProvider; +import org.simantics.db.exception.DatabaseException; +import org.simantics.modelica.ModelicaManager; +import org.simantics.sysdyn.modelica.ModelicaWriter; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.LoadRepresentation; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.ModuleType; +import org.simantics.sysdyn.representation.utils.RepresentationUtils; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.workbench.ResourceEditorInput; + +/** + * Text editor for displaying Modelica code + * + * @author Teemu Lempinen + * + */ +public class SysdynModelicaEditor extends TextEditor { + + AnnotationModel annotationModel = new AnnotationModel(); + AnnotationPainter apainter; + + + public void init(final IEditorSite site, final IEditorInput input) throws PartInitException { + super.init(site, input); + try { + Configuration configuration = + LoadRepresentation.loadConfiguration(SimanticsUI.getSession(), ((ResourceEditorInput)input).getResource()); + setPartName(configuration.getLabel()); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + public SysdynModelicaEditor() { + super(); + showOverviewRuler(); + setDocumentProvider(new AbstractDocumentProvider() { + + @Override + protected IAnnotationModel createAnnotationModel(Object element) + throws CoreException { + return annotationModel; + } + + @Override + protected IDocument createDocument(Object element) + throws CoreException { + try { + Configuration configuration = + LoadRepresentation.loadConfiguration(SimanticsUI.getSession(), ((ResourceEditorInput)element).getResource()); + + HashSet configurations = new HashSet(); + configurations.add(configuration); + getConfigurations(configuration, configurations); + + String version = ModelicaManager.getDefaultOMVersion(); + return new Document(ModelicaWriter.write(configurations, RepresentationUtils.isGameExperimentActive(), version)); + } catch (DatabaseException e) { + e.printStackTrace(); + throw new CoreException(STATUS_ERROR); + } + } + + @Override + protected void doSaveDocument(IProgressMonitor monitor, + Object element, IDocument document, boolean overwrite) + throws CoreException { + } + + @Override + protected IRunnableContext getOperationRunner( + IProgressMonitor monitor) { + return PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + } + + @Override + public boolean isModifiable(Object element) { + return false; + } + + @Override + public boolean isReadOnly(Object element) { + return true; + } + + }); + + setSourceViewerConfiguration(new ModelicaSourceViewerConfiguration()); + + } + + private void getConfigurations(Configuration configuration, Set configurations) { + for(IElement e : configuration.getElements()) { + if(e instanceof Module) { + ModuleType mt = ((Module) e).getType(); + configurations.add(mt.getConfiguration()); + getConfigurations(mt.getConfiguration(), configurations); + } + } + } + + @Override + protected void createActions() { + super.createActions(); + + PaintManager paintManager = new PaintManager(getSourceViewer()); + MatchingCharacterPainter matchingCharacterPainter = new MatchingCharacterPainter(getSourceViewer(), + new DefaultCharacterPairMatcher( new char[] {'(', ')', '{', '}', '[', ']'} )); + matchingCharacterPainter.setColor(new Color(Display.getCurrent(), new RGB(160, 160, 160))); + paintManager.addPainter(matchingCharacterPainter); + } + + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/TextEditorActionBarContributor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/TextEditorActionBarContributor.java new file mode 100644 index 00000000..555b13aa --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/TextEditorActionBarContributor.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.modelica; + +import org.eclipse.ui.part.EditorActionBarContributor; + +public class TextEditorActionBarContributor extends EditorActionBarContributor { + + public TextEditorActionBarContributor() { + // TODO Auto-generated constructor stub + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/ModelicaPreferencePage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/ModelicaPreferencePage.java new file mode 100644 index 00000000..443c9014 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/ModelicaPreferencePage.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.preferences; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.jface.preference.DirectoryFieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.RadioGroupFieldEditor; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.osgi.service.prefs.Preferences; +import org.simantics.modelica.Activator; +import org.simantics.modelica.ModelicaManager; +import org.simantics.modelica.preferences.OpenModelicaPreferences; + +public class ModelicaPreferencePage extends FieldEditorPreferencePage implements + IWorkbenchPreferencePage { + + private static String CUSTOM_PATH = "Custom path"; + + private DirectoryFieldEditor path; + private RadioGroupFieldEditor rg; + + public ModelicaPreferencePage() { + super(GRID); + setDescription("Modelica preferences"); + } + + @Override + public void init(IWorkbench workbench) { + setPreferenceStore(new ScopedPreferenceStore(ConfigurationScope.INSTANCE, Activator.PLUGIN_ID)); + } + + @Override + public void createFieldEditors() { + final File installed = ModelicaManager.getInstalledOMHome(); + final File builtIn = ModelicaManager.getBuiltinOMHome(); + + List optionList = new ArrayList(); + optionList.add(new String[]{CUSTOM_PATH, CUSTOM_PATH}); + if (installed != null) { + optionList.add(new String[]{ "Local installation (" + ModelicaManager.getOMVersion(installed) + ")", installed.getAbsolutePath() }); + } + if (builtIn != null) { + optionList.add(new String[]{ "Built-in (" + ModelicaManager.getOMVersion(builtIn) + ")", builtIn.getAbsolutePath() }); + } + + String[][] options = optionList.toArray(new String[optionList.size()][]); + + rg = new RadioGroupFieldEditor(OpenModelicaPreferences.OM_HOME, + "&Choose the used OpenModelica version", 1, + options, getFieldEditorParent()) { + + @Override + protected void doStore() { + // Do nothing. Path handles saving the value + } + + @Override + protected void fireValueChanged(String property, Object oldValue, Object newValue) { + if((installed != null && newValue.equals(installed.getAbsolutePath())) || (builtIn != null && newValue.equals(builtIn.getAbsolutePath()))) { + path.setStringValue((String)newValue); + path.setEnabled(false, getFieldEditorParent()); + } else { + path.setEnabled(true, getFieldEditorParent()); + } + } + + @Override + public void doLoadDefault() { + System.err.println("LOAD DEFAULT"); + IScopeContext context = ConfigurationScope.INSTANCE; + Preferences node = context.getNode(Activator.PLUGIN_ID); + node.put(OpenModelicaPreferences.OM_HOME, ModelicaManager.getDefaultOMHome().getAbsolutePath()); + load(); + } + }; + + addField(rg); + + path = new DirectoryFieldEditor(OpenModelicaPreferences.OM_HOME, + "&Modelica Home:", getFieldEditorParent()) { + + @Override + public void setValidateStrategy(int value) { + super.setValidateStrategy(StringFieldEditor.VALIDATE_ON_KEY_STROKE); + } + + @Override + public void doStore() { + super.doStore(); + IScopeContext context = ConfigurationScope.INSTANCE; + Preferences node = context.getNode(Activator.PLUGIN_ID); + node.put(OpenModelicaPreferences.OM_HOME, getStringValue()); + } + + @Override + protected boolean doCheckState() { + boolean valid = super.doCheckState(); + if(valid) { + // path is a valid directory + String path = getStringValue(); + File dir = new File(path); + String version = ModelicaManager.getOMVersion(dir); + if(version == null || version.isEmpty()) { + return false; + } + } + + return valid; + } + + @Override + public void doLoad() { + super.doLoad(); + String value = getStringValue(); + updatePath(value); + } + + @Override + public void doLoadDefault() { + updatePath(ModelicaManager.getDefaultOMHome().getAbsolutePath()); + } + + private void updatePath(String newValue) { + if((installed != null && newValue.equals(installed.getAbsolutePath()) || newValue.equals(builtIn.getAbsolutePath()))) { + path.setStringValue(newValue); + path.setEnabled(false, getFieldEditorParent()); + } else { + path.setEnabled(true, getFieldEditorParent()); + } + } + + + }; + + path.setErrorMessage("Path must be a valid OpenModelica directory"); + addField(path); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java new file mode 100644 index 00000000..3cd3f059 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java @@ -0,0 +1,37 @@ +package org.simantics.sysdyn.ui.preferences; + +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.RadioGroupFieldEditor; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.simantics.sysdyn.solver.SolverSettings; + +public class SolverPreferencePage extends FieldEditorPreferencePage implements + IWorkbenchPreferencePage { + + private FieldEditor solverEditor; + + public SolverPreferencePage() { + super(GRID); + setDescription("Solver preferences"); + } + + @Override + public void init(IWorkbench workbench) { + setPreferenceStore(new ScopedPreferenceStore(ConfigurationScope.INSTANCE, SolverSettings.QUALIFIER)); + } + + @Override + protected void createFieldEditors() { + solverEditor = new RadioGroupFieldEditor(SolverSettings.SOLVER_TYPE, "Solver type", 1, + new String[][] { + { "Internal", SolverSettings.SOLVER_TYPE_INTERNAL }, + { "OpenModelica", SolverSettings.SOLVER_TYPE_OPENMODELICA } + }, getFieldEditorParent()); + addField(solverEditor); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencePage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencePage.java new file mode 100644 index 00000000..4f9639da --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencePage.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy + *******************************************************************************/ + +package org.simantics.sysdyn.ui.preferences; + +import java.util.HashMap; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ColorFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.FontFieldEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.simantics.sysdyn.ui.Activator; + +/** + * + * @author Teemu Lempinen + * + */ +public class SysdynDiagramPreferencePage extends FieldEditorPreferencePage implements +IWorkbenchPreferencePage { + + private HashMap fieldParents; + private Group colorEditors, fontEditors; + + public SysdynDiagramPreferencePage() { + super(GRID); + setDescription("System dynamics diagram preferences"); + fieldParents = new HashMap(); + } + + @Override + public void init(IWorkbench workbench) { + setPreferenceStore(Activator.getDefault().getPreferenceStore()); + } + + @Override + protected void createFieldEditors() { + Composite parent = new Composite(getFieldEditorParent(), SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(1).applyTo(parent); + GridDataFactory.fillDefaults().grab(true, true).applyTo(parent); + + // DEFAULTS + Group defaults = new Group(parent, SWT.NONE); + defaults.setText("Default settings"); + GridDataFactory.fillDefaults().grab(true, false).applyTo(defaults); + addField(new ColorFieldEditor(SysdynDiagramPreferences.DEFAULT_COLOR, "Color", defaults)); + addField(new CustomFontFieldEditor(SysdynDiagramPreferences.DEFAULT_FONT, "Font", defaults)); + GridLayout layout = (GridLayout) defaults.getLayout(); + layout.marginHeight = 3; + layout.marginWidth = 3; + defaults.setLayout(layout); + + // COLORS + colorEditors = new Group(parent, SWT.NONE); + colorEditors.setText("Colors"); + GridDataFactory.fillDefaults().applyTo(colorEditors); + GridDataFactory.fillDefaults().applyTo(colorEditors); + Label label = new Label(colorEditors, SWT.NONE); + GridDataFactory.fillDefaults().span(3, 1).applyTo(label); + + label = new Label(colorEditors, SWT.NONE); + label.setText("Use default"); + GridDataFactory.fillDefaults().applyTo(label); + + addColorFieldEditor(SysdynDiagramPreferences.ARROW_COLOR, "&Dependency", SysdynDiagramPreferences.ARROW_USE_DEFAULT_COLOR); + addColorFieldEditor(SysdynDiagramPreferences.FLOW_COLOR, "&Flow", SysdynDiagramPreferences.FLOW_USE_DEFAULT_COLOR); + addColorFieldEditor(SysdynDiagramPreferences.AUXILIARY_COLOR, "&Auxiliary", SysdynDiagramPreferences.AUXILIARY_USE_DEFAULT_COLOR); + addColorFieldEditor(SysdynDiagramPreferences.STOCK_COLOR, "&Stock", SysdynDiagramPreferences.STOCK_USE_DEFAULT_COLOR); + addColorFieldEditor(SysdynDiagramPreferences.VALVE_COLOR, "&Valve", SysdynDiagramPreferences.VALVE_USE_DEFAULT_COLOR); + addColorFieldEditor(SysdynDiagramPreferences.INPUT_COLOR, "&Input", SysdynDiagramPreferences.VALVE_USE_DEFAULT_COLOR); + addColorFieldEditor(SysdynDiagramPreferences.CLOUD_COLOR, "&Cloud", SysdynDiagramPreferences.CLOUD_USE_DEFAULT_COLOR); + addColorFieldEditor(SysdynDiagramPreferences.MODULE_COLOR, "&Module", SysdynDiagramPreferences.MODULE_USE_DEFAULT_COLOR); + + // FONTS + fontEditors = new Group(parent, SWT.NONE); + fontEditors.setText("Fonts"); + GridDataFactory.fillDefaults().applyTo(fontEditors); + GridLayoutFactory.fillDefaults().applyTo(fontEditors); + + label = new Label(fontEditors, SWT.NONE); + GridDataFactory.fillDefaults().span(3, 1).applyTo(label); + + label = new Label(fontEditors, SWT.NONE); + label.setText("Use default"); + GridDataFactory.fillDefaults().applyTo(label); + + addFontFieldEditor(SysdynDiagramPreferences.ARROW_FONT, "Dependency", SysdynDiagramPreferences.ARROW_USE_DEFAULT_FONT); + addFontFieldEditor(SysdynDiagramPreferences.AUXILIARY_FONT, "Auxiliary", SysdynDiagramPreferences.AUXILIARY_USE_DEFAULT_FONT); + addFontFieldEditor(SysdynDiagramPreferences.STOCK_FONT, "Stock", SysdynDiagramPreferences.STOCK_USE_DEFAULT_FONT); + addFontFieldEditor(SysdynDiagramPreferences.VALVE_FONT, "Valve", SysdynDiagramPreferences.VALVE_USE_DEFAULT_FONT); + addFontFieldEditor(SysdynDiagramPreferences.INPUT_FONT, "Input", SysdynDiagramPreferences.INPUT_USE_DEFAULT_FONT); + addFontFieldEditor(SysdynDiagramPreferences.CLOUD_FONT, "Cloud", SysdynDiagramPreferences.CLOUD_USE_DEFAULT_FONT); + addFontFieldEditor(SysdynDiagramPreferences.MODULE_FONT, "Module", SysdynDiagramPreferences.MODULE_USE_DEFAULT_FONT); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(4).applyTo(colorEditors); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(4).applyTo(fontEditors); + } + + + private void addColorFieldEditor(String property, String label, String defaultBoolean) { + ColorFieldEditor colorField = new ColorFieldEditor(property, label, colorEditors); + colorField.setEnabled(!getPreferenceStore().getBoolean(defaultBoolean), colorEditors); + Composite c = new Composite(colorEditors, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(c); + GridLayoutFactory.fillDefaults().applyTo(c); + BooleanFieldEditor useDefault = new DefaultBooleanFiedEditor(colorField, defaultBoolean, c); + fieldParents.put(colorField, colorEditors); + addField(useDefault); + addField(colorField); + } + + private void addFontFieldEditor(String property, String label, String defaultBoolean) { + CustomFontFieldEditor fontField = new CustomFontFieldEditor(property, label, fontEditors); + fontField.setEnabled(!getPreferenceStore().getBoolean(defaultBoolean), fontEditors); + Composite c = new Composite(fontEditors, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(c); + GridLayoutFactory.fillDefaults().applyTo(c); + BooleanFieldEditor useDefault = new DefaultBooleanFiedEditor(fontField, defaultBoolean, c); + + + + fieldParents.put(fontField, fontEditors); + addField(useDefault); + addField(fontField); + } + + private class DefaultBooleanFiedEditor extends BooleanFieldEditor { + private FieldEditor fieldEditor; + + public DefaultBooleanFiedEditor(FieldEditor fieldEditor, String name, Composite parent) { + super(name, "", parent); + this.fieldEditor = fieldEditor; + } + + @Override + protected void valueChanged(boolean oldValue, boolean newValue) { + super.valueChanged(oldValue, newValue); + fieldEditor.setEnabled(!newValue, fieldParents.get(fieldEditor)); + } + } + + private class CustomFontFieldEditor extends FontFieldEditor { + + public CustomFontFieldEditor(String name, String labelText, Composite parent) { + super(name, labelText, parent); + + GridDataFactory.fillDefaults().applyTo(getChangeControl(parent)); + setChangeButtonText("..."); + getChangeControl(parent).setToolTipText("Change"); + + + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferences.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferences.java new file mode 100644 index 00000000..94c4bcab --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferences.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy + *******************************************************************************/ +package org.simantics.sysdyn.ui.preferences; + +import java.util.HashMap; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.Activator; + +/** + * + * @author Teemu Lempinen + * + */ +public class SysdynDiagramPreferences { + + public static String DEFAULT_COLOR = "Default color"; + public static String DEFAULT_FONT = "Default font"; + + public static String ARROW_COLOR = "Arrow color"; + public static String FLOW_COLOR = "Flow color"; + public static String AUXILIARY_COLOR = "Auxiliary color"; + public static String CLOUD_COLOR = "Cloud color"; + public static String STOCK_COLOR = "Stock color"; + public static String VALVE_COLOR = "Valve color"; + public static String INPUT_COLOR = "Input color"; + public static String MODULE_COLOR = "Module color"; + + public static HashMap colorPreferenceNames; + + static { + colorPreferenceNames = new HashMap(); + colorPreferenceNames.put(SysdynResource.URIs.DependencyConnection, ARROW_COLOR); + colorPreferenceNames.put(SysdynResource.URIs.FlowConnection, FLOW_COLOR); + colorPreferenceNames.put(SysdynResource.URIs.AuxiliarySymbol, AUXILIARY_COLOR); + colorPreferenceNames.put(SysdynResource.URIs.CloudSymbol, CLOUD_COLOR); + colorPreferenceNames.put(SysdynResource.URIs.StockSymbol, STOCK_COLOR); + colorPreferenceNames.put(SysdynResource.URIs.ValveSymbol, VALVE_COLOR); + colorPreferenceNames.put(SysdynResource.URIs.InputSymbol, INPUT_COLOR); + colorPreferenceNames.put(SysdynResource.URIs.ModuleSymbol, MODULE_COLOR); + } + + public static String getColorPreferenceName(ReadGraph graph, Resource resource) + throws DatabaseException { + String preference = colorPreferenceNames.get(getSymbolUri(graph, resource)); + return preference; + } + + public static String ARROW_USE_DEFAULT_COLOR = "Arrow use default color"; + public static String FLOW_USE_DEFAULT_COLOR = "Flow use default color"; + public static String AUXILIARY_USE_DEFAULT_COLOR = "Auxiliary use default color"; + public static String CLOUD_USE_DEFAULT_COLOR = "Cloud use default color"; + public static String STOCK_USE_DEFAULT_COLOR = "Stock use default color"; + public static String VALVE_USE_DEFAULT_COLOR = "Valve use default color"; + public static String INPUT_USE_DEFAULT_COLOR = "Input use default color"; + public static String MODULE_USE_DEFAULT_COLOR = "Module use default color"; + + public static HashMap colorDefaults; + + static { + colorDefaults = new HashMap(); + colorDefaults.put(ARROW_COLOR, ARROW_USE_DEFAULT_COLOR); + colorDefaults.put(FLOW_COLOR, FLOW_USE_DEFAULT_COLOR); + colorDefaults.put(AUXILIARY_COLOR, AUXILIARY_USE_DEFAULT_COLOR); + colorDefaults.put(CLOUD_COLOR, CLOUD_USE_DEFAULT_COLOR); + colorDefaults.put(STOCK_COLOR, STOCK_USE_DEFAULT_COLOR); + colorDefaults.put(VALVE_COLOR, VALVE_USE_DEFAULT_COLOR); + colorDefaults.put(INPUT_COLOR, INPUT_USE_DEFAULT_COLOR); + colorDefaults.put(MODULE_COLOR, MODULE_USE_DEFAULT_COLOR); + + } + + public static String ARROW_FONT = "Arrow font"; + public static String AUXILIARY_FONT = "Auxiliary font"; + public static String CLOUD_FONT = "Cloud font"; + public static String STOCK_FONT = "Stock font"; + public static String VALVE_FONT = "Valve font"; + public static String INPUT_FONT = "Input font"; + public static String MODULE_FONT = "Module font"; + + public static HashMap fontPreferenceNames; + + static { + fontPreferenceNames = new HashMap(); + fontPreferenceNames.put(SysdynResource.URIs.DependencyConnection, ARROW_FONT); + fontPreferenceNames.put(SysdynResource.URIs.AuxiliarySymbol, AUXILIARY_FONT); + fontPreferenceNames.put(SysdynResource.URIs.CloudSymbol, CLOUD_FONT); + fontPreferenceNames.put(SysdynResource.URIs.StockSymbol, STOCK_FONT); + fontPreferenceNames.put(SysdynResource.URIs.ValveSymbol, VALVE_FONT); + fontPreferenceNames.put(SysdynResource.URIs.InputSymbol, INPUT_FONT); + fontPreferenceNames.put(SysdynResource.URIs.ModuleSymbol, MODULE_FONT); + } + + public static String getFontPreferenceName(ReadGraph graph, Resource resource) + throws DatabaseException { + + String preference = fontPreferenceNames.get(getSymbolUri(graph, resource)); + return preference; + } + + public static String ARROW_USE_DEFAULT_FONT = "Arrow use default font"; + public static String AUXILIARY_USE_DEFAULT_FONT = "Auxiliary use default font"; + public static String CLOUD_USE_DEFAULT_FONT = "Cloud use default font"; + public static String STOCK_USE_DEFAULT_FONT = "Stock use default font"; + public static String VALVE_USE_DEFAULT_FONT = "Valve use default font"; + public static String INPUT_USE_DEFAULT_FONT = "Input use default font"; + public static String MODULE_USE_DEFAULT_FONT = "Module use default font"; + + + public static HashMap fontDefaults; + + static { + fontDefaults = new HashMap(); + fontDefaults.put(ARROW_FONT, ARROW_USE_DEFAULT_FONT); + fontDefaults.put(AUXILIARY_FONT, AUXILIARY_USE_DEFAULT_FONT); + fontDefaults.put(CLOUD_FONT, CLOUD_USE_DEFAULT_FONT); + fontDefaults.put(STOCK_FONT, STOCK_USE_DEFAULT_FONT); + fontDefaults.put(VALVE_FONT, VALVE_USE_DEFAULT_FONT); + fontDefaults.put(INPUT_FONT, INPUT_USE_DEFAULT_FONT); + fontDefaults.put(MODULE_FONT, MODULE_USE_DEFAULT_FONT); + } + + + + private static String getSymbolUri(ReadGraph graph, Resource resource) + throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource symbol = graph.getSingleObject(resource, L0.InstanceOf); + + SysdynResource SR = SysdynResource.getInstance(graph); + if(graph.isInheritedFrom(symbol, SR.ModuleSymbol)) + symbol = SR.ModuleSymbol; + + return graph.getURI(symbol); + } + + /** + * Get the name of the property that decides whether to use default value or not + * @param property + * @return + */ + public static String getUseDefaultProperty(String property) { + String result = colorDefaults.get(property); + if(result == null) + result = fontDefaults.get(property); + return result; + } + + /** + * Returns default property if USE DEFAULT is set, otherwise returns the + * same property as given as argument. + * @param property + * @return + */ + public static String getPreferenceName(String property) { + String useDefault = fontDefaults.get(property); + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + if(useDefault != null && store.getBoolean(useDefault)) { + return DEFAULT_FONT; + } + + useDefault = colorDefaults.get(property); + if(useDefault != null && store.getBoolean(useDefault)) { + return DEFAULT_COLOR; + } + + return property; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencesInitializer.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencesInitializer.java new file mode 100644 index 00000000..cd5c8f50 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencesInitializer.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy + *******************************************************************************/ +package org.simantics.sysdyn.ui.preferences; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; +import org.simantics.sysdyn.ui.Activator; + +import com.lowagie.text.Font; + +/** + * + * @author Teemu Lempinen + * + */ +public class SysdynDiagramPreferencesInitializer extends AbstractPreferenceInitializer { + + @Override + public void initializeDefaultPreferences() { + RGB black = new RGB(0, 0, 0); + RGB arrow = new RGB(0,128,192); + + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.DEFAULT_COLOR, black); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.ARROW_COLOR, arrow); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.FLOW_COLOR, black); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.AUXILIARY_COLOR, black); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.STOCK_COLOR, black); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.VALVE_COLOR, black); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.INPUT_COLOR, black); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.CLOUD_COLOR, black); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.MODULE_COLOR, black); + + + store.setDefault(SysdynDiagramPreferences.ARROW_USE_DEFAULT_COLOR, false); + store.setDefault(SysdynDiagramPreferences.FLOW_USE_DEFAULT_COLOR, true); + store.setDefault(SysdynDiagramPreferences.AUXILIARY_USE_DEFAULT_COLOR, true); + store.setDefault(SysdynDiagramPreferences.STOCK_USE_DEFAULT_COLOR, true); + store.setDefault(SysdynDiagramPreferences.VALVE_USE_DEFAULT_COLOR, true); + store.setDefault(SysdynDiagramPreferences.INPUT_USE_DEFAULT_COLOR, true); + store.setDefault(SysdynDiagramPreferences.CLOUD_USE_DEFAULT_COLOR, true); + store.setDefault(SysdynDiagramPreferences.MODULE_USE_DEFAULT_COLOR, true); + + FontData[] basicFont = new FontData[] {new FontData("Tahoma", 12, Font.NORMAL)}; + FontData[] italicFont = new FontData[] {new FontData("Tahoma", 12, Font.ITALIC)}; + FontData[] moduleFont = new FontData[] {new FontData("Tahoma", 16, Font.NORMAL)}; + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.DEFAULT_FONT, basicFont); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.ARROW_FONT, basicFont); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.AUXILIARY_FONT, basicFont); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.STOCK_FONT, basicFont); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.VALVE_FONT, basicFont); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.INPUT_FONT, italicFont); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.CLOUD_FONT, basicFont); + PreferenceConverter.setDefault(store, SysdynDiagramPreferences.MODULE_FONT, moduleFont); + + store.setDefault(SysdynDiagramPreferences.ARROW_USE_DEFAULT_FONT, true); + store.setDefault(SysdynDiagramPreferences.AUXILIARY_USE_DEFAULT_FONT, true); + store.setDefault(SysdynDiagramPreferences.STOCK_USE_DEFAULT_FONT, true); + store.setDefault(SysdynDiagramPreferences.VALVE_USE_DEFAULT_FONT, true); + store.setDefault(SysdynDiagramPreferences.INPUT_USE_DEFAULT_FONT, false); + store.setDefault(SysdynDiagramPreferences.CLOUD_USE_DEFAULT_FONT, true); + store.setDefault(SysdynDiagramPreferences.MODULE_USE_DEFAULT_FONT, false); + + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertyExternalRead.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertyExternalRead.java new file mode 100644 index 00000000..6a950012 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertyExternalRead.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy + *******************************************************************************/ +package org.simantics.sysdyn.ui.preferences; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ParametrizedPrimitiveRead; +import org.simantics.db.procedure.Listener; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.utils.datastructures.Pair; + +/** + * + * @author Teemu Lempinen + * + */ +public class SysdynDiagramPropertyExternalRead extends ParametrizedPrimitiveRead, String> { + + private SysdynDiagramPropertySubscription subscription; + + public SysdynDiagramPropertyExternalRead(Pair input) { + super(input); + } + + @Override + public void register(ReadGraph graph, Listener procedure) { + subscription = new SysdynDiagramPropertySubscription(procedure, parameter.second); + SysdynDiagramPropertySupport.INSTANCE.register(subscription); + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + if(store.contains(parameter.second)) { + String preference = SysdynDiagramPreferences.getPreferenceName(parameter.second); + procedure.execute(store.getString(preference)); + } else + procedure.execute(null); + } + + @Override + public void unregistered() { + if(subscription != null) { + SysdynDiagramPropertySupport.INSTANCE.unregister(subscription); + subscription = null; + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySubscription.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySubscription.java new file mode 100644 index 00000000..286572cf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySubscription.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy + *******************************************************************************/ +package org.simantics.sysdyn.ui.preferences; + +import org.simantics.db.procedure.Listener; + +/** + * + * @author Teemu Lempinen + * + */ +public class SysdynDiagramPropertySubscription { + + private Listener listener; + private String propertyName; + + public SysdynDiagramPropertySubscription(Listener listener, String propertyName) { + this.listener = listener; + this.propertyName = propertyName; + } + + public Listener getListener() { + return listener; + } + + public String getPropertyName() { + return propertyName; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySupport.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySupport.java new file mode 100644 index 00000000..441b7fe5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySupport.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy + *******************************************************************************/ +package org.simantics.sysdyn.ui.preferences; + +import gnu.trove.set.hash.THashSet; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.simantics.sysdyn.ui.Activator; + +/** + * + * @author Teemu Lempinen + * + */ +public class SysdynDiagramPropertySupport { + + public static SysdynDiagramPropertySupport INSTANCE = new SysdynDiagramPropertySupport(); + + private Set diagramProperties; + private THashSet subscriptions = new THashSet(); + private SysdynDiagramPropertySubscription[] subscriptionSnapshot = null; + + private void add(String property) { + diagramProperties.add(property); + String useDefault = SysdynDiagramPreferences.getUseDefaultProperty(property); + if(useDefault != null) + diagramProperties.add(useDefault); + } + + public SysdynDiagramPropertySupport() { + diagramProperties = new HashSet(); + for(String property : SysdynDiagramPreferences.colorPreferenceNames.values()) + add(property); + + add(SysdynDiagramPreferences.DEFAULT_COLOR); + add(SysdynDiagramPreferences.DEFAULT_FONT); + + + for(String property : SysdynDiagramPreferences.fontPreferenceNames.values()) + add(property); + + Activator.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent event) { + String propertyName = event.getProperty(); + if(diagramProperties.contains(propertyName)){ + for(SysdynDiagramPropertySubscription subscription : getSubscriptionSnapshot()) { + String p = subscription.getPropertyName(); + String p2 = SysdynDiagramPreferences.getPreferenceName(p); + String dp = SysdynDiagramPreferences.getUseDefaultProperty(subscription.getPropertyName()); + if(propertyName.equals(p) || + propertyName.equals(p2) || + propertyName.equals(dp)) { + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + String result = store.getString(p2); + subscription.getListener().execute(result); + } + } + } + } + }); + } + + public void register(SysdynDiagramPropertySubscription subscription) { + assert subscription != null; + synchronized (subscriptions) { + subscriptions.add(subscription); + subscriptionSnapshot = null; + } + } + + public void unregister(SysdynDiagramPropertySubscription subscription) { + assert subscription != null; + synchronized (subscriptions) { + subscriptions.remove(subscription); + subscriptionSnapshot = null; + } + + } + + public SysdynDiagramPropertySubscription[] getSubscriptionSnapshot() { + SysdynDiagramPropertySubscription[] snapshot = subscriptionSnapshot; + if (snapshot == null) { + synchronized (subscriptions) { + snapshot = subscriptionSnapshot; + if (snapshot == null) { + snapshot = subscriptionSnapshot = + subscriptions.toArray(new SysdynDiagramPropertySubscription[subscriptions.size()]); + } + } + } + return snapshot; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynEquationPerspectiveFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynEquationPerspectiveFactory.java new file mode 100644 index 00000000..d1c2a243 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynEquationPerspectiveFactory.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.project; + +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class SysdynEquationPerspectiveFactory implements IPerspectiveFactory { + + @Override + public void createInitialLayout(IPageLayout layout) { + layout.setEditorAreaVisible(true); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynPerspectiveFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynPerspectiveFactory.java new file mode 100644 index 00000000..096dfc5a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynPerspectiveFactory.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.project; + +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class SysdynPerspectiveFactory implements IPerspectiveFactory { + + @Override + public void createInitialLayout(IPageLayout layout) { + layout.setEditorAreaVisible(true); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java new file mode 100644 index 00000000..41b8aaa6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.project; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import org.eclipse.core.runtime.Platform; +import org.simantics.databoard.accessor.Accessor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.RuntimeValuations; +import org.simantics.db.layer0.adapter.TrendVariable; +import org.simantics.db.layer0.service.ActivationManager; +import org.simantics.db.request.Read; +import org.simantics.db.service.GraphChangeListenerSupport; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.fmu.FMUControlJNI; +import org.simantics.issues.common.IssueUtils; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingUtils; +import org.simantics.modeling.services.CaseInsensitiveComponentNamingStrategy2; +import org.simantics.modeling.services.ComponentNamingStrategy; +import org.simantics.project.IProject; +import org.simantics.project.ProjectKeys; +import org.simantics.project.exception.ProjectException; +import org.simantics.project.features.AbstractProjectFeature; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.simulation.project.ExperimentManagerKeys; +import org.simantics.simulation.project.ExperimentManagerMode; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.editor.SysdynEditorNamingService; +import org.simantics.ui.workbench.IEditorNamingService; +import org.simantics.utils.FileUtils; + +public class SysdynProject extends AbstractProjectFeature { + private static final String DEFAULT_PERSPECTIVE = "org.simantics.sysdyn.ui.perspective"; + + @Override + public void configure() throws ProjectException { + final IProject project = getProject(); + final Session session = getSession(); + + getProjectElement().setHint(ProjectKeys.DEFAULT_PERSPECTIVE, DEFAULT_PERSPECTIVE); + + // Multi for simupedia use + getProjectElement().setHint(ExperimentManagerKeys.EXPERIMENT_MANAGER_MODE, ExperimentManagerMode.MULTI_EXPERIMENT); + // Single for normal workbench use +// getProjectElement().setHint(ExperimentManagerKeys.EXPERIMENT_MANAGER_MODE, ExperimentManagerMode.SINGLE_EXPERIMENT); + + getProjectElement().setHint(IEditorNamingService.KEY_EDITOR_NAMING_SERVICE, new SysdynEditorNamingService()); + + // Install naming strategy for model components. + GraphChangeListenerSupport changeSupport = session.peekService(GraphChangeListenerSupport.class); + if (changeSupport != null) { + getProjectElement().setHint(ComponentNamingStrategy.PROJECT_KEY, new CaseInsensitiveComponentNamingStrategy2(changeSupport, "%s%d")); + } + + try { + + Resource projectResource = project.get(); + + session.registerService(RuntimeValuations.class, new RuntimeValuations() { + + @Override + public boolean supports(String valuation) { + + IExperimentManager expMan = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = expMan.getExperiment(valuation); + + return experiment != null; + + } + + @Override + public Accessor getAccessor(String variableIdentityPrefix, String valuation, String suffix) { + return null; + } + + @Override + public TrendVariable getVariable(String variableIdentityPrefix, String valuation, String suffix) { + + return null; + + } + + }); + + + + ActivationManager activationManager = session.getService(ActivationManager.class); + if (activationManager != null) { + activationManager.activate(session, projectResource); + } + + + final VirtualGraphSupport support = session.getService(VirtualGraphSupport.class); + + support.getWorkspacePersistent("experiments"); + support.getWorkspacePersistent("profiles"); + support.getWorkspacePersistent("preferences"); + support.getWorkspacePersistent("issues"); + + // Before activating, make sure that the necessary activations have been installed into the project. + //final Set requiredActivations = new HashSet(); + //requiredActivations.add(APROS.IndexActivation); + + + + } catch (DatabaseException e) { + + throw new ProjectException(e); + + } + + + cleanProjectFolder(session, project.get()); + + // Clean all temporary files possibly left by previous sysdyn instances + clearFMUTempDirectory(); + + + // Issues + try { + session.syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + onActivated(graph, getProject()); + } + }); + } catch (DatabaseException e) { + throw new ProjectException(e); + } + } + + /** + * Clears fmu temp directory. This directory hosts + * fmu files for game experiments. In normal situations + * experiments clean up their temp files, but for example + * a system crash may leave files to temp directory. + */ + private void clearFMUTempDirectory() { + // Find commone "TEMP/fmu" directory + File commonDir = new File(FMUControlJNI.TEMP_FMU_COMMON_DIRECTORY); + if(commonDir != null && commonDir.isDirectory()) { + + // List all files and directories in "TEMP/fmu" + for(File child : commonDir.listFiles()) { + if(child.isDirectory()) { + // If directory is found, try to get the lock file in it + File lock = new File(child, FMUControlJNI.LOCK_FILE_NAME); + if(!lock.isFile() || lock.delete()) { + // If lock is not found, or the lock can be delted, the directory is not locked. -> Delete the rest of the directory + try { + FileUtils.deleteAll(child); + child.delete(); + } catch (IOException e) { + + } + } + } + } + } + } + + @Override + public void deconfigure() throws ProjectException { + + ModelingUtils.untrackDependencies(getSession()); + + getProjectElement().removeHint(ComponentNamingStrategy.PROJECT_KEY); + } + + public void cleanProjectFolder(Session session, final Resource projectResource) throws ProjectException { + String projectName = null; + final HashMap resultPaths = new HashMap(); + try { + projectName = session.syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource model : graph.getObjects(projectResource, l0.ConsistsOf)) { + if(graph.isInstanceOf(model, sr.SysdynModel)){ + for(Resource experiment : graph.getObjects(model, l0.ConsistsOf)) { + if(graph.isInstanceOf(experiment, SIMU.Experiment)) { + for(Resource result : graph.getObjects(experiment, sr.Experiment_result)) { + if(!graph.isInstanceOf(result, sr.HistoryDataset)) { + String resultFile = (String)graph.getPossibleRelatedValue(result, sr.Result_resultFile); + if(result != null) resultPaths.put(resultFile, result); + } + } + for(Resource resultSet : graph.getObjects(experiment, sr.Experiment_resultSet)) { + for(Resource result : graph.getObjects(resultSet, sr.Experiment_result)) { + if(!graph.isInstanceOf(result, sr.HistoryDataset)) { + String resultFile = (String)graph.getPossibleRelatedValue(result, sr.Result_resultFile); + if(result != null) resultPaths.put(resultFile, result); + } + } + } + } + } + } + } + return graph.getPossibleRelatedValue(projectResource, l0.HasName); + + } + }); + } catch (DatabaseException e) { + throw new ProjectException(e); + } + + if(projectName != null) { + File root = new File(Platform.getLocation().toOSString(), "www.simantics.org"); + if(!root.isDirectory()) return; + File projectRoot = new File(root, projectName); + if(!projectRoot.isDirectory()) return; + File[] files = projectRoot.listFiles(); + + for(File file : files) { + if(resultPaths.get(file.getAbsolutePath()) == null) { + file.delete(); + } else { + resultPaths.remove(file.getAbsolutePath()); + } + } + + if (!resultPaths.keySet().isEmpty()) { + session.asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + for(String key : resultPaths.keySet()) { + Resource result = resultPaths.get(key); + graph.deny(result, l0.PartOf); + graph.deny(result, graph.getInverse(SysdynResource.getInstance(graph).Experiment_result)); + } + } + }) ; + } + } + } + + public void onActivated(final ReadGraph graph, final IProject project) throws DatabaseException { + +// GraphChangeListenerSupport changeSupport = graph.getService(GraphChangeListenerSupport.class); +// changeSupport.addMetadataListener(new GenericChangeListener() { +// +// @Override +// public void onEvent(ReadGraph graph, DependencyChanges event) throws DatabaseException { +// +// WriteGraph w = (WriteGraph)graph; +// w.addMetadata(event); +// +// } +// +// }); + + IssueUtils.listenActiveProjectIssueSources(graph, project.get()); + + ModelingUtils.trackDependencies(graph); + + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynTrendPerspectiveFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynTrendPerspectiveFactory.java new file mode 100644 index 00000000..cf2eb01c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynTrendPerspectiveFactory.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.project; + +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class SysdynTrendPerspectiveFactory implements IPerspectiveFactory { + + @Override + public void createInitialLayout(IPageLayout layout) { + layout.setEditorAreaVisible(true); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/AdjustableTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/AdjustableTab.java new file mode 100644 index 00000000..b0ad402b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/AdjustableTab.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2007, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.selectionview.StandardProperties; + +/** + * Tab adjusting the layout depending on its dimensions. + * @author Tuomas Miettinen + * + */ +public abstract class AdjustableTab extends LabelPropertyTabContributor { + + private Composite spp; + private ControlListener controlListener; + private static final int WIDE_SCREEN_WIDTH = 1100; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport _support) { + // Get size of the available area. + spp = body; + do { + spp = spp.getParent(); + } while (!(spp instanceof StandardProperties)); + + // Add listener to change the layout when the composite resizes. + spp.addControlListener(controlListener = new ControlListener(){ + + @Override + public void controlMoved(ControlEvent e) {} + + @Override + public void controlResized(ControlEvent e) { + createLayout(); + } + }); + + // Create the controls and their initial layout. + createAndAddControls(body, site, context, _support); + createLayout(); + } + + /** + * Create controls and add them to the tab. + * @param body the composite where the controls are added. + * @param site + * @param context + * @param _support + */ + protected abstract void createAndAddControls(Composite body, IWorkbenchSite site, + ISessionContext context, WidgetSupport _support); + + /** + * Create layout for controls. + */ + protected void createLayout() { + Point size = spp.getSize(); + if (size.x > size.y) { + createControlLayoutHorizontal((size.x > WIDE_SCREEN_WIDTH)); + } else { + createControlLayoutVertical(); + } + } + + /** + * Create vertical layout for controls. + */ + protected abstract void createControlLayoutVertical(); + + /** + * Create horizontal layout for controls. + * @param wideScreen true iff the control is wider than WIDE_SCREEN_WIDTH + */ + protected abstract void createControlLayoutHorizontal(boolean wideScreen); + + @Override + public void dispose() { + if(controlListener != null && spp != null) + spp.removeControlListener(controlListener); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayDependencyTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayDependencyTab.java new file mode 100644 index 00000000..e7991a22 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayDependencyTab.java @@ -0,0 +1,347 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.Scale; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.util.ObjectUtils; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements.connections.DependencyEdgeClass; +import org.simantics.sysdyn.ui.elements.connections.DependencyNode; +import org.simantics.sysdyn.ui.properties.widgets.ArrowHeadWidget; +import org.simantics.sysdyn.ui.properties.widgets.DelayMarkWidget; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.datastructures.Triple; + +/** + * Tab for multiple dependencies. + * @author Tuomas Miettinen + * + */ +public class ArrayDependencyTab extends LabelPropertyTabContributor { + + Button none, plus, minus, other, inside, outside; + TrackedText polarityText, polarityLocationText; + private DelayMarkWidget delayMark; + private ArrowHeadWidget arrowhead; + private Scale lineThicknessScale; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + /* Add a dummy button at the begin to suck in the nonsense selection events that + * the first radio button in the group of ALL the radio buttons receives when no + * radio is selected and then one is selected in other group than where the first + * radio button lies. + */ + Group hiddenDefaultbuttonGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().exclude(true).applyTo(hiddenDefaultbuttonGroup); + GridLayoutFactory.fillDefaults().applyTo(hiddenDefaultbuttonGroup); + new Button(hiddenDefaultbuttonGroup, support, SWT.RADIO); + + Group polarityGroup = new Group(composite, SWT.NONE); + polarityGroup.setText("Polarity"); + GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityGroup); + GridLayoutFactory.fillDefaults().numColumns(5).applyTo(polarityGroup); + + none = new Button(polarityGroup, support, SWT.RADIO); + none.setText("None"); + none.setSelectionFactory(new PolarityRadioSelectionFactory("")); + none.addSelectionListener(new PolaritySelectionListener(context, "")); + + plus = new Button(polarityGroup, support, SWT.RADIO); + plus.setText("+"); + plus.setSelectionFactory(new PolarityRadioSelectionFactory("+")); + plus.addSelectionListener(new PolaritySelectionListener(context, "+")); + + minus = new Button(polarityGroup, support, SWT.RADIO); + minus.setText("-"); + minus.setSelectionFactory(new PolarityRadioSelectionFactory("-")); + minus.addSelectionListener(new PolaritySelectionListener(context, "-")); + + other = new Button(polarityGroup, support, SWT.RADIO); + other.setText("other"); + other.setSelectionFactory(new OtherPolaritySelectionFactory(new String[] {null, "+", "-", ""})); + + polarityText = new TrackedText(polarityGroup, support, SWT.BORDER); + polarityText.setTextFactory(new OtherPolarityStringPropertyFactory()); + polarityText.addModifyListener(new OtherPolarityStringPropertyModifier()); + GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityText.getWidget()); + + Group locationGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(locationGroup); + GridLayoutFactory.fillDefaults().applyTo(locationGroup); + locationGroup.setText("Location"); + + inside = new Button(locationGroup, support, SWT.RADIO); + inside.setText("Inside"); + inside.setSelectionFactory(new PolarityLocationRadioSelectionFactory(DependencyNode.INSIDE)); + inside.addSelectionListener(new PolarityLocationSelectionListener(context, DependencyNode.INSIDE)); + + outside = new Button(locationGroup, support, SWT.RADIO); + outside.setText("Outside"); + outside.setSelectionFactory(new PolarityLocationRadioSelectionFactory(DependencyNode.OUTSIDE)); + outside.addSelectionListener(new PolarityLocationSelectionListener(context, DependencyNode.OUTSIDE)); + + Composite misc = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(misc); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(misc); + + arrowhead = new ArrowHeadWidget(misc, support, SWT.NULL); + GridDataFactory.fillDefaults().applyTo(arrowhead.getWidget()); + delayMark = new DelayMarkWidget(misc, support, SWT.NULL); + GridDataFactory.fillDefaults().applyTo(delayMark.getWidget()); + + Group lineThicknessGroup = new Group(misc, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(lineThicknessGroup); + GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup); + lineThicknessGroup.setText("Line thickness:"); + lineThicknessScale = new Scale(lineThicknessGroup, support, SWT.HORIZONTAL); + lineThicknessScale.getWidget().setMinimum(1); + lineThicknessScale.getWidget().setMaximum(15); + lineThicknessScale.getWidget().setPageIncrement(1); + lineThicknessScale.getWidget().setIncrement(1); + lineThicknessScale.setSelectionFactory(new LineThicknessRadioSelectionFactory()); + lineThicknessScale.addSelectionListener(new LineThicknessSelectionListener(context, lineThicknessScale)); + } + + class LineThicknessSelectionListener extends SelectionListenerImpl> { + Scale scale; + private int selection; + + public LineThicknessSelectionListener(ISessionContext context, Scale scale) { + super(context); + this.scale = scale; + } + + @Override + public void beforeApply() { + this.selection = scale.getWidget().getSelection(); + } + + @Override + public void apply(WriteGraph graph, ArrayList connectionElements) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + float width = ((float)selection) / 10.0f; + for (Resource r : connectionElements) + graph.claimLiteral(r, sr.DependencyConnection_strokeWidth, width); + } + + } + + class LineThicknessRadioSelectionFactory extends ReadFactoryImpl, Integer> { + + public LineThicknessRadioSelectionFactory() { + } + + @Override + public Integer perform(ReadGraph graph, ArrayList dependencyConnection) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if (dependencyConnection.size() > 0) { + Float width = graph.getPossibleRelatedValue(dependencyConnection.get(0), sr.DependencyConnection_strokeWidth, Bindings.FLOAT); + if(width != null) { + return (int)Math.round(width * 10); + } + } + return (int)Math.round(DependencyEdgeClass.DEFAULT_STROKE_WIDTH * 10); + } + } + + class OtherPolarityStringPropertyFactory extends ReadFactoryImpl, String> { + + private final String propertyURI; + + public OtherPolarityStringPropertyFactory() { + this.propertyURI = SysdynResource.URIs.DependencyConnection_polarity; + } + + @SuppressWarnings("unchecked") + @Override + public Object getIdentity(Object inputContents) { + return new Triple, String, Object>((ArrayList) inputContents, propertyURI, getClass()); + } + + @Override + public String perform(ReadGraph graph, ArrayList resources) throws DatabaseException { + String value = graph.getPossibleRelatedValue(resources.get(0), graph.getResource(propertyURI));; + if (value == null) + return ""; + for (Resource r : resources) { + String s = graph.getPossibleRelatedValue(r, graph.getResource(propertyURI)); + if (!value.equals(s)) + return ""; + } + return value; + } + } + + class OtherPolarityStringPropertyModifier extends TextModifyListenerImpl> { + + final private String propertyURI; + + public OtherPolarityStringPropertyModifier() { + this.propertyURI = SysdynResource.URIs.DependencyConnection_polarity; + } + + @Override + public void applyText(WriteGraph graph, ArrayList resources, String text) throws DatabaseException { + for (Resource r : resources) + graph.claimLiteral(r, graph.getResource(propertyURI), text, Bindings.STRING); + } + + } + + class PolarityLocationSelectionListener extends SelectionListenerImpl> { + private String location; + + public PolarityLocationSelectionListener(ISessionContext context, String location) { + super(context); + this.location = location; + } + + @Override + public void apply(WriteGraph graph, ArrayList connectionElements) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for (Resource r : connectionElements) + graph.claimLiteral(r, sr.DependencyConnection_polarityLocation, location); + } + + } + + class PolarityLocationRadioSelectionFactory extends ReadFactoryImpl, Boolean> { + private String location; + + public PolarityLocationRadioSelectionFactory(String location) { + this.location = location; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple>(inputContents, location, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, ArrayList dependencyConnections) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for (Resource r : dependencyConnections) { + String location = graph.getPossibleRelatedValue(r, sr.DependencyConnection_polarityLocation, Bindings.STRING); + if (DependencyNode.OUTSIDE.equals(this.location)) { + if (ObjectUtils.objectEquals(this.location, location)) + continue; + } else { + if (location == null) { + continue; + } else { + if (ObjectUtils.objectEquals(this.location, location)) + continue; + } + } + return false; + } + return true; + } + } + + class PolaritySelectionListener extends SelectionListenerImpl> { + private String polarity; + + public PolaritySelectionListener(ISessionContext context, String polarity) { + super(context); + this.polarity = polarity; + } + + @Override + public void apply(WriteGraph graph, ArrayList connectionElements) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for (Resource r : connectionElements) + graph.claimLiteral(r, sr.DependencyConnection_polarity, polarity.trim()); + } + + } + + class PolarityRadioSelectionFactory extends ReadFactoryImpl, Boolean> { + private String polarity; + + public PolarityRadioSelectionFactory(String polarity) { + this.polarity = polarity; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple>(inputContents, polarity, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, ArrayList dependencyConnections) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for (Resource r : dependencyConnections) { + String polarity = graph.getPossibleRelatedValue(r, sr.DependencyConnection_polarity, Bindings.STRING); + if (polarity == null && this.polarity.equals("")) + continue; + if (ObjectUtils.objectEquals(polarity, this.polarity)) + continue; + return false; + } + return true; + } + } + + class OtherPolaritySelectionFactory extends ReadFactoryImpl, Boolean> { + + String[] limits; + + public OtherPolaritySelectionFactory(String[] limits) { + this.limits = limits; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Pair>(inputContents, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, ArrayList dependencyConnections) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for (Resource r : dependencyConnections) { + String polarity = graph.getPossibleRelatedValue(r, sr.DependencyConnection_polarity, Bindings.STRING); + for(String s : limits) { + if(ObjectUtils.objectEquals(polarity, s)) + return false; + } + } + return true; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayFlowTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayFlowTab.java new file mode 100644 index 00000000..ef0403f6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayFlowTab.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Scale; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements.connections.FlowConnectionStyle; + +/** + * Tab for multiple dependencies. + * @author Tuomas Miettinen + * + */ +public class ArrayFlowTab extends LabelPropertyTabContributor { + + private Scale lineThicknessScale; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(1).applyTo(composite); + + Group lineThicknessGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(lineThicknessGroup); + GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup); + lineThicknessGroup.setText("Flow thickness:"); + lineThicknessScale = new Scale(lineThicknessGroup, support, SWT.HORIZONTAL); + lineThicknessScale.getWidget().setMinimum(1); + lineThicknessScale.getWidget().setMaximum(9); + lineThicknessScale.getWidget().setPageIncrement(1); + lineThicknessScale.getWidget().setIncrement(1); + lineThicknessScale.setSelectionFactory(new LineThicknessRadioSelectionFactory()); + lineThicknessScale.addSelectionListener(new LineThicknessSelectionListener(context, lineThicknessScale)); + } + + class LineThicknessSelectionListener extends SelectionListenerImpl> { + Scale scale; + private int selection; + + public LineThicknessSelectionListener(ISessionContext context, Scale scale) { + super(context); + this.scale = scale; + } + + @Override + public void beforeApply() { + this.selection = scale.getWidget().getSelection(); + } + + @Override + public void apply(WriteGraph graph, ArrayList connectionElements) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + float width = ((float)selection) / 3.0f; + for (Resource r : connectionElements) + graph.claimLiteral(r, sr.FlowConnection_width, width); + } + + } + + class LineThicknessRadioSelectionFactory extends ReadFactoryImpl, Integer> { + + public LineThicknessRadioSelectionFactory() { + } + + @Override + public Integer perform(ReadGraph graph, ArrayList flowConnection) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if (flowConnection.size() > 0) { + Float width = graph.getPossibleRelatedValue(flowConnection.get(0), sr.FlowConnection_width, Bindings.FLOAT); + if(width != null) { + return (int)Math.round(width * 3); + } + } + return (int)Math.round(FlowConnectionStyle.DEFAULT_LINE_WIDTH * 3); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayIndexesTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayIndexesTab.java new file mode 100644 index 00000000..2b622ac8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayIndexesTab.java @@ -0,0 +1,409 @@ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.AdaptableHintContext; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.ResourceArray; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; +import org.simantics.utils.RunnableWithObject; +import org.simantics.utils.datastructures.ArrayMap; + +public class ArrayIndexesTab extends LabelPropertyTabContributor implements Widget{ + + GraphExplorerComposite availableEnumerationsExplorer; + GraphExplorerComposite usedEnumerationsExplorer; + private WidgetSupportImpl buttonSupport; + private org.simantics.browsing.ui.swt.widgets.Label usedEnumerationsLabel; + + @Override + public void createControls(Composite body, IWorkbenchSite site, + ISessionContext context, WidgetSupport support) { + support.register(this); + + buttonSupport = new WidgetSupportImpl(); + + GridLayoutFactory.fillDefaults().numColumns(4).applyTo(body); + + + Composite available = new Composite(body, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(available); + GridDataFactory.fillDefaults().grab(true, true).applyTo(available); + Label label = new Label(available, SWT.None); + label.setText("Available Enumerations"); + availableEnumerationsExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, available, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI); + + availableEnumerationsExplorer + .setBrowseContexts(SysdynResource.URIs.AvailableVariableIndexes); + availableEnumerationsExplorer.setColumns(ColumnKeys.ENUMERATION_TABLE_COLUMNS); + availableEnumerationsExplorer.setInputSource(new SingleSelectionInputSource( + ResourceArray.class)); + + availableEnumerationsExplorer.finish(); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + availableEnumerationsExplorer); + + Control c = availableEnumerationsExplorer.getExplorerControl(); + if (c instanceof Tree) + ((Tree) c).setLinesVisible(true); + + + Button add = new Button(body, buttonSupport, SWT.NONE); + add.setText(" -> "); + + add.addSelectionListener(new SelectionListenerImpl(context) { + + List enumerationResources; + + @Override + public void beforeApply() { + enumerationResources = getSelectedResources(availableEnumerationsExplorer); + } + + @Override + public void apply(WriteGraph graph, ResourceArray input) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource r : input.resources) { + Resource arrayIndexes = graph.getPossibleObject(r, sr.Variable_arrayIndexesList); + if(arrayIndexes == null) { + graph.claim(r, sr.Variable_arrayIndexesList, ListUtils.create(graph, enumerationResources)); + } else { + ArrayList filtered = new ArrayList(); + for(Resource enumeration : enumerationResources) { + if(ListUtils.getNode(graph, arrayIndexes, enumeration) == null) + filtered.add(enumeration); + } + ListUtils.insertBack(graph, arrayIndexes, filtered); + } + } + } + }); + + Composite used = new Composite(body, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(used); + GridDataFactory.fillDefaults().grab(true, true).applyTo(used); + usedEnumerationsLabel = new org.simantics.browsing.ui.swt.widgets.Label(used, buttonSupport, SWT.None); + usedEnumerationsLabel.setTextFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, ResourceArray input) throws DatabaseException { + if(input.size() < 2) + return "Used Enumerations"; + else { + StringBuilder sb = new StringBuilder(); + sb.append("Enumerations in: "); + boolean first = true; + for(Resource r : input) { + if(!first) + sb.append(", "); + first = false; + + String name = NameUtils.getSafeName(graph, r); + sb.append(name); + } + return sb.toString(); + } + } + + }); + + usedEnumerationsExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, used, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI); + + usedEnumerationsExplorer + .setBrowseContexts(SysdynResource.URIs.UsedVariableIndexes); + usedEnumerationsExplorer.setColumns(ColumnKeys.ENUMERATION_TABLE_COLUMNS); + usedEnumerationsExplorer.setInputSource(new SingleSelectionInputSource( + ResourceArray.class)); + + usedEnumerationsExplorer.finish(); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + usedEnumerationsExplorer); + + Control c2 = usedEnumerationsExplorer.getExplorerControl(); + if (c2 instanceof Tree) + ((Tree) c2).setLinesVisible(true); + + Composite buttons = new Composite(body, SWT.None); + GridLayoutFactory.fillDefaults().applyTo(buttons); + + Button up = new Button(buttons, buttonSupport, SWT.NONE); + up.setText("Up"); + up.addSelectionListener(new SelectionListenerImpl(context) { + + List selectedIndexes; + + @Override + public void beforeApply() { + selectedIndexes = getSelectedIndexes(usedEnumerationsExplorer); + } + + @Override + public void apply(WriteGraph graph, ResourceArray input) + throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + for(Resource variable : input) { + Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList); + if(arrayIndexes != null) { + List enumerations = ListUtils.toList(graph, arrayIndexes); + List toBeMoved = new ArrayList(); + for(Integer index : selectedIndexes) { + if(index < enumerations.size()) { + Resource enumeration = enumerations.get(index); + toBeMoved.add(enumeration); + } + + } + + for(Resource enumeration : toBeMoved) { + Resource node = ListUtils.getNode(graph, arrayIndexes, enumeration); + Resource prev = graph.getSingleObject(node, L0.List_Previous); + if(!arrayIndexes.equals(prev) && !toBeMoved.contains(graph.getPossibleObject(prev, L0.List_Element))) { + ListUtils.swapWithPrevious(graph, arrayIndexes, enumeration); + } + } + } + } + + // Move selection + usedEnumerationsExplorer.getDisplay().asyncExec(new RunnableWithObject(usedEnumerationsExplorer, selectedIndexes) { + @Override + public void run() { + Control c = ((GraphExplorerComposite)object).getExplorerControl(); + if(c != null && c instanceof Tree && object2 instanceof List) { + Tree tree = (Tree) c; + tree.deselectAll(); + + @SuppressWarnings("unchecked") + List list = (List) object2; + Set selection = new HashSet(); + for(Integer i : list) { + TreeItem item = null; + if(i - 1 >= 0) + item = tree.getItem(i - 1); + if(item == null || selection.contains(item)) + item = tree.getItem(i); + if(item != null && !selection.contains(item)) + selection.add(item); + } + tree.setSelection(selection.toArray(new TreeItem[selection.size()])); + } + } + }); + } + }); + + Button down = new Button(buttons, buttonSupport, SWT.NONE); + down.setText("Down"); + down.addSelectionListener(new SelectionListenerImpl(context) { + + List selectedIndexes; + + @Override + public void beforeApply() { + selectedIndexes = getSelectedIndexes(usedEnumerationsExplorer); + } + + + @Override + public void apply(WriteGraph graph, ResourceArray input) + throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + for(Resource variable : input) { + Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList); + if(arrayIndexes != null) { + List enumerations = ListUtils.toList(graph, arrayIndexes); + List toBeMoved = new ArrayList(); + for(Integer index : selectedIndexes) { + if(index < enumerations.size()) { + Resource enumeration = enumerations.get(index); + toBeMoved.add(0, enumeration); // Make an inverted list. + } + + } + + for(Resource enumeration : toBeMoved) { + Resource node = ListUtils.getNode(graph, arrayIndexes, enumeration); + Resource next = graph.getSingleObject(node, L0.List_Next); + if(!arrayIndexes.equals(next) && !toBeMoved.contains(graph.getPossibleObject(next, L0.List_Element))) { + ListUtils.swapWithNext(graph, arrayIndexes, enumeration); + } + } + } + } + + // Move selection + usedEnumerationsExplorer.getDisplay().asyncExec(new RunnableWithObject(usedEnumerationsExplorer, selectedIndexes) { + @Override + public void run() { + Control c = ((GraphExplorerComposite)object).getExplorerControl(); + if(c != null && c instanceof Tree && object2 instanceof List) { + Tree tree = (Tree) c; + tree.deselectAll(); + + @SuppressWarnings("unchecked") + List list = (List) object2; + Set selection = new HashSet(); + Collections.reverse(list); + for(Integer i : list) { + TreeItem item = null; + if(i + 1 < tree.getItemCount()) + item = tree.getItem(i + 1); + if(item == null || selection.contains(item)) + item = tree.getItem(i); + if(item != null && !selection.contains(item)) + selection.add(item); + } + tree.setSelection(selection.toArray(new TreeItem[selection.size()])); + } + } + }); + } + }); + + + Button remove = new Button(buttons, buttonSupport, SWT.NONE); + remove.setText("Remove"); + remove.addSelectionListener(new SelectionListenerImpl(context) { + + List selectedIndexes; + + @Override + public void beforeApply() { + selectedIndexes = getSelectedIndexes(usedEnumerationsExplorer); + } + + @Override + public void apply(WriteGraph graph, ResourceArray input) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + for(Resource variable : input) { + Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList); + if(arrayIndexes != null) { + List enumerations = ListUtils.toList(graph, arrayIndexes); + List toBeRemoved = new ArrayList(); + for(Integer index : selectedIndexes) { + if(index < enumerations.size()) { + Resource enumeration = enumerations.get(index); + toBeRemoved.add(enumeration); + } + + } + + for(Resource enumeration : toBeRemoved) + ListUtils.removeElement(graph, arrayIndexes, enumeration); + } + } + } + }); + } + + + private List getSelectedResources(GraphExplorerComposite explorer) { + List result = new ArrayList(); + + ISelection selection = ((ISelectionProvider) explorer + .getAdapter(ISelectionProvider.class)).getSelection(); + if (selection == null) + return result; + IStructuredSelection iss = (IStructuredSelection) selection; + @SuppressWarnings("unchecked") + List selections = iss.toList(); + for(AdaptableHintContext ahc : selections) { + Resource resource = (Resource) ahc.getAdapter(Resource.class); + result.add(resource); + } + return result; + } + + private List getSelectedIndexes(final GraphExplorerComposite explorer) { + final List result = new ArrayList(); + + explorer.getDisplay().syncExec(new Runnable() { + + @Override + public void run() { + Control c = explorer.getExplorerControl(); + if (c instanceof Tree) { + Tree tree = (Tree) c; + TreeItem[] selection = tree.getSelection(); + + for(TreeItem item : selection) { + result.add(tree.indexOf(item)); + } + } + } + }); + + return result; + } + + + @Override + public void setInput(ISessionContext context, Object input) { + + if(input != null && input instanceof IStructuredSelection) { + Object first = ((IStructuredSelection)input).getFirstElement(); + ResourceArray resourceArray = null; + if(first instanceof Resource) + resourceArray = new ResourceArray((Resource)first); + else if( first instanceof Collection) + resourceArray = new ResourceArray(((Collection)first).toArray(new Resource[((Collection)first).size()])); + + if(resourceArray != null) { + StructuredSelection selection = new StructuredSelection(resourceArray); + availableEnumerationsExplorer.setInput(context, selection); + usedEnumerationsExplorer.setInput(context, selection); + buttonSupport.fireInput(context, selection); + } + } + + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/CommentTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/CommentTab.java new file mode 100644 index 00000000..c4bf7b12 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/CommentTab.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.utils.datastructures.Callback; + +/** + * Tab for editing diagram comments + * + * @author Teemu Lempinen + * + */ +public class CommentTab extends LabelPropertyTabContributor { + + @Override + public void updatePartName(ISelection forSelection, final Callback updateCallback) { + updateCallback.run("Comment"); + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + ScrolledComposite sc = new ScrolledComposite(body, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().applyTo(sc); + + Composite composite = new Composite(sc, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite); + + // FIXME: Currently needs Ctrl+Enter to accept changes. Change so that the syntax is common in all sysdyn + TrackedText text = new TrackedText(composite, support, SWT.BORDER | SWT.WRAP | SWT.MULTI); + text.setTextFactory(new StringPropertyFactory(DiagramResource.URIs.HasText)); + text.addModifyListener(new StringPropertyModifier(context, DiagramResource.URIs.HasText)); + + GridDataFactory.fillDefaults().grab(true, true).hint(200, SWT.DEFAULT).applyTo(text.getWidget()); + + // Scrolled composite settings + sc.setContent(composite); + sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ConfigurationTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ConfigurationTab.java new file mode 100644 index 00000000..1b6eed62 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ConfigurationTab.java @@ -0,0 +1,371 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.issues.ontology.IssueResource; +import org.simantics.layer0.Layer0; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.EquivalentUnitsWidget; +import org.simantics.sysdyn.ui.properties.widgets.factories.ComboStringPropertyModifier; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; +import org.simantics.sysdyn.ui.properties.widgets.factories.ModelNameInputValidator; + +/** + * Tab displaying configuration properties. Displayed for model and configuration. + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ConfigurationTab extends AdjustableTab { + + private ScrolledComposite sc; + private Composite composite; + private Label nameLabel, startTimeLabel, stopTimeLabel, stepLengthLabel, + outputIntervalLabel, methodLabel, toleranceLabel, variableFilterLabel; + private TrackedText name, startTime, stopTime, stepLength, outputInterval, tolerance, variableFilter; + private TrackedCombo method, timeUnit; + private Button validateUnits; + private EquivalentUnitsWidget equivalentUnitsWidget; + /** + * Modifier for modifying model labels + * @author Teemu Lempinen + * + */ + private class ModelLabelModifier extends TextModifyListenerImpl { + + public ModelLabelModifier(ISessionContext context, String propertyURI) { + } + + @Override + public void applyText(WriteGraph graph, Resource issue, String text) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + graph.claimLiteral(issue, l0.HasLabel, text); + String safeName = NameUtils.findFreshName(graph, text, graph.getSingleObject(issue, l0.PartOf), l0.ConsistsOf, "%s%d"); + graph.claimLiteral(issue, l0.HasName, safeName); + } + + } + + @Override + protected void createAndAddControls(Composite body, IWorkbenchSite site, + ISessionContext context, WidgetSupport support) { + sc = new ScrolledComposite(body, SWT.H_SCROLL | SWT.V_SCROLL); + composite = new Composite(sc, SWT.NONE); + sc.setContent(composite); + + nameLabel = new Label(composite, SWT.NONE); + nameLabel.setText("Name"); + + name = new TrackedText(composite, support, SWT.BORDER); + name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel)); + name.addModifyListener(new ModelLabelModifier(context, Layer0.URIs.HasLabel)); + name.setInputValidator(new ModelNameInputValidator(support)); + + startTimeLabel = new Label(composite, SWT.NONE); + startTimeLabel.setText("Start time"); + + startTime = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT); + startTime.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_startTime)); + startTime.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_startTime)); + startTime.setInputValidator(new DoubleValidator()); + + stopTimeLabel = new Label(composite, SWT.NONE); + stopTimeLabel.setText("Stop time"); + + stopTime = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT); + stopTime.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_stopTime)); + stopTime.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_stopTime)); + stopTime.setInputValidator(new DoubleValidator()); + + stepLengthLabel = new Label(composite, SWT.NONE); + stepLengthLabel.setText("Step length\n(empty = default)"); + + stepLength = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT); + stepLength.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_simulationStepLength)); + stepLength.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_simulationStepLength)); + stepLength.setInputValidator(new DoubleValidator()); + + outputIntervalLabel = new Label(composite, SWT.NONE); + outputIntervalLabel.setText("Output interval\n(empty = all steps)"); + outputIntervalLabel.setAlignment(SWT.RIGHT); + + outputInterval = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT); + outputInterval.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_outputInterval)); + outputInterval.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_outputInterval)); + outputInterval.setInputValidator(new DoubleValidator()); + + methodLabel = new Label(composite, SWT.NONE); + methodLabel.setText("Method"); + + method = new TrackedCombo(composite, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); + method.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, final Resource input) throws DatabaseException { + + Map map = new HashMap(); + map.put("euler", "euler"); + map.put("rungekutta", "rungekutta"); + map.put("dassl", "dassl"); + map.put("dassl2", "dassl2"); + map.put("inline-euler", "inline-euler"); + map.put("inline-rungekutta", "inline-rungekutta"); + return map; + } + }); + + method.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + String s = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).SysdynModel_solver); + return s != null ? s : ""; + } + }); + + method.addModifyListener(new ComboStringPropertyModifier() { + + @Override + public void applyText(WriteGraph graph, Resource input, String text) + throws DatabaseException { + graph.claimLiteral(input, SysdynResource.getInstance(graph).SysdynModel_solver, text); + } + }); + + validateUnits = new Button(composite, support, SWT.CHECK); + validateUnits.setText("Validate units"); + validateUnits.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public Boolean perform(ReadGraph graph, Resource model) throws DatabaseException { + Resource unitIssueSource = graph.syncRequest( + new PossibleObjectWithType(model, + Layer0X.getInstance(graph).Activates, + SysdynResource.getInstance(graph).Validations_Units_UnitIssueSource)); + if(unitIssueSource == null) + return false; + + Boolean result = graph.getPossibleRelatedValue(unitIssueSource, IssueResource.getInstance(graph).IssueSource_active, Bindings.BOOLEAN); + return Boolean.TRUE.equals(result); + } + }); + + validateUnits.addSelectionListener(new SelectionListenerImpl(context){ + + @Override + public void apply(WriteGraph graph, Resource model) throws DatabaseException { + Resource unitIssueSource = graph.syncRequest( + new PossibleObjectWithType(model, + Layer0X.getInstance(graph).Activates, + SysdynResource.getInstance(graph).Validations_Units_UnitIssueSource)); + IssueResource ISSUE = IssueResource.getInstance(graph); + Boolean result = graph.getPossibleRelatedValue(unitIssueSource, ISSUE.IssueSource_active, Bindings.BOOLEAN); + if(result == null) + result = false; + graph.claimLiteral(unitIssueSource, ISSUE.IssueSource_active, Boolean.FALSE.equals(result)); + + // Enable or disable the Unit Equivalents button based if + // unit validation is enabled or not. + final boolean enabled = !result; + if (!equivalentUnitsWidget.getWidget().isDisposed()) + equivalentUnitsWidget.getWidget().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(!equivalentUnitsWidget.getWidget().isDisposed()) + equivalentUnitsWidget.getWidget().setEnabled(enabled); + } + }); + + } + + }); + + timeUnit = new TrackedCombo(composite, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); + timeUnit.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, final Resource input) throws DatabaseException { + + Map map = new HashMap(); + map.put("year", "year"); + map.put("month", "month"); + map.put("day", "day"); + map.put("hour", "hour"); + map.put("min", "min"); + map.put("s", "s"); + return map; + } + }); + + timeUnit.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + String s = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).SysdynModel_timeUnit); + return s != null ? s : "month"; + } + }); + + timeUnit.addModifyListener(new ComboStringPropertyModifier() { + + @Override + public void applyText(WriteGraph graph, Resource input, String text) + throws DatabaseException { + graph.claimLiteral(input, SysdynResource.getInstance(graph).SysdynModel_timeUnit, text); + } + }); + + equivalentUnitsWidget = new EquivalentUnitsWidget(composite, support, SWT.NONE); + + toleranceLabel = new Label(composite, SWT.NONE); + toleranceLabel.setText("Tolerance"); + + tolerance = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT); + tolerance.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_tolerance)); + tolerance.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_tolerance)); + tolerance.setInputValidator(new DoubleValidator()); + + variableFilterLabel = new Label(composite, SWT.NONE); + variableFilterLabel.setText("Variable filter"); + variableFilterLabel.setToolTipText("Variable filter as regular expression.\n" + + "To include variables Auxiliary1, Auxiliary2 and Auxiliary3: \n" + + "Auxiliary[1-3]\n" + + "or\n" + + "Auxiliary1|Auxiliary2|Auxiliary3"); + + variableFilter = new TrackedText(composite, support, SWT.BORDER); + variableFilter.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.SysdynModel_variableFilter, "")); + variableFilter.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.SysdynModel_variableFilter)); + variableFilter.getWidget().setToolTipText("Variable filter as regular expression.\n" + + "To include variables Auxiliary1, Auxiliary2 and Auxiliary3: \n" + + "Auxiliary[1-3]\n" + + "or\n" + + "Auxiliary1|Auxiliary2|Auxiliary3"); + + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + } + + @Override + protected void createControlLayoutVertical() { + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().applyTo(sc); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(nameLabel); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(name.getWidget()); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(startTimeLabel); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(startTime.getWidget()); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(stopTimeLabel); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(stopTime.getWidget()); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(stepLengthLabel); + stepLengthLabel.setAlignment(SWT.LEFT); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(stepLength.getWidget()); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(outputIntervalLabel); + outputIntervalLabel.setAlignment(SWT.LEFT); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(outputInterval.getWidget()); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(methodLabel); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(validateUnits.getWidget()); + GridDataFactory.fillDefaults().span(2, 1).align(SWT.BEGINNING, SWT.CENTER).applyTo(equivalentUnitsWidget.getWidget()); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(toleranceLabel); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(tolerance.getWidget()); + GridDataFactory.fillDefaults().span(2, 1).align(SWT.BEGINNING, SWT.CENTER).applyTo(variableFilterLabel); + GridDataFactory.fillDefaults().span(2, 1).grab(true, false).hint(100, SWT.DEFAULT).applyTo(variableFilter.getWidget()); + + sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + + @Override + protected void createControlLayoutHorizontal(boolean wideScreen) { + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().applyTo(sc); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(wideScreen ? 13 : 6).applyTo(composite); + + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(nameLabel); + GridDataFactory.fillDefaults().grab(true, false).span(wideScreen ? 12 : 5, 1).hint(200, SWT.DEFAULT).applyTo(name.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(startTimeLabel); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(startTime.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(stopTimeLabel); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(stopTime.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(stepLengthLabel); + stepLengthLabel.setAlignment(SWT.RIGHT); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(stepLength.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(outputIntervalLabel); + outputIntervalLabel.setAlignment(SWT.RIGHT); + GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(outputInterval.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(methodLabel); + GridDataFactory.fillDefaults().span(wideScreen ? 1 : 3, 1).align(SWT.BEGINNING, SWT.CENTER).applyTo(method.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(validateUnits.getWidget()); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(timeUnit.getWidget()); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(equivalentUnitsWidget.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(toleranceLabel); + GridDataFactory.fillDefaults().grab(true, false).span(wideScreen ? 1 : 2, 1).hint(60, SWT.DEFAULT).applyTo(tolerance.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(variableFilterLabel); + GridDataFactory.fillDefaults().grab(true, false).span(wideScreen ? 10 : 5, 1).hint(200, SWT.DEFAULT).applyTo(variableFilter.getWidget()); + + sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + + private class DoubleValidator implements IInputValidator { + + @Override + public String isValid(String newText) { + for(int i = 0; i < newText.length(); i++){ + if(!Character.isDigit(newText.charAt(i))){ + if(newText.charAt(i) != '.') { + return "Invalid character '" + newText.charAt(i) + "'"; + } else if(newText.indexOf('.') != newText.lastIndexOf('.')) { + return "There can be only one '.'"; + } + } + } + return null; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/DependencyTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/DependencyTab.java new file mode 100644 index 00000000..b2ba5ca7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/DependencyTab.java @@ -0,0 +1,268 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.Scale; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.util.ObjectUtils; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements.connections.DependencyEdgeClass; +import org.simantics.sysdyn.ui.elements.connections.DependencyNode; +import org.simantics.sysdyn.ui.properties.widgets.ArrowHeadWidget; +import org.simantics.sysdyn.ui.properties.widgets.DelayMarkWidget; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.datastructures.Triple; + +public class DependencyTab extends LabelPropertyTabContributor { + + Button none, plus, minus, other, inside, outside; + TrackedText polarityText, polarityLocationText; + Scale lineThicknessScale; + private DelayMarkWidget delayMark; + private ArrowHeadWidget arrowhead; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + Group polarityGroup = new Group(composite, SWT.NONE); + polarityGroup.setText("Polarity"); + GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityGroup); + GridLayoutFactory.fillDefaults().numColumns(5).applyTo(polarityGroup); + + none = new Button(polarityGroup, support, SWT.RADIO); + none.setText("None"); + none.setSelectionFactory(new PolarityRadioSelectionFactory("")); + none.addSelectionListener(new PolaritySelectionListener(context, "")); + + plus = new Button(polarityGroup, support, SWT.RADIO); + plus.setText("+"); + plus.setSelectionFactory(new PolarityRadioSelectionFactory("+")); + plus.addSelectionListener(new PolaritySelectionListener(context, "+")); + + minus = new Button(polarityGroup, support, SWT.RADIO); + minus.setText("-"); + minus.setSelectionFactory(new PolarityRadioSelectionFactory("-")); + minus.addSelectionListener(new PolaritySelectionListener(context, "-")); + + other = new Button(polarityGroup, support, SWT.RADIO); + other.setText("other"); + other.setSelectionFactory(new OtherPolaritySelectionFactory(new String[] {null, "+", "-", ""})); + + polarityText = new TrackedText(polarityGroup, support, SWT.BORDER); + polarityText.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.DependencyConnection_polarity)); + polarityText.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.DependencyConnection_polarity)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityText.getWidget()); + + Group locationGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(locationGroup); + GridLayoutFactory.fillDefaults().applyTo(locationGroup); + locationGroup.setText("Location"); + + inside = new Button(locationGroup, support, SWT.RADIO); + inside.setText("Inside"); + inside.setSelectionFactory(new PolarityLocationRadioSelectionFactory(DependencyNode.INSIDE)); + inside.addSelectionListener(new PolarityLocationSelectionListener(context, DependencyNode.INSIDE)); + + outside = new Button(locationGroup, support, SWT.RADIO); + outside.setText("Outside"); + outside.setSelectionFactory(new PolarityLocationRadioSelectionFactory(DependencyNode.OUTSIDE)); + outside.addSelectionListener(new PolarityLocationSelectionListener(context, DependencyNode.OUTSIDE)); + + Composite misc = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(misc); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(misc); + + arrowhead = new ArrowHeadWidget(misc, support, SWT.NULL); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(arrowhead.getWidget()); + delayMark = new DelayMarkWidget(misc, support, SWT.NULL); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(delayMark.getWidget()); + + Group lineThicknessGroup = new Group(misc, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(lineThicknessGroup); + GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup); + lineThicknessGroup.setText("Line thickness:"); + lineThicknessScale = new Scale(lineThicknessGroup, support, SWT.HORIZONTAL); + lineThicknessScale.getWidget().setMinimum(1); + lineThicknessScale.getWidget().setMaximum(15); + lineThicknessScale.getWidget().setPageIncrement(1); + lineThicknessScale.getWidget().setIncrement(1); + lineThicknessScale.setSelectionFactory(new LineThicknessRadioSelectionFactory()); + lineThicknessScale.addSelectionListener(new LineThicknessSelectionListener(context, lineThicknessScale)); + } + + class LineThicknessSelectionListener extends SelectionListenerImpl { + Scale scale; + private int selection; + + public LineThicknessSelectionListener(ISessionContext context, Scale scale) { + super(context); + this.scale = scale; + } + + @Override + public void beforeApply() { + this.selection = scale.getWidget().getSelection(); + } + + @Override + public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + float width = ((float)selection) / 10.0f; + graph.claimLiteral(connectionElement, sr.DependencyConnection_strokeWidth, width); + } + + } + + class LineThicknessRadioSelectionFactory extends ReadFactoryImpl { + + public LineThicknessRadioSelectionFactory() { + } + + @Override + public Integer perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Float width = graph.getPossibleRelatedValue(dependencyConnection, sr.DependencyConnection_strokeWidth, Bindings.FLOAT); + if(width == null) + return (int)Math.round(DependencyEdgeClass.DEFAULT_STROKE_WIDTH * 10); + else + return (int)Math.round(width * 10); + } + } + + class PolarityLocationSelectionListener extends SelectionListenerImpl { + private String location; + + public PolarityLocationSelectionListener(ISessionContext context, String location) { + super(context); + this.location = location; + } + + @Override + public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + graph.claimLiteral(connectionElement, sr.DependencyConnection_polarityLocation, location); + } + + } + + class PolarityLocationRadioSelectionFactory extends ReadFactoryImpl { + private String location; + + public PolarityLocationRadioSelectionFactory(String location) { + this.location = location; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple>(inputContents, location, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + String location = graph.getPossibleRelatedValue(dependencyConnection, sr.DependencyConnection_polarityLocation, Bindings.STRING); + if(DependencyNode.OUTSIDE.equals(this.location)) { + return ObjectUtils.objectEquals(this.location, location); + } else { + if(location == null) + return true; + else + return ObjectUtils.objectEquals(this.location, location); + } + } + } + + class PolaritySelectionListener extends SelectionListenerImpl { + private String polarity; + + public PolaritySelectionListener(ISessionContext context, String polarity) { + super(context); + this.polarity = polarity; + } + + @Override + public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + graph.claimLiteral(connectionElement, sr.DependencyConnection_polarity, polarity.trim()); + } + + } + + class PolarityRadioSelectionFactory extends ReadFactoryImpl { + private String polarity; + + public PolarityRadioSelectionFactory(String polarity) { + this.polarity = polarity; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple>(inputContents, polarity, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + String polarity = graph.getPossibleRelatedValue(dependencyConnection, sr.DependencyConnection_polarity, Bindings.STRING); + if(polarity == null && this.polarity.equals("")) + return true; + return ObjectUtils.objectEquals(polarity, this.polarity); + } + } + + class OtherPolaritySelectionFactory extends ReadFactoryImpl { + + String[] limits; + + public OtherPolaritySelectionFactory(String[] limits) { + this.limits = limits; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Pair>(inputContents, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + String polarity = graph.getPossibleRelatedValue(dependencyConnection, sr.DependencyConnection_polarity, Bindings.STRING); + for(String s : limits) { + if(ObjectUtils.objectEquals(polarity, s)) + return false; + } + return true; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EnumerationTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EnumerationTab.java new file mode 100644 index 00000000..b9f246ce --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EnumerationTab.java @@ -0,0 +1,383 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.Table; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.ui.properties.widgets.arrays.EnumerationIndexNode; +import org.simantics.sysdyn.ui.properties.widgets.arrays.ReplaceableIndexesWidget; +import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNamePropertyModifier; +import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameInputValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.AdaptionUtils; + +public class EnumerationTab extends LabelPropertyTabContributor implements Widget { + + GraphExplorerComposite indexExplorer; + + Button showAll; + Variable variable; + + Table table; + @Override + public void createControls(Composite body, IWorkbenchSite site, + final ISessionContext context, WidgetSupport support) { + + support.register(this); + + Composite container = new Composite(body, SWT.None); + GridDataFactory.fillDefaults().grab(true, true).applyTo(container); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(4).applyTo(container); + + TrackedText nameText = new TrackedText(container, support, SWT.BORDER); + nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName)); + nameText.addModifyListener(new VariableNamePropertyModifier(context, Layer0.URIs.HasName)); + nameText.setInputValidator(new VariableNameInputValidator(support)); + GridDataFactory.fillDefaults().grab(true, false).span(4,1).applyTo(nameText.getWidget()); + + indexExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, container, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI | SWT.CHECK); + + indexExplorer + .setBrowseContexts(SysdynResource.URIs.EnumerationIndexes); + indexExplorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + ((Tree)indexExplorer.getExplorerControl()).addListener(SWT.Selection, new Listener () { + + @Override + public void handleEvent (Event event) { + if(event.detail == SWT.CHECK) { + final TreeItem item = (TreeItem)event.item; + final boolean checked = item.getChecked(); + NodeContext context = (NodeContext)item.getData(); + final EnumerationIndexNode node = (EnumerationIndexNode) context.getAdapter(EnumerationIndexNode.class); + node.setShowInChartsSelected(checked); + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + updateModelResults(graph); + } + }); + } + } + }); + + + indexExplorer.finish(); + + GridDataFactory.fillDefaults().grab(true, true).span(4, 1).applyTo( + indexExplorer); + + Control c = indexExplorer.getExplorerControl(); + if (c instanceof Tree) + ((Tree) c).setLinesVisible(true); + + + final Button add = new Button(container, support, SWT.None); + add.setText("Add"); + add.addSelectionListener(new addEnumerationIndexListener(support)); + + final Button remove = new Button(container, support, SWT.None); + remove.setText("Remove"); + remove.addSelectionListener(new removeEnumerationIndexListener(support)); + + ReplaceableIndexesWidget externalIndexes = new ReplaceableIndexesWidget(container, support, SWT.NULL); + GridDataFactory.fillDefaults().applyTo(externalIndexes.getWidget()); + + showAll = new Button(container, support, SWT.CHECK); + showAll.setText("Show all in charts"); + showAll.addSelectionListener(new ShowAllIndexesListener(support)); + + } + + private class addEnumerationIndexListener implements SelectionListener, Widget { + + Resource enumerationIndexes; + + public addEnumerationIndexListener(WidgetSupport support) { + support.register(this); + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource enumeration = AdaptionUtils.adaptToSingle(input, Resource.class); + try { + context.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + enumerationIndexes = graph.getSingleObject(enumeration, SysdynResource.getInstance(graph).Enumeration_enumerationIndexList); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void widgetSelected(SelectionEvent e) { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + HashSet names = new HashSet(); + for(Resource r : ListUtils.toList(graph, enumerationIndexes)) { + names.add(NameUtils.getSafeName(graph, r)); + } + + Resource ei = GraphUtils.create2(graph, + sr.EnumerationIndex, + l0.HasName, NameUtils.findFreshName(graph, "index", names, "")); + ArrayList index = new ArrayList(); + index.add(ei); + ListUtils.insertBack(graph, enumerationIndexes, index); + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + + } + + } + + private class removeEnumerationIndexListener implements SelectionListener, Widget { + + Resource enumerationIndexes; + + public removeEnumerationIndexListener(WidgetSupport support) { + support.register(this); + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource enumeration = AdaptionUtils.adaptToSingle(input, Resource.class); + try { + context.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + enumerationIndexes = graph.getSingleObject(enumeration, SysdynResource.getInstance(graph).Enumeration_enumerationIndexList); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void widgetSelected(SelectionEvent e) { + ISelectionProvider selectionProvider = (ISelectionProvider)indexExplorer.getAdapter(ISelectionProvider.class); + final IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + for(Object o : selection.toList()) { + Resource r = AdaptionUtils.adaptToSingle(o, Resource.class); + if(r == null) + continue; + ListUtils.removeElement(graph, enumerationIndexes, r); + } + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + + } + + } + + private class ShowAllIndexesListener implements SelectionListener, Widget { + + Resource enumerationIndexes; + + public ShowAllIndexesListener(WidgetSupport support) { + support.register(this); + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource enumeration = AdaptionUtils.adaptToSingle(input, Resource.class); + + context.getSession().asyncRequest(new Read() { + + @Override + public Boolean perform(ReadGraph graph) + throws DatabaseException { + if(!graph.hasStatement(enumeration)) + return null; + + SysdynResource sr = SysdynResource.getInstance(graph); + enumerationIndexes = graph.getSingleObject(enumeration, sr.Enumeration_enumerationIndexList); + List indexes = ListUtils.toList(graph, enumerationIndexes); + for(Resource index : indexes) { + Boolean show = graph.getPossibleRelatedValue(index, sr.EnumerationIndex_showEnumerationIndexInCharts, Bindings.BOOLEAN); + if(!Boolean.TRUE.equals(show)) + return false; + } + return true; + } + + }, new org.simantics.db.procedure.Listener() { + + @Override + public void execute(final Boolean result) { + showAll.getWidget().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(result != null && !showAll.getWidget().isDisposed()) + showAll.getWidget().setSelection(result.booleanValue()); + } + }); + } + + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + if(showAll == null) + return true; + return showAll.getWidget().isDisposed(); + } + }); + + } + + @Override + public void widgetSelected(SelectionEvent e) { + final boolean selected = showAll.getWidget().getSelection(); + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + List indexes = ListUtils.toList(graph, enumerationIndexes); + for(Resource index : indexes) { + Boolean show = graph.getPossibleRelatedValue(index, sr.EnumerationIndex_showEnumerationIndexInCharts, Bindings.BOOLEAN); + if(selected && !Boolean.TRUE.equals(show)) { + graph.claimLiteral(index, sr.EnumerationIndex_showEnumerationIndexInCharts, true, Bindings.BOOLEAN); + } else if(!selected && !Boolean.FALSE.equals(show)) { + graph.claimLiteral(index, sr.EnumerationIndex_showEnumerationIndexInCharts, false, Bindings.BOOLEAN); + } + } + + updateModelResults(graph); + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + + } + + } + + private void updateModelResults(ReadGraph graph) { + try { + if(variable != null ) { + Resource modelResource = Variables.getModel(graph, variable); + if(modelResource != null) { + Resource configuration = graph.getSingleObject( + modelResource, + SimulationResource.getInstance(graph).HasConfiguration); + SysdynModel model = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configuration); + // update results in graphs + model.resultChanged(); + } + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void setInput(ISessionContext context, Object input) { + variable = AdaptionUtils.adaptToSingle(input, Variable.class); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java new file mode 100644 index 00000000..901d6ecc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java @@ -0,0 +1,761 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.IWorkbenchPartReference; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.platform.PropertyPageView; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.VirtualGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.request.WriteResultRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.AsyncListener; +import org.simantics.db.request.Read; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.ui.properties.widgets.ArrayExpressionCombo; +import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes; +import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType; +import org.simantics.sysdyn.ui.properties.widgets.ExpressionWidget; +import org.simantics.sysdyn.ui.properties.widgets.IsOutputWidget; +import org.simantics.sysdyn.ui.properties.widgets.ShortcutTabWidget; +import org.simantics.sysdyn.ui.properties.widgets.arrays.NameAndArrayRangeModifyListener; +import org.simantics.sysdyn.ui.properties.widgets.expressions.DelayExpression; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionComposite; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionWidgetInput; +import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameInputValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Tab for displaying equation information of a variable + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class EquationTab extends AdjustableTab implements Widget { + + private TrackedCombo expressionTypeCombo, unitCombo, arrayEquationCombo; + private ShortcutTabWidget shortcutTabWidget; + private ExpressionWidget expressionWidget; + private org.eclipse.ui.IPartListener2 focusLostListener; + private IWorkbenchSite site; + private Button deleteExpression, newExpression; + private WidgetSupportImpl support; + private ExpressionComposite expressionComposite; + private final WidgetSupportImpl expressionSupport = new WidgetSupportImpl(); + private Composite composite; + private Composite nameComposite; + private Composite TypeAndUnit; + private Label typeLabel; + private Label unitLabel; + private IsOutputWidget isOutput; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport _support) { + _support.register(this); + setSupport(); + this.site = site; + super.createControls(body, site, context, _support); + } + + protected void createControlLayoutHorizontal(boolean wideScreen) { + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + GridLayoutFactory.fillDefaults().numColumns(wideScreen ? 4 : 3).applyTo(nameComposite); + GridDataFactory.fillDefaults().grab(true, true).applyTo(nameComposite); + + GridDataFactory.fillDefaults().grab(true, false).hint(280, SWT.DEFAULT).applyTo(arrayEquationCombo.getWidget()); + GridDataFactory.fillDefaults().applyTo(deleteExpression.getWidget()); + GridDataFactory.fillDefaults().applyTo(newExpression.getWidget()); + + GridDataFactory.fillDefaults().span(1, wideScreen ? 2 : 3).grab(false, true).hint(250, SWT.DEFAULT).applyTo(shortcutTabWidget.getWidget()); + + GridDataFactory.fillDefaults().span(wideScreen ? 1 : 3, 1).grab(true, false).applyTo(TypeAndUnit); + GridLayoutFactory.fillDefaults().numColumns(5).applyTo(TypeAndUnit); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(typeLabel); + GridDataFactory.fillDefaults().applyTo(expressionTypeCombo.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(unitLabel); + GridDataFactory.fillDefaults().grab(true, false).hint(160, SWT.DEFAULT).applyTo(unitCombo.getWidget()); + GridDataFactory.fillDefaults().applyTo(isOutput.getWidget()); + + GridDataFactory.fillDefaults().span(wideScreen ? 4 : 3, 1).grab(true, true).applyTo(expressionComposite); + } + + protected void createControlLayoutVertical() { + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite); + + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(nameComposite); + GridDataFactory.fillDefaults().grab(true, true).applyTo(nameComposite); + + GridDataFactory.fillDefaults().grab(true, false).applyTo(arrayEquationCombo.getWidget()); + GridDataFactory.fillDefaults().applyTo(deleteExpression.getWidget()); + GridDataFactory.fillDefaults().applyTo(newExpression.getWidget()); + + GridDataFactory.fillDefaults().span(3, 1).applyTo(TypeAndUnit); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(TypeAndUnit); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(typeLabel); + GridDataFactory.fillDefaults().applyTo(expressionTypeCombo.getWidget()); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(unitLabel); + GridDataFactory.fillDefaults().grab(true, false).hint(160, SWT.DEFAULT).applyTo(unitCombo.getWidget()); + GridDataFactory.fillDefaults().span(3, 1).align(SWT.END, SWT.CENTER).applyTo(isOutput.getWidget()); + + GridDataFactory.fillDefaults().span(3, 1).grab(true, true).hint(SWT.DEFAULT, 250).applyTo(expressionComposite); + + GridDataFactory.fillDefaults().span(3, 1).grab(true, true).hint(SWT.DEFAULT, 300).applyTo(shortcutTabWidget.getWidget()); + } + + protected void createAndAddControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport _support) { + // Composite for the whole tab + Composite composite = new Composite(body, SWT.NONE); + this.composite = composite; + + // Composite holding name controls and controls for adding and removing expressions + nameComposite = new Composite(composite, SWT.NONE); + arrayEquationCombo = new ArrayExpressionCombo(nameComposite, support, SWT.DROP_DOWN | SWT.BORDER); + arrayEquationCombo.setInputValidator(new VariableNameInputValidator(support)); + arrayEquationCombo.addModifyListener(new NameAndArrayRangeModifyListener(support, expressionWidget, (ArrayExpressionCombo)arrayEquationCombo)); + deleteExpression = new Button(nameComposite, support, SWT.NONE); + deleteExpression.setText("Delete"); + newExpression = new Button(nameComposite, support, SWT.NONE); + newExpression.setText("New"); + + // Shortcut widget. Tabular widget containing tabs for functions and connected variables + shortcutTabWidget = new ShortcutTabWidget(composite, support, SWT.NONE); + + TypeAndUnit = new Composite(nameComposite, SWT.NONE); + typeLabel = new Label(TypeAndUnit, SWT.SINGLE ); + typeLabel.setText("Type:"); + expressionTypeCombo = new TrackedCombo(TypeAndUnit, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); + unitLabel = new Label(TypeAndUnit, SWT.SINGLE ); + unitLabel.setText("Unit:"); + unitCombo = new TrackedCombo(TypeAndUnit, support, SWT.DROP_DOWN | SWT.BORDER); + isOutput = new IsOutputWidget(TypeAndUnit, support, SWT.NULL); + + // The actual expression + expressionComposite = new ExpressionComposite(nameComposite, SWT.NONE); + expressionWidget = new ExpressionWidget(expressionComposite, expressionSupport, SWT.NONE); + expressionWidget.setVariableTable(shortcutTabWidget.getVariableTable()); + + addListeners(context); + } + + private void setSupport() { + support = new WidgetSupportImpl() { + + @Override + public void fireInput(ISessionContext context, Object input) { + final Variable var = AdaptionUtils.adaptToSingle(input, Variable.class); + if(var != null) { + Resource r; + try { + r = context.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) + throws DatabaseException { + return var.getRepresents(graph); + } + }); + input = new StructuredSelection(r); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + super.fireInput(context, input); + } + }; + } + + @Override + public void setInput(ISessionContext context, final Object input) { + support.fireInput(context, input); + + final Variable var = AdaptionUtils.adaptToSingle(input, Variable.class); + final Resource variable; + + // Find variable resource either from Variable var or from input + if(var != null) + try { + variable = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return var.getRepresents(graph); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + return; + } + else + variable = AdaptionUtils.adaptToSingle(input, Resource.class); + + if(var == null && variable == null) + return; + + + Resource expression = null; + try { + expression = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return getActiveExpression(graph, variable); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // The variable has no expressions -> creating a new ordered set expressions and the active expression + if(expression == null && variable != null) { + try { + expression = SimanticsUI.getSession().syncRequest(new WriteResultRequest() { + + @Override + public Resource perform(WriteGraph graph) + throws DatabaseException { + if(!graph.hasStatement(variable)) { + /* Trying to create empty experiment for removed variable due to + * async setInput + */ + return null; + } + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource expressions = ListUtils.create(graph, Collections.emptyList()); + graph.claim(variable, sr.Variable_expressionList, expressions); + final Resource expression = graph.newResource(); + + if(graph.isInstanceOf(variable, sr.Auxiliary) || + graph.isInstanceOf(variable, sr.Valve)) { + graph.claim(expression, l0.InstanceOf, null, sr.NormalExpression); + graph.claimLiteral(expression, sr.Expression_equation, ""); + } + else if(graph.isInstanceOf(variable, sr.Stock)) { + graph.claim(expression, l0.InstanceOf, null, sr.StockExpression); + graph.claimLiteral(expression, sr.StockExpression_initialEquation, ""); + } + ArrayList addition = new ArrayList(1); + addition.add(expression); + ListUtils.insertBack(graph, expressions, addition); + + graph.claim(variable, l0.ConsistsOf, expression); + + VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); + final Session session = graph.getSession(); + session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + VirtualGraph runtime = graph.getService(VirtualGraph.class); + session.asyncRequest(new WriteRequest(runtime) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression)) + graph.deny(variable, sr.IndependentVariable_activeExpression); + graph.claim(variable, sr.IndependentVariable_activeExpression, expression); + } + } + ); + } + }); + return expression; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + if(expression == null) + return; + } + + // Now the variable should have an expression + SimanticsUI.getSession().asyncRequest(new Read>() { + + /** + * Find out if user can add a new expression or delete the current expression + */ + @Override + public Pair perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource expressions = graph.getPossibleObject(variable, sr.Variable_expressionList); + if(expressions == null) { + return new Pair(false, false); + } + List expressionList = ListUtils.toList(graph, expressions); + if(expressionList.isEmpty()) { + return new Pair(false, false); + } + + boolean canAdd = true; + boolean canDelete = false; + // If there are multiple expressions, one can be removed + if(expressionList.size() > 1) + canDelete = true; + String defaultRange = ArrayExpressionCombo.getDefaultRange(graph, variable); + + /* If the variable is an array variable, a range has been set to all expressions and none of + * the ranges is the default range, an expression can be added + */ + for(Resource expression : expressionList) { + String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange); + if(range == null || range.equals("") || range.equals(defaultRange)) { + canAdd = false; + break; + } + } + return new Pair(canAdd, canDelete); + } + }, new AsyncListener>() { + + @Override + public void execute(AsyncReadGraph graph, + final Pair result) { + newExpression.getWidget().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(!newExpression.getWidget().isDisposed()) + newExpression.getWidget().setEnabled(result.first); + if(!deleteExpression.getWidget().isDisposed()) + deleteExpression.getWidget().setEnabled(result.second); + } + }); + + } + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return newExpression.getWidget().isDisposed() || deleteExpression.getWidget().isDisposed(); + } + }); + + // Set input to widgets using expressionSupport + StructuredSelection ss = new StructuredSelection(new ExpressionWidgetInput(var, expression)); + expressionSupport.fireInput(context, ss); + } + + /** + * Adds listeners to widgets in this tab + * + * @param context ISessionContext + */ + private void addListeners(ISessionContext context) { + + // Validate expression fields when a dependency has been added or removed + shortcutTabWidget.addDependencyListener(new Runnable() { + + @Override + public void run() { + expressionWidget.validateFields(); + } + }); + + // Deletes a selected expression + deleteExpression.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, final Resource input) + throws DatabaseException { + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + // Currently active expression should be located in (Model sr.HasActiveExpression expression) + Resource activeExpression = graph.getPossibleObject(input, sr.IndependentVariable_activeExpression); + if(activeExpression == null) + return; + + Resource expressionList = graph.getPossibleObject(input, sr.Variable_expressionList); + + List list = ListUtils.toList(graph, expressionList); + if(list.size() <= 1) + return; + + // Get the previous expression in expression list to be activated + int index = list.indexOf(activeExpression); + + ListUtils.removeElement(graph, expressionList, activeExpression); + graph.deny(input, l0.ConsistsOf, activeExpression); + + final Resource newActive = index == 0 ? list.get(1) : list.get(index - 1); + + // Set newActive as active in virtual graph + VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); + final Session session = graph.getSession(); + session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + VirtualGraph runtime = graph.getService(VirtualGraph.class); + session.asyncRequest(new WriteRequest(runtime) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.hasStatement(input, sr.IndependentVariable_activeExpression)) + graph.deny(input, sr.IndependentVariable_activeExpression); + graph.claim(input, sr.IndependentVariable_activeExpression, newActive); + } + } + ); + } + }); + } + }); + + // Creates a new expression + newExpression.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, Resource input) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource expressions = graph.getPossibleObject(input, sr.Variable_expressionList); + if(expressions == null) { + return; + } + // Get the currently active expression + Resource activeExpression = graph.getPossibleObject(input, sr.IndependentVariable_activeExpression); + Resource newExpression = graph.newResource(); + if(activeExpression != null) { + // Create a new expression based on the old expression + graph.claim(newExpression, l0.InstanceOf, graph.getSingleObject(activeExpression, l0.InstanceOf)); + if(graph.isInstanceOf(newExpression, sr.StockExpression)) { + graph.claimLiteral(newExpression, sr.StockExpression_initialEquation, ""); + } + } else { + // If there was no active expression, create a normal expression + graph.claim(newExpression, l0.InstanceOf, sr.NormalExpression); + } + ArrayList addition = new ArrayList(1); + addition.add(newExpression); + ListUtils.insertBack(graph, expressions, addition); + graph.claim(input, l0.ConsistsOf, newExpression); + } + }); + + // Item factory for expression type combo + expressionTypeCombo.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, final Resource input) throws DatabaseException { + + Map map = new HashMap(); + SysdynResource sr = SysdynResource.getInstance(graph); + + // Select expression types based on the type of the variable + final ExpressionType[] expressionTypes; + if(graph.isInstanceOf(input, sr.Auxiliary)) + expressionTypes = ExpressionTypes.auxiliaryExpressions; + else if(graph.isInstanceOf(input, sr.Stock)) + expressionTypes = ExpressionTypes.stockExpressions; + else if(graph.isInstanceOf(input, sr.Valve)) + expressionTypes = ExpressionTypes.valveExpressions; + else + expressionTypes = new ExpressionType[] {}; + + for(ExpressionType et : expressionTypes) { + map.put(et.toString(), et); + } + return map; + } + }); + + // Initial selection to the combo from active expression + expressionTypeCombo.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + Resource activeExpression = getActiveExpression(graph, input); + if(activeExpression == null) + return null; + return ExpressionTypes.getExpressionType(graph, activeExpression).toString(); + } + }); + + // Modify listener for selecting expression type + expressionTypeCombo.addModifyListener(new TextModifyListener() { + + @Override + public void modifyText(TrackedModifyEvent e) { + expressionWidget.displayExpression(e.getText(), false); + expressionWidget.save(); + } + }); + + + // Add all units used in the model to the unit combo + unitCombo.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, final Resource input) throws DatabaseException { + Map map = new HashMap(); + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource model = graph.getPossibleObject(input, l0.PartOf); + if (model != null) { + Collection variables = graph.getObjects(model, l0.ConsistsOf); + for(Resource v : variables) { + Object unit = graph.getPossibleRelatedValue(v, sr.Variable_unit); + if (unit != null && !map.keySet().contains(unit)) { + map.put((String)unit, (String)unit); + + } + } + } + return map; + } + }); + + // Set initial selection of unit combo + unitCombo.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + String unit = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).Variable_unit); + if(unit == null) + return ""; + else + return unit; + } + }); + + // Modify unit + unitCombo.addModifyListener(new ComboModifyListenerImpl() { + + @Override + public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException { + graph.denyValue(input, SysdynResource.getInstance(graph).Variable_unit); + graph.claimLiteral(input, SysdynResource.getInstance(graph).Variable_unit, text); + + Resource conf = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf); + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, conf); + sm.getMapping().domainModified(input); + sm.update(graph); + } + }); + + + /* + * Double-clicking something in shortcut tab widget + * writes the clicked element into expression widget, + * sets focus on expression widget and validates its fields + */ + shortcutTabWidget.addMouseListener(new MouseListener(){ + + @Override + public void mouseDoubleClick(MouseEvent e) { + Table table = (Table)e.widget; + TableItem item = table.getItem(new Point(e.x, e.y)); + if(item != null) { + final String var = (String)item.getData(); + table.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(expressionWidget!= null) { + expressionWidget.getExpression().focus(); + expressionWidget.getExpression().replaceSelection(var); + expressionWidget.validateFieldsTimed(); + } + } + }); + } + } + + @Override + public void mouseDown(MouseEvent e) { + expressionWidget.getExpression().focus(); + } + + @Override + public void mouseUp(MouseEvent e) { + } + + }); + + /* Modifying an expression sets a timed validation. The timer is + * reset after each modification + */ + expressionWidget.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + expressionWidget.validateFieldsTimed(); + } + }); + + // Pressing return without shift key triggers saving the expression + expressionWidget.addVerifyKeyListener(new VerifyKeyListener() { + + @Override + public void verifyKey(VerifyEvent event) { + // Check if some of the expression fields has active completion assistant + boolean isAnyAssistSessionActive = false; + for (int i = 0; i < expressionWidget.getExpression().getExpressionFields().size(); ++i) { + if (expressionWidget.getExpression().getExpressionFields().get(i).isAssistSessionActive()) { + isAnyAssistSessionActive = true; + break; + } + } + if(event.keyCode == SWT.CR || event.keyCode == SWT.KEYPAD_CR) { + if (!isAnyAssistSessionActive) { + if((event.stateMask & SWT.SHIFT) == 0) { + event.doit = false; + ((StyledText)event.widget).getParent().forceFocus(); + expressionWidget.save(); + } + } else { + // When a proposed expression is selected with enter, fields are validated. + expressionWidget.validateFieldsTimed(); + } + } + } + }); + + // Triggers save when equation tab loses focus + if(focusLostListener == null) { + focusLostListener = new org.eclipse.ui.IPartListener2() + { + @Override + public void partInputChanged(IWorkbenchPartReference partRef) {} + @Override + public void partVisible(IWorkbenchPartReference partRef) {} + @Override + public void partHidden(IWorkbenchPartReference partRef) {} + @Override + public void partOpened(IWorkbenchPartReference partRef) {} + @Override + public void partDeactivated(IWorkbenchPartReference partRef) + { + if(partRef.getPart(false) instanceof PropertyPageView) { + PropertyPageView ppv = (PropertyPageView)partRef.getPart(false); + if(ppv.getCurrentPage() instanceof SysdynPropertyPage) { + // Save expressions + if(expressionWidget != null) { + expressionWidget.save(); + } +// site.getPage().removePartListener(this); + } + } + } + @Override + public void partClosed(IWorkbenchPartReference partRef) {} + @Override + public void partBroughtToTop(IWorkbenchPartReference partRef) {} + @Override + public void partActivated(IWorkbenchPartReference partRef) {} + }; + site.getPage().addPartListener(focusLostListener); + } + } + + @Override + public void dispose() { + if(expressionWidget != null && !(expressionWidget.getExpression() instanceof DelayExpression)) { + // For delay expression this doesn't work, + // but it doesn't matter since the saving is succeeded elsewhere. + expressionWidget.save(); + } + if(focusLostListener != null && site != null) + site.getPage().removePartListener(focusLostListener); + super.dispose(); + if(expressionComposite != null && !expressionComposite.isDisposed()) + expressionComposite.dispose(); + } + + /** + * Get the currently active expression of the first expression in expression list if + * no expression has been set to active + * + * @param graph ReadGraph + * @param variable Variable + * @return active expression or the first expression in variables expression list + * @throws DatabaseException + */ + private Resource getActiveExpression(ReadGraph graph, Resource variable) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource expression = graph.getPossibleObject(variable, sr.IndependentVariable_activeExpression); + if(expression == null) { + Resource expressions = graph.getPossibleObject(variable, sr.Variable_expressionList); + if(expressions == null) { + return null; + } + List expressionList = ListUtils.toList(graph, expressions); + if(expressionList.isEmpty()) { + return null; + } + expression = expressionList.get(0); + } + return expression; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExperimentTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExperimentTab.java new file mode 100644 index 00000000..8d4aa90b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExperimentTab.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; + +public class ExperimentTab extends LabelPropertyTabContributor { + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExternalFilesTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExternalFilesTab.java new file mode 100644 index 00000000..47ba4e84 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExternalFilesTab.java @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.AdaptableHintContext; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.handlers.RemoveNodeHandler; +import org.simantics.sysdyn.ui.handlers.exports.ExportExternalFunctionFilesHandler; +import org.simantics.sysdyn.ui.handlers.imports.ImportExternalFunctionFilesHandler; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.datastructures.Pair; + +/** + * Tab for properties of a SysdynModelicaFunction containing all external files added to that function + * + * @author Teemu Lempinen + * + */ +public class ExternalFilesTab extends LabelPropertyTabContributor implements Widget { + + GraphExplorerComposite externalFilesExplorer; + Button importButton, exportButton, removeButton; + + @Override + public void createControls(Composite body, IWorkbenchSite site, + final ISessionContext context, WidgetSupport support) { + support.register(this); + + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite); + + // Create the graph explorer displaying external files + externalFilesExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI); + + externalFilesExplorer + .setBrowseContexts(SysdynResource.URIs.ExternalFiles); + externalFilesExplorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + + externalFilesExplorer.setContextMenuId("#ExternalFunctionFileBrowser"); + externalFilesExplorer.finish(); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + externalFilesExplorer); + + Control c = externalFilesExplorer.getExplorerControl(); + if (c instanceof Tree) + ((Tree) c).setLinesVisible(true); + + + // Create controls for importing, exporting and removing external files + Composite buttonRow = new Composite(composite, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonRow); + GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonRow); + + importButton = new Button(buttonRow, support, SWT.NONE); + importButton.setText("Import"); + importButton.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, final Resource input) + throws DatabaseException { + + importButton.getWidget().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + Shell shell = importButton.getWidget().getShell(); + + final Pair importedFiles = ImportExternalFunctionFilesHandler.importFiles(shell, "Import files", ImportExternalFunctionFilesHandler.C_EXTENSIONS); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + ImportExternalFunctionFilesHandler.addFilesToFunction(graph, input, importedFiles); + } + }); + } + }); + + + } + }); + + exportButton = new Button(buttonRow, support, SWT.NONE); + exportButton.setText("Export"); + exportButton.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, final Resource input) + throws DatabaseException { + + exportButton.getWidget().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + Shell shell = exportButton.getWidget().getShell(); + List resourceList = getSelectedResources(externalFilesExplorer); + Resource[] resources = resourceList.toArray(new Resource[resourceList.size()]); + if (resources.length > 0) + ExportExternalFunctionFilesHandler.exportFiles(shell, resources); + } + }); + + + } + }); + + removeButton = new Button(buttonRow, support, SWT.NONE); + removeButton.setText("Remove"); + removeButton.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, final Resource input) + throws DatabaseException { + + removeButton.getWidget().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + Shell shell = removeButton.getWidget().getShell(); + + List resourceList = getSelectedResources(externalFilesExplorer); + Resource[] resources = resourceList.toArray(new Resource[resourceList.size()]); + if(resources.length > 0) { + MessageDialog dialog = new MessageDialog(shell, resources.length > 1 ? "Remove selected items" : "Remove selected item" , null, "Are you sure?", 0, + new String[] { "OK", "Cancel" }, 0); + dialog.create(); + if (dialog.open() == 0) { + RemoveNodeHandler.deleteItem(resources); + } + } + } + }); + + + } + }); + } + + @Override + public void setInput(ISessionContext context, Object input) { + externalFilesExplorer.setInput(context, input); + } + + /** + * Method for retreiving selected resources from a GraphExplorerComposite + * @param explorer + * @return + */ + private List getSelectedResources(GraphExplorerComposite explorer) { + List result = new ArrayList(); + + ISelection selection = ((ISelectionProvider) explorer + .getAdapter(ISelectionProvider.class)).getSelection(); + if (selection == null) + return result; + IStructuredSelection iss = (IStructuredSelection) selection; + @SuppressWarnings("unchecked") + List selections = iss.toList(); + for(AdaptableHintContext ahc : selections) { + Resource resource = (Resource) ahc.getAdapter(Resource.class); + result.add(resource); + } + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FlowTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FlowTab.java new file mode 100644 index 00000000..fa864737 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FlowTab.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Scale; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.elements.connections.FlowConnectionStyle; + +public class FlowTab extends LabelPropertyTabContributor { + + Scale lineThicknessScale; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(1).applyTo(composite); + + Group lineThicknessGroup = new Group(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(lineThicknessGroup); + GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup); + lineThicknessGroup.setText("Flow thickness:"); + lineThicknessScale = new Scale(lineThicknessGroup, support, SWT.HORIZONTAL); + lineThicknessScale.getWidget().setMinimum(1); + lineThicknessScale.getWidget().setMaximum(9); + lineThicknessScale.getWidget().setPageIncrement(1); + lineThicknessScale.getWidget().setIncrement(1); + lineThicknessScale.setSelectionFactory(new LineThicknessRadioSelectionFactory()); + lineThicknessScale.addSelectionListener(new LineThicknessSelectionListener(context, lineThicknessScale)); + } + + class LineThicknessSelectionListener extends SelectionListenerImpl { + Scale scale; + private int selection; + + public LineThicknessSelectionListener(ISessionContext context, Scale scale) { + super(context); + this.scale = scale; + } + + @Override + public void beforeApply() { + this.selection = scale.getWidget().getSelection(); + } + + @Override + public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + float width = ((float)selection) / 3.0f; + graph.claimLiteral(connectionElement, sr.FlowConnection_width, width); + } + + } + + class LineThicknessRadioSelectionFactory extends ReadFactoryImpl { + + public LineThicknessRadioSelectionFactory() { + } + + @Override + public Integer perform(ReadGraph graph, Resource flowConnection) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Float width = graph.getPossibleRelatedValue(flowConnection, sr.FlowConnection_width, Bindings.FLOAT); + if(width == null) + return (int)Math.round(FlowConnectionStyle.DEFAULT_LINE_WIDTH * 3); + else + return (int)Math.round(width * 3); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionLibraryTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionLibraryTab.java new file mode 100644 index 00000000..5164aa97 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionLibraryTab.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.properties.widgets.factories.FunctionLibraryNameInputValidator; + +public class FunctionLibraryTab extends LabelPropertyTabContributor { + + @Override + public void createControls(Composite body, IWorkbenchSite site, + ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite); + + + TrackedText nameText = new TrackedText(composite, support, SWT.BORDER); + nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName)); + nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName)); + nameText.setInputValidator(new FunctionLibraryNameInputValidator(support)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget()); + + + TrackedText information = new TrackedText(composite, support, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.WRAP); + information.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasDescription)); + information.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasDescription)); + GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget()); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionTab.java new file mode 100644 index 00000000..d7c57f34 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionTab.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.properties.widgets.FunctionLabelFactory; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField; +import org.simantics.sysdyn.ui.properties.widgets.factories.FunctionNameInputValidator; +import org.simantics.sysdyn.ui.properties.widgets.functions.FunctionCodeWidget; + +public class FunctionTab extends LabelPropertyTabContributor { + + ExpressionField modelicaCode; + + @Override + public void createControls(Composite body, IWorkbenchSite site, + ISessionContext context, WidgetSupport support) { + + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + TrackedText nameText = new TrackedText(composite, support, SWT.BORDER); + nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName)); + nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName)); + nameText.setInputValidator(new FunctionNameInputValidator(support)); + GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(nameText.getWidget()); + + + Group modelicaGroup = new Group(composite, SWT.SHADOW_ETCHED_IN); + modelicaGroup.setText("Modelica code"); + GridDataFactory.fillDefaults().grab(true, true).minSize(150, 0).applyTo(modelicaGroup); + GridLayoutFactory.fillDefaults().spacing(0, 0).margins(3, 3).applyTo(modelicaGroup); + + Label startLabel = new Label(modelicaGroup, support, SWT.NONE); + startLabel.setTextFactory(new FunctionLabelFactory(Layer0.URIs.HasName, false)); + + new FunctionCodeWidget(modelicaGroup, support, SWT.BORDER); + /* + TrackedText modelicaCode = new TrackedText(modelicaGroup, support, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.WRAP); + modelicaCode.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.HasModelicaFunctionCode)); + modelicaCode.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.HasModelicaFunctionCode)); + modelicaCode.addModifyListener(new TextModifyListenerImpl() { + + @Override + public void applyText(WriteGraph graph, Resource input, String text) + throws DatabaseException { + Resource library = graph.getSingleObject(input, Layer0.getInstance(graph).PartOf); + FunctionUtils.updateFunctionFileForLibrary(graph, library); + } + }); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(modelicaCode.getWidget()); + */ + Label endLabel = new Label(modelicaGroup, support, SWT.NONE); + endLabel.setTextFactory(new FunctionLabelFactory(Layer0.URIs.HasName, true)); + + Group documentationGroup = new Group(composite, SWT.SHADOW_ETCHED_IN); + documentationGroup.setText("Documentation"); + GridDataFactory.fillDefaults().grab(true, true).applyTo(documentationGroup); + GridLayoutFactory.fillDefaults().spacing(0, 0).margins(3, 3).applyTo(documentationGroup); + + TrackedText information = new TrackedText(documentationGroup, support, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP); + information.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasDescription)); + information.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasDescription)); + GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget()); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/GameExperimentTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/GameExperimentTab.java new file mode 100644 index 00000000..e77b9f86 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/GameExperimentTab.java @@ -0,0 +1,82 @@ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; +import org.simantics.utils.ui.validators.DoubleValidator; + +/** + * Tab for displaying game experiment properties + * + * @author Teemu Lempinen + * + */ +public class GameExperimentTab extends LabelPropertyTabContributor { + + @Override + public void createControls(Composite body, IWorkbenchSite site, + ISessionContext context, WidgetSupport support) { + + ScrolledComposite sc = new ScrolledComposite(body, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().applyTo(sc); + + Composite composite = new RemoveFocusBeforeExperimentComposite(sc, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + // Label + Label label = new Label(composite, SWT.NONE); + label.setText("Name"); + + TrackedText name = new TrackedText(composite, support, SWT.BORDER); + name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName)); + name.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), name.getWidget()))); + + // Step duration (i.e. how many time units is one step in user's perspective) + label = new Label(composite, SWT.NONE); + label.setText("Step duration"); + + TrackedText stepDuration = new TrackedText(composite, support, SWT.BORDER); + stepDuration.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.GameExperiment_stepDuration)); + stepDuration.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.GameExperiment_stepDuration)); + stepDuration.setInputValidator(new DoubleValidator()); + stepDuration.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), stepDuration.getWidget()))); + GridDataFactory.fillDefaults().hint(300, SWT.DEFAULT).applyTo(name.getWidget()); + + // Integrator step length (i.e. how long is a integration step in the simulator. This time is stepped until stepDuration is full) + label = new Label(composite, SWT.NONE); + label.setText("Integrator step length"); + + TrackedText integratorStep = new TrackedText(composite, support, SWT.BORDER); + integratorStep.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.GameExperiment_stepLength)); + integratorStep.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.GameExperiment_stepLength)); + integratorStep.setInputValidator(new DoubleValidator()); + integratorStep.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), integratorStep.getWidget()))); + + // Scrolled composite settings + sc.setContent(composite); + sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/HistoryDataTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/HistoryDataTab.java new file mode 100644 index 00000000..fe3694de --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/HistoryDataTab.java @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.spreadsheet.resource.SpreadsheetResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Tab for displaying and modifying history data settings in SysDyn. + * @author Teemu Lempinen + * + */ +public class HistoryDataTab extends LabelPropertyTabContributor { + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + + // Scrolled composite for scrollable tab + ScrolledComposite sc = new ScrolledComposite(body, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(sc); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(sc); + + // Container for all components + Composite composite = new Composite(sc, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(3).margins(3, 3).applyTo(composite); + + // Name + Label label = new Label(composite, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Name: "); + + TrackedText nameText = new TrackedText(composite, support, SWT.BORDER); + nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel)); + nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(nameText.getWidget()); + + // Sheet selection + label = new Label(composite, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Sheet: "); + + TrackedCombo sheet = new TrackedCombo(composite, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); + sheet.setItemFactory(new SheetItemFactory()); + sheet.setSelectionFactory(new SheetSelectionFactory()); + sheet.addModifyListener(new SheetModifyListener()); + GridDataFactory.fillDefaults().span(2, 1).applyTo(sheet.getWidget()); + + // Orientation (columns or rows) + label = new Label(composite, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Orientation: "); + + Composite orientation = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(orientation); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(orientation); + + // Radio buttons for orientation + Button columns = new Button(orientation, support, SWT.RADIO); + GridDataFactory.fillDefaults().applyTo(columns.getWidget()); + columns.setText("Columns"); + columns.addSelectionListener(new SelectionListenerImpl(context) { + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + graph.claimLiteral(input, SysdynResource.getInstance(graph).HistoryDataset_columns, Boolean.TRUE, Bindings.BOOLEAN); + } + }); + columns.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public Boolean perform(ReadGraph graph, Resource input) throws DatabaseException { + return graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).HistoryDataset_columns); + } + }); + + Button rows = new Button(orientation, support, SWT.RADIO); + rows.setText("Rows"); + rows.addSelectionListener(new SelectionListenerImpl(context) { + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + graph.claimLiteral(input, SysdynResource.getInstance(graph).HistoryDataset_columns, Boolean.FALSE, Bindings.BOOLEAN); + } + }); + rows.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public Boolean perform(ReadGraph graph, Resource input) throws DatabaseException { + return Boolean.FALSE.equals(graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).HistoryDataset_columns)); + } + }); + + + // Group container displaying all variables found in the defined range + Group c = new Group(composite, SWT.NONE); + c.setText("Variables in range"); + GridDataFactory.fillDefaults().span(1, 4).applyTo(c); + GridLayoutFactory.fillDefaults().margins(3, 1).spacing(0, 0).applyTo(c); + + GraphExplorerComposite explorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, c, support, SWT.FULL_SELECTION | SWT.BORDER); + explorer.setBrowseContexts(SysdynResource.URIs.HistoryDataset_HistoryDatasetVariablesBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource(Resource.class)); + explorer.finish(); + GridDataFactory.fillDefaults().hint(SWT.DEFAULT,100).grab(true, false).applyTo(explorer); + + // Range start + label = new Label(composite, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Range Start: "); + + TrackedText start = new TrackedText(composite, support, SWT.BORDER); + start.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.HistoryDataset_start)); + start.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.HistoryDataset_start)); + GridDataFactory.fillDefaults().applyTo(start.getWidget()); + + // Range end + label = new Label(composite, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Range End: "); + + TrackedText end = new TrackedText(composite, support, SWT.BORDER); + end.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.HistoryDataset_end)); + end.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.HistoryDataset_end)); + GridDataFactory.fillDefaults().applyTo(end.getWidget()); + + // Time variable. This variable is used as time values in the history dataset + label = new Label(composite, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Time variable: "); + + TrackedText time = new TrackedText(composite, support, SWT.BORDER); + time.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.HistoryDataset_timeName)); + time.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.HistoryDataset_timeName)); + GridDataFactory.fillDefaults().applyTo(time.getWidget()); + + + // Scrolled composite settings + sc.setContent(composite); + sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + + } + + /** + * Item factory for finding spreadsheets from a model + * @author Teemu Lempinen + * + */ + private class SheetItemFactory extends ReadFactoryImpl> { + + @Override + public Map perform(ReadGraph graph, Resource historyData) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SimulationResource simu = SimulationResource.getInstance(graph); + SpreadsheetResource spreadSheet = SpreadsheetResource.getInstance(graph); + + Resource model = graph.getPossibleObject(historyData, l0.PartOf); + Resource config = graph.getPossibleObject(model, simu.HasConfiguration); + Resource book = graph.syncRequest(new PossibleObjectWithType(config, l0.ConsistsOf, spreadSheet.Book)); + Collection sheets = graph.syncRequest(new ObjectsWithType(book, l0.ConsistsOf, spreadSheet.Spreadsheet)); + + Map map = new LinkedHashMap(); + + for(Resource sheet : sheets) { + map.put(NameUtils.getSafeName(graph, sheet), sheet); + } + return map; + } + }; + + /** + * Selection factory for finding the defined sheet name for a history dataset + * @author Teemu Lempinen + * + */ + private class SheetSelectionFactory extends ReadFactoryImpl { + + @Override + public String perform(ReadGraph graph, Resource historyData) throws DatabaseException { + Resource selectedSheet = graph.getPossibleObject(historyData, SysdynResource.getInstance(graph).HistoryDataset_sheet); + if(selectedSheet != null) { + String name = NameUtils.getSafeName(graph, selectedSheet); + return name;// Return the selected sheet, if it exits + } else { + return null; + } + } + }; + + /** + * Listener for listening sheet selections in sheet combo + * @author Teemu Lempinen + * + */ + private class SheetModifyListener implements TextModifyListener, Widget { + + private ISessionContext context; + private Object lastInput = null; + + @Override + public void modifyText(TrackedModifyEvent e) { + + Combo combo = (Combo)e.getWidget(); + String textValue = combo.getText(); + Map data = (Map) combo.getData(); + if(data == null) return; + final Resource value = (Resource) data.get(textValue); + if(value == null) return; + final Object input = lastInput; + + try { + context.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + + Resource resource = (Resource) ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class); + SysdynResource sr = SysdynResource.getInstance(graph); + graph.deny(resource, sr.HistoryDataset_sheet); + graph.claim(resource, SysdynResource.getInstance(graph).HistoryDataset_sheet, value); + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + } + + @Override + public void setInput(ISessionContext context, Object parameter) { + this.context = context; + lastInput = parameter; + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/InputVariableTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/InputVariableTab.java new file mode 100644 index 00000000..19146ffa --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/InputVariableTab.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.ui.properties.widgets.IsOutputWidget; +import org.simantics.sysdyn.ui.properties.widgets.UnitComboWidget; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; +import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNamePropertyModifier; +import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameInputValidator; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.ui.validators.DoubleValidator; + +/** + * Properties for input variables: Name, default value, isOutput + * + * @author Teemu Lempinen + * + */ +public class InputVariableTab extends LabelPropertyTabContributor { + + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().hint(200, SWT.DEFAULT).grab(false, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite); + + TrackedText nameText = new TrackedText(composite, support, SWT.BORDER); + nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName)); + nameText.addModifyListener(new VariableNamePropertyModifier(context, Layer0.URIs.HasName)); + nameText.setInputValidator(new VariableNameInputValidator(support)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget()); + + Composite defaultValueComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, false).applyTo(defaultValueComposite); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(defaultValueComposite); + + Label label = new Label(defaultValueComposite, SWT.NULL); + label.setText("Default Value:"); + + TrackedText defaultValue = new TrackedText(defaultValueComposite, support, SWT.RIGHT | SWT.BORDER); + defaultValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.Input_defaultInputValue)); + defaultValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.Input_defaultInputValue)); + defaultValue.setInputValidator(new DoubleValidator()); + GridDataFactory.fillDefaults().grab(true, false).applyTo(defaultValue.getWidget()); + + + Composite unitComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(unitComposite); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(unitComposite); + + label = new Label(unitComposite, SWT.NULL ); + label.setText("Unit:"); + GridDataFactory.fillDefaults().applyTo(label); + + TrackedCombo unitCombo = new UnitComboWidget(unitComposite, support, SWT.DROP_DOWN | SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(unitCombo.getWidget()); + + + Composite variabilityComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(false, true).applyTo(variabilityComposite); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(variabilityComposite); + + label = new Label(variabilityComposite, SWT.NULL); + label.setText("Variability:"); + + TrackedCombo variability = new TrackedCombo(variabilityComposite, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); + GridDataFactory.fillDefaults().grab(true, false).applyTo(variability.getWidget()); + setVariabilityFactories(variability); + + new IsOutputWidget(composite, support, SWT.NULL); + } + + /** + * set item, selection and modify properties for variability combo + * @param variability + */ + private void setVariabilityFactories(TrackedCombo variability) { + variability.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, final Resource input) throws DatabaseException { + Map map = new HashMap(); + map.put("continuous", "continuous"); + map.put("parameter", "parameter"); + map.put("constant", "constant"); + return map; + } + }); + + variability.setSelectionFactory(new ReadFactoryImpl() { + + public Object getIdentity(Object inputContents) { + return new Pair>(inputContents, getClass()); + } + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + String variability = graph.getPossibleRelatedValue(input, sr.Variable_variability); + if(variability == null || variability.isEmpty()) + return "continuous"; + else + return variability; + } + }); + + variability.addModifyListener(new ComboModifyListenerImpl() { + + @Override + public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + String variability = text; + if(text.equals("continuous")) + variability = ""; + + if(variability != null) { + graph.denyValue(input, sr.Variable_variability); + graph.claimLiteral(input, sr.Variable_variability, variability); + + Resource conf = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf); + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, conf); + sm.getMapping().domainModified(input); + sm.update(graph); + + } + } + + }); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LabelPropertyTabContributor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LabelPropertyTabContributor.java new file mode 100644 index 00000000..d4a31f59 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LabelPropertyTabContributor.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.AsyncListener; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.selectionview.PropertyTabContributorImpl; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.ui.AdaptionUtils; + +public abstract class LabelPropertyTabContributor extends PropertyTabContributorImpl { + + private boolean isDisposed = false; + + + public void createControl(Composite parent, final IWorkbenchSite site, final ISessionContext context, final WidgetSupportImpl support) { + super.createControl(parent, site, context, support); + + // Add dispose listener to make sure name listening receives the correct isDisposed -value + parent.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + LabelPropertyTabContributor.this.dispose(); + } + }); + } + + @Override + public void updatePartName(ISelection forSelection, final Callback updateCallback) { + final Variable variable = AdaptionUtils.adaptToSingle(forSelection, Variable.class); + final Resource resource = AdaptionUtils.adaptToSingle(forSelection, Resource.class); + if(resource == null && variable == null) { + updateCallback.run("Selection properties"); + return; + } + + SimanticsUI.getSession().asyncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + + Resource r; + if(variable != null) { + r = (Resource)variable.getRepresents(graph); + } else { + r = resource; + } + + if(graph.hasStatement(r, mr.ElementToComponent)) { + r = graph.getSingleObject(r, mr.ElementToComponent); + } + String label = graph.getPossibleRelatedValue(r, l0.HasLabel); + if(label != null) + return label; + label = graph.getPossibleRelatedValue(r, l0.HasName); + if(label != null) + return label; + return "No name for selection"; + } + }, new AsyncListener() { + + @Override + public void execute(AsyncReadGraph graph, String result) { + updateCallback.run(result); + } + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + + } + + @Override + public boolean isDisposed() { + return isDisposed; + } + }); + } + + @Override + protected void dispose() { + this.isDisposed = true; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LookupTableTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LookupTableTab.java new file mode 100644 index 00000000..16c92c38 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LookupTableTab.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.ChartTableWidget; +import org.simantics.sysdyn.ui.properties.widgets.ChartWidget; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; + +public class LookupTableTab extends LabelPropertyTabContributor { + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + + + Composite baseContainer = new Composite(body, SWT.NONE); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(3).applyTo(baseContainer); + GridDataFactory.fillDefaults().grab(true, true).applyTo(baseContainer); + + Composite Ycontainer = new Composite(baseContainer, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(Ycontainer); + GridDataFactory.fillDefaults().grab(false, true).applyTo(Ycontainer); + + TrackedText maxYText = new TrackedText(Ycontainer, support, SWT.BORDER); + maxYText.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.WithLookupExpression_maxY)); + maxYText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.WithLookupExpression_maxY)); + + Label l = new Label(Ycontainer, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(false, true).applyTo(l); + + TrackedText minYText = new TrackedText(Ycontainer, support, SWT.BORDER); + minYText.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.WithLookupExpression_minY)); + minYText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.WithLookupExpression_minY)); + + + Composite chartContainer = new Composite(baseContainer, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(chartContainer); + GridDataFactory.fillDefaults().grab(true, true).applyTo(chartContainer); + + @SuppressWarnings("unused") + ChartWidget chartWidget = new ChartWidget(chartContainer, support, SWT.NONE); + + Composite chartTableContainer = new Composite(baseContainer, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(chartTableContainer); + GridDataFactory.fillDefaults().grab(false, true).span(1, 2).applyTo(chartTableContainer); + + @SuppressWarnings("unused") + ChartTableWidget chartTableWidget = new ChartTableWidget(chartTableContainer, support, SWT.NONE); + + l = new Label(baseContainer, SWT.NONE); + + Composite Xcontainer = new Composite(baseContainer, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(Xcontainer); + GridDataFactory.fillDefaults().grab(true, false).applyTo(Xcontainer); + + TrackedText minXText = new TrackedText(Xcontainer, support, SWT.BORDER); + minXText.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.WithLookupExpression_minX)); + minXText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.WithLookupExpression_minX)); + + l = new Label(Xcontainer, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, false).applyTo(l); + + TrackedText maxXText = new TrackedText(Xcontainer, support, SWT.BORDER); + maxXText.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.WithLookupExpression_maxX)); + maxXText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.WithLookupExpression_maxX)); + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LoopTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LoopTab.java new file mode 100644 index 00000000..b8fb2f06 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LoopTab.java @@ -0,0 +1,405 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.util.ObjectUtils; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.utils.LoopUtils; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.datastructures.Triple; + +/** + * Tab for displaying information of a loop + * @author Tuomas Miettinen + * + */ +public class LoopTab extends AdjustableTab { + + private Label loopItemsLabel; + private TrackedCombo loopItemsDropdown; + Button auto, balancing, reinforcing, other, inside, outside; + TrackedText loopComment, polarityLocationText; + Composite composite, loopItems; + Group commentGroup, rotationGroup; + protected Resource resource; + public static final String AUTO = "$$AUTO$$"; + + @Override + protected void createAndAddControls(Composite body, IWorkbenchSite site, + ISessionContext context, WidgetSupport support) { + composite = new Composite(body, SWT.NONE); + + loopItems = new Composite(composite, SWT.NONE); + loopItemsLabel = new Label(loopItems, SWT.SINGLE); + loopItemsLabel.setText("Loop Items:"); + loopItemsDropdown = new TrackedCombo(loopItems, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); + + commentGroup = new Group(composite, SWT.NONE); + commentGroup.setText("Comment"); + + auto = new Button(commentGroup, support, SWT.RADIO); + auto.setText("Auto"); + auto.setSelectionFactory(new CommentRadioSelectionFactory(AUTO)); + auto.addSelectionListener(new CommentSelectionListener(context, AUTO)); + + balancing = new Button(commentGroup, support, SWT.RADIO); + balancing.setText("B"); + balancing.setSelectionFactory(new CommentRadioSelectionFactory("B")); + balancing.addSelectionListener(new CommentSelectionListener(context, "B")); + + reinforcing = new Button(commentGroup, support, SWT.RADIO); + reinforcing.setText("R"); + reinforcing.setSelectionFactory(new CommentRadioSelectionFactory("R")); + reinforcing.addSelectionListener(new CommentSelectionListener(context, "R")); + + other = new Button(commentGroup, support, SWT.RADIO); + other.setText("other"); + other.setSelectionFactory(new OtherCommentSelectionFactory(new String[] {null, "B", "R", AUTO})); + other.addSelectionListener(new CommentSelectionListener(context, "")); + + loopComment = new TrackedText(commentGroup, support, SWT.BORDER); + loopComment.setTextFactory(new OtherCommentStringPropertyFactory()); + loopComment.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.Loop_Comment)); + + rotationGroup = new Group(composite, SWT.NONE); + rotationGroup.setText("Direction of Rotation"); + + inside = new Button(rotationGroup, support, SWT.RADIO); + inside.setText("Clockwise"); + inside.setSelectionFactory(new ClockwiseRotationRadioSelectionFactory(true)); + inside.addSelectionListener(new ClockwiseRotationSelectionListener(context, true)); + + outside = new Button(rotationGroup, support, SWT.RADIO); + outside.setText("Counterclockwise"); + outside.setSelectionFactory(new ClockwiseRotationRadioSelectionFactory(false)); + outside.addSelectionListener(new ClockwiseRotationSelectionListener(context, false)); + + addListeners(context); + } + + private void addListeners(ISessionContext context) { + // Item factory for loopItemsDropdown combo + loopItemsDropdown.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, final Resource input) throws DatabaseException { + + LoopTab.this.resource = input; + Map map = new HashMap(); + List> loops = LoopUtils.getAllLoopsInDiagram(graph, input); + map.put("", null); + for (List loop : loops) { + map.put(LoopUtils.cycleToString(graph, loop), loop); + } + return map; + } + }); + + // Initial selection to the combo + loopItemsDropdown.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource itemListResource = graph.getPossibleObject(input, sr.Loop_Items); + + // If the loop hasn't been defined, return empty. + if (itemListResource == null) { + return ""; + } + List itemList = ListUtils.toPossibleList(graph, itemListResource); + if (itemList == null) { + return ""; + } + + // See if the defined loop still exists. + List> loops = LoopUtils.getAllLoopsInDiagram(graph, input); + Resource first = itemList.get(0); + for (List loop : loops) { + // If the loops are of different size, continue. + if (loop.size() != itemList.size()) + continue; + + // If the first element of the sought loop is not found, continue. + int indexOfFirst = loop.indexOf(first); + if (indexOfFirst < 0) { + continue; + } + + // Check if the loops are the same, + // even if they start at different Resources + boolean match = true; + int i = 1;// = indexOfFirst + 1; + do { + // Get the next Resource in the loop + Resource next = loop.get((i + indexOfFirst) % loop.size()); + // If it is other than what should be, continue to the next loop. + if (!next.equalsResource(itemList.get(i))) { + match = false; + break; + } + } while (++i != itemList.size()); + if (!match) + continue; + + return LoopUtils.cycleToString(graph, loop); + } + + // No match found, hence empty + return ""; + } + }); + + // Modify listener for selecting loop items + loopItemsDropdown.addModifyListener(new ComboModifyListenerImpl() { + + @SuppressWarnings("unchecked") + @Override + public void applyText(WriteGraph graph, final Resource input, String text) throws DatabaseException { + final Combo c = loopItemsDropdown.getWidget(); + Display.getDefault().asyncExec(new Runnable() { + public void run() { + Object o = c.getData(); + if (o != null && !(o instanceof HashMap)) + return; + + Object loopObject = ((HashMap)o).get(c.getText()); + if (loopObject == null || !(loopObject instanceof List)) + return; + + final List loop = (List)loopObject; + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource loopResource = graph.getPossibleObject(input, sr.Loop_Items); + // Delete the current list if it exists. + if (loopResource != null) { + List removedList = ListUtils.toPossibleList(graph, loopResource); + for (Resource r : removedList) + ListUtils.removeElement(graph, loopResource, r); + graph.deny(loopResource); + } + // Create new list. + Resource newList = ListUtils.create(graph, loop); + graph.claim(input, sr.Loop_Items, newList); + } + }); + } + }); + + } + }); + } + + @Override + protected void createControlLayoutVertical() { + GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(loopItems); + GridLayoutFactory.fillDefaults().numColumns(1).applyTo(loopItems); + GridDataFactory.fillDefaults().grab(false, false).applyTo(loopItemsLabel); + GridDataFactory.fillDefaults().grab(true, false).applyTo(loopItemsDropdown.getWidget()); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(1).applyTo(composite); + + GridDataFactory.fillDefaults().grab(true, false).applyTo(commentGroup); + GridLayoutFactory.fillDefaults().numColumns(5).applyTo(commentGroup); + + GridDataFactory.fillDefaults().grab(true, false).applyTo(loopComment.getWidget()); + GridDataFactory.fillDefaults().grab(false, false).applyTo(rotationGroup); + GridLayoutFactory.fillDefaults().applyTo(rotationGroup); + } + + @Override + protected void createControlLayoutHorizontal(boolean wideScreen) { + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(loopItems); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(loopItems); + GridDataFactory.fillDefaults().grab(false, false).applyTo(loopItemsLabel); + GridDataFactory.fillDefaults().grab(true, false).applyTo(loopItemsDropdown.getWidget()); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + GridDataFactory.fillDefaults().grab(true, false).applyTo(commentGroup); + GridLayoutFactory.fillDefaults().numColumns(5).applyTo(commentGroup); + + GridDataFactory.fillDefaults().grab(true, false).applyTo(loopComment.getWidget()); + GridDataFactory.fillDefaults().grab(false, false).applyTo(rotationGroup); + GridLayoutFactory.fillDefaults().applyTo(rotationGroup); + } + + class OtherCommentStringPropertyFactory extends ReadFactoryImpl { + + private final String propertyURI; + + public OtherCommentStringPropertyFactory() { + this.propertyURI = SysdynResource.URIs.Loop_Comment; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple((Resource)inputContents, propertyURI, getClass()); + } + + @Override + public String perform(ReadGraph graph, Resource resource) throws DatabaseException { + String value = graph.getPossibleRelatedValue(resource, graph.getResource(propertyURI));; + if (value == null || AUTO.equals(value)) + return ""; + return value; + } + } + + class ClockwiseRotationSelectionListener extends SelectionListenerImpl { + private boolean clockwise; + + public ClockwiseRotationSelectionListener(ISessionContext context, boolean clockwise) { + super(context); + this.clockwise = clockwise; + } + + @Override + public void apply(WriteGraph graph, Resource component) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + Resource symbol = graph.getPossibleObject(component, mr.ComponentToElement); + if(symbol != null) { + graph.deny(symbol, sr.LoopSymbol_Clockwise); + graph.claimLiteral(symbol, sr.LoopSymbol_Clockwise, clockwise); + } + } + + } + + class ClockwiseRotationRadioSelectionFactory extends ReadFactoryImpl { + private boolean clockwise; + + public ClockwiseRotationRadioSelectionFactory(boolean clockwise) { + this.clockwise = clockwise; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple>(inputContents, clockwise, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, Resource component) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + Resource symbol = graph.getPossibleObject(component, mr.ComponentToElement); + if(symbol != null) { + Boolean clockwise = graph.getPossibleRelatedValue(symbol, sr.LoopSymbol_Clockwise, Bindings.BOOLEAN); + return ObjectUtils.objectEquals(this.clockwise, clockwise); + } + return Boolean.TRUE; + } + } + + class CommentSelectionListener extends SelectionListenerImpl { + private String comment; + + public CommentSelectionListener(ISessionContext context, String comment) { + super(context); + this.comment = comment; + } + + @Override + public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + graph.deny(connectionElement, sr.Loop_Comment); + graph.claimLiteral(connectionElement, sr.Loop_Comment, comment.trim()); + } + + } + + class CommentRadioSelectionFactory extends ReadFactoryImpl { + private String comment; + + public CommentRadioSelectionFactory(String comment) { + this.comment = comment; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple>(inputContents, comment, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + String comment = graph.getPossibleRelatedValue(dependencyConnection, sr.Loop_Comment, Bindings.STRING); + if(comment == null && this.comment.equals("")) + return true; + return ObjectUtils.objectEquals(comment, this.comment); + } + } + + class OtherCommentSelectionFactory extends ReadFactoryImpl { + + String[] limits; + + public OtherCommentSelectionFactory(String[] limits) { + this.limits = limits; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Pair>(inputContents, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + String comment = graph.getPossibleRelatedValue(dependencyConnection, sr.Loop_Comment, Bindings.STRING); + for(String s : limits) { + if(ObjectUtils.objectEquals(comment, s)) + return false; + } + return true; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleInputTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleInputTab.java new file mode 100644 index 00000000..0b5b3d68 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleInputTab.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; + +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.modules.ModuleInputEditingSupport; +import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceRow; +import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceRowLabelProvider; +import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceTable; +import org.simantics.sysdyn.ui.properties.widgets.modules.RowProvider; + +public class ModuleInputTab extends LabelPropertyTabContributor { + + public static final String FIRSTCOLUMN = "Input in Module"; + public static final String SECONDCOLUMN = "Refers to output"; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + ReferenceTable referenceTable = new ReferenceTable(body, support, SWT.NONE); + + String[] titles = { FIRSTCOLUMN, SECONDCOLUMN}; + int[] bounds = { 200, 200 }; + for (int i = 0; i < titles.length; i++) { + TableViewerColumn column = new TableViewerColumn(referenceTable.getTableViewer(), SWT.NONE); + column.getColumn().setText(titles[i]); + column.getColumn().setWidth(bounds[i]); + column.getColumn().setResizable(true); + column.getColumn().setMoveable(false); + // enable editing support + column.setEditingSupport(new ModuleInputEditingSupport(referenceTable.getTableViewer(), i)); + } + referenceTable.setContentProvider (new ArrayContentProvider()); + referenceTable.setLabelProvider (new ReferenceRowLabelProvider()); + + RowProvider rp = new RowProvider() { + + @Override + public ArrayList getRows(ReadGraph graph, Resource module) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + ArrayList result = new ArrayList(); + Resource instanceOf = graph.getPossibleObject(module, l0.InstanceOf); + if(instanceOf == null) return result; + Resource configuration = graph.getSingleObject(instanceOf, sr2.IsDefinedBy); + for(Resource input : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Input))) { + if(!graph.getObjects(input, sr.Variable_isHeadOf).isEmpty()) + continue; // Only inputs with tail dependencies allowed. + + Resource dependency = null; + for(Resource dep : graph.getObjects(module, sr.Variable_isHeadOf)) { + Resource refersTo = graph.getPossibleObject(dep, sr.Dependency_refersTo); + if(refersTo != null && refersTo.equals(input)) { + dependency = dep; + break; + } + } + ReferenceRow rr = new ReferenceRow(module, dependency, input); + result.add(rr); + } + return result; + } + }; + referenceTable.setRowProvider(rp); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleOutputTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleOutputTab.java new file mode 100644 index 00000000..ef0e5cc4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleOutputTab.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; + +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.modules.ModuleOutputEditingSupport; +import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceRow; +import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceRowLabelProvider; +import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceTable; +import org.simantics.sysdyn.ui.properties.widgets.modules.RowProvider; + +public class ModuleOutputTab extends LabelPropertyTabContributor { + + public static final String FIRSTCOLUMN = "Output in module"; + public static final String SECONDCOLUMN = "Referes to input"; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + ReferenceTable referenceTable = new ReferenceTable(body, support, SWT.NONE); + + String[] titles = { FIRSTCOLUMN, SECONDCOLUMN}; + int[] bounds = { 200, 200 }; + for (int i = 0; i < titles.length; i++) { + TableViewerColumn column = new TableViewerColumn(referenceTable.getTableViewer(), SWT.NONE); + column.getColumn().setText(titles[i]); + column.getColumn().setWidth(bounds[i]); + column.getColumn().setResizable(true); + column.getColumn().setMoveable(false); + // enable editing support + column.setEditingSupport(new ModuleOutputEditingSupport(referenceTable.getTableViewer(), i)); + } + referenceTable.setContentProvider (new ArrayContentProvider()); + referenceTable.setLabelProvider (new ReferenceRowLabelProvider()); + + RowProvider rp = new RowProvider() { + + @Override + public ArrayList getRows(ReadGraph graph, Resource module) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + ArrayList result = new ArrayList(); + Resource instanceOf = graph.getPossibleObject(module, l0.InstanceOf); + if(instanceOf == null) return result; + Resource configuration = graph.getSingleObject(instanceOf, sr2.IsDefinedBy); + for(Resource variable : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Variable))) { + if(!graph.hasStatement(variable, sr.IsOutput)) continue; + + Resource dependency = null; + for(Resource dep : graph.getObjects(module, sr.Variable_isTailOf)) { + Resource refersTo = graph.getPossibleObject(dep, sr.Dependency_refersTo); + if(refersTo != null && refersTo.equals(variable)) { + dependency = dep; + break; + } + } + ReferenceRow rr = new ReferenceRow(module, dependency, variable); + result.add(rr); + } + return result; + } + }; + referenceTable.setRowProvider(rp); + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleParameterTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleParameterTab.java new file mode 100644 index 00000000..42220661 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleParameterTab.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; +import org.simantics.utils.datastructures.ArrayMap; + +public class ModuleParameterTab extends LabelPropertyTabContributor { + + GraphExplorerComposite explorer; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite); + + explorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER); + + explorer.setBrowseContexts(SysdynResource.URIs.Module_ParameterOverrideBrowseContext); + explorer.setColumns(ColumnKeys.MODULE_PARAMETER_COLUMNS); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + + explorer.finish(); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + explorer); + + Control c = explorer.getExplorerControl(); + if (c instanceof Tree) + ((Tree) c).setLinesVisible(true); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTab.java new file mode 100644 index 00000000..030746cc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTab.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; +import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameInputValidator; +import org.simantics.utils.datastructures.ArrayMap; + +public class ModuleTab extends LabelPropertyTabContributor implements Widget { + + GraphExplorerComposite enumerationRedeclarationExplorer; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + support.register(this); + + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite); + TrackedText nameText = new TrackedText(composite, support, SWT.BORDER); + nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName)); + nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName)); + nameText.setInputValidator(new VariableNameInputValidator(support)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget()); + + Label label = new Label(composite, SWT.NONE); + label.setText("Replaceable enumerations"); + enumerationRedeclarationExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI); + + enumerationRedeclarationExplorer + .setBrowseContexts(SysdynResource.URIs.EnumerationReplacement); + enumerationRedeclarationExplorer.setColumns(ColumnKeys.ENUMERATION_REDECLARATION_COLUMNS); + enumerationRedeclarationExplorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + + enumerationRedeclarationExplorer.finish(); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + enumerationRedeclarationExplorer); + + Control c = enumerationRedeclarationExplorer.getExplorerControl(); + if (c instanceof Tree) + ((Tree) c).setLinesVisible(true); + + } + + + @Override + public void setInput(ISessionContext context, Object input) { + enumerationRedeclarationExplorer.setInput(context, input); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTypeTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTypeTab.java new file mode 100644 index 00000000..79ebe9ab --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTypeTab.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.properties.widgets.factories.ModuleTypeNameInputValidator; + +public class ModuleTypeTab extends LabelPropertyTabContributor { + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(composite); + TrackedText nameText = new TrackedText(composite, support, SWT.BORDER); + nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName)); + nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName)); + nameText.setInputValidator(new ModuleTypeNameInputValidator(support)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget()); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/PlaybackExperimentTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/PlaybackExperimentTab.java new file mode 100644 index 00000000..4b7eb906 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/PlaybackExperimentTab.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.management.ISessionContext; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.utils.datastructures.Triple; +import org.simantics.utils.ui.color.Color; +import org.simantics.utils.ui.color.ColorGradient; +import org.simantics.utils.ui.color.ColorValue; + +public class PlaybackExperimentTab extends LabelPropertyTabContributor { + + private static int gradientWidth = 250; + private static int gradientHeight = 20; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite); + + Group gradientGroup = new Group(composite, SWT.NONE); + gradientGroup.setText("Color scale"); + GridDataFactory.fillDefaults().applyTo(gradientGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(gradientGroup); + + + ColorValue cv1 = new ColorValue(new Color(0, 62, 133), 0.0); + ColorValue cv2 = new ColorValue(new Color(255, 230, 0), 1.0); + ColorValue[] values = new ColorValue[] {cv1, cv2}; + ColorGradient cg = new ColorGradient(values, ColorGradient.HSV); + Image image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL); + Button b = new Button(gradientGroup, support, SWT.RADIO); + GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget()); + b.setImage(image); + b.addSelectionListener(new GradientSelectionListener(context, values)); + b.setSelectionFactory(new GradientSelectionFactory(values)); + + cv1 = new ColorValue(new Color(255, 230, 0), 0.0); + cv2 = new ColorValue(new Color(0, 62, 133), 1.0); + values = new ColorValue[] {cv1, cv2}; + cg = new ColorGradient(values, ColorGradient.HSV); + image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL); + b = new Button(gradientGroup, support, SWT.RADIO); + GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget()); + b.setImage(image); + b.addSelectionListener(new GradientSelectionListener(context, values)); + b.setSelectionFactory(new GradientSelectionFactory(values)); + + cv1 = new ColorValue(new Color(0, 0, 0), 0.0); + cv2 = new ColorValue(new Color(255, 255, 255), 1.0); + values = new ColorValue[] {cv1, cv2}; + cg = new ColorGradient(values, ColorGradient.HSV); + image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL); + b = new Button(gradientGroup, support, SWT.RADIO); + GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget()); + b.setImage(image); + b.addSelectionListener(new GradientSelectionListener(context, values)); + b.setSelectionFactory(new GradientSelectionFactory(values)); + + cv1 = new ColorValue(new Color(0, 0, 255), 0.0); + cv2 = new ColorValue(new Color(255, 0, 0), 1.0); + values = new ColorValue[] {cv1, cv2}; + cg = new ColorGradient(values, ColorGradient.HSV); + image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL); + b = new Button(gradientGroup, support, SWT.RADIO); + GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget()); + b.setImage(image); + b.addSelectionListener(new GradientSelectionListener(context, values)); + b.setSelectionFactory(new GradientSelectionFactory(values)); + + + cv1 = new ColorValue(new Color(255, 0, 0), 0.0); + cv2 = new ColorValue(new Color(0, 0, 255), 1.0); + values = new ColorValue[] {cv1, cv2}; + cg = new ColorGradient(values, ColorGradient.HSV); + image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL); + b = new Button(gradientGroup, support, SWT.RADIO); + GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget()); + b.setImage(image); + b.addSelectionListener(new GradientSelectionListener(context, values)); + b.setSelectionFactory(new GradientSelectionFactory(values)); + } + + + class GradientSelectionListener extends SelectionListenerImpl { + private ArrayList colorValues; + + public GradientSelectionListener(ISessionContext context, ColorValue[] colorValues) { + super(context); + this.colorValues = new ArrayList(); + for(ColorValue cv : colorValues) + this.colorValues.add(cv); + } + + @Override + public void apply(WriteGraph graph, Resource experiment) throws DatabaseException { + G2DResource g2d = G2DResource.getInstance(graph); + + Resource gradient = graph.getPossibleObject(experiment, g2d.HasColorGradient); + + if(gradient != null) { + graph.denyStatement(experiment, g2d.HasColorGradient, gradient); + RemoverUtil.remove(graph, gradient); + } + + gradient = GraphUtils.create2(graph, g2d.ColorGradient); + graph.claim(experiment, g2d.HasColorGradient, gradient); + + for(ColorValue cv : colorValues) { + Resource placement = GraphUtils.create2(graph, g2d.ColorPlacement, + g2d.HasGradientPosition, cv.getValue()); + graph.claimLiteral(placement, g2d.HasColor, g2d.Color, cv.getColor().getAWTColor().getColorComponents(new float[4])); + graph.claim(gradient, g2d.HasColorPlacement, placement); + } + } + + } + + class GradientSelectionFactory extends ReadFactoryImpl { + private ArrayList colorValues; + + public GradientSelectionFactory(ColorValue[] colorValues) { + this.colorValues = new ArrayList(); + for(ColorValue cv : colorValues) + this.colorValues.add(cv); + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple>(inputContents, colorValues, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, Resource experiment) throws DatabaseException { + G2DResource g2d = G2DResource.getInstance(graph); + Resource gradient = graph.getPossibleObject(experiment, g2d.HasColorGradient); + if(gradient == null) { + return Boolean.FALSE; + } + Collection placements = graph.syncRequest(new ObjectsWithType(gradient, g2d.HasColorPlacement, g2d.ColorPlacement)); + if(placements.isEmpty()) + return Boolean.FALSE; + + for(Resource placement : placements) { + Double position = graph.getPossibleRelatedValue(placement, g2d.HasGradientPosition); + if(position == null) + return Boolean.FALSE; + int index = -1; + + // First look for a color with matching value + for(int i = 0; i < colorValues.size(); i++) { + if(position.equals(colorValues.get(i).getValue())) { + + index = i; + break; + } + } + + // If matching value was found, see if the color is the same + if(index >= 0) { + Color c = colorValues.get(index).getColor(); + float[] cArray = c.getAWTColor().getColorComponents(new float[4]); + float[] color = graph.getPossibleRelatedValue(placement, g2d.HasColor, Bindings.FLOAT_ARRAY); + for(int i = 0; i < color.length; i++) { + if(cArray[i] != color[i]) + // Some inconsistency found in colors, return false + return Boolean.FALSE; + } + } + } + + // Everything matched + return Boolean.TRUE; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ReferenceDependencyTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ReferenceDependencyTab.java new file mode 100644 index 00000000..cc8f4384 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ReferenceDependencyTab.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; + +public class ReferenceDependencyTab extends LabelPropertyTabContributor { + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/RemoveFocusBeforeExperimentComposite.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/RemoveFocusBeforeExperimentComposite.java new file mode 100644 index 00000000..1966eccf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/RemoveFocusBeforeExperimentComposite.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.swt.widgets.Composite; +import org.simantics.sysdyn.ui.utils.HandlerUtils; + +/** + * Composite for providing info for {@link HandlerUtils}.saveBeforeExperimentRun to force focus + * of text and other widgets before simulation. Forcing focus off makes the widget to save its value. + * @author Teemu Lempinen + * + */ +public class RemoveFocusBeforeExperimentComposite extends Composite { + + public RemoveFocusBeforeExperimentComposite(Composite parent, int style) { + super(parent, style); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java new file mode 100644 index 00000000..1fb36162 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java @@ -0,0 +1,536 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.model.nodetypes.NodeType; +import org.simantics.browsing.ui.model.nodetypes.SpecialNodeType; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.layer0.request.PossibleActiveVariableFromVariable; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.jfreechart.ChartSelectionTabContributor; +import org.simantics.jfreechart.chart.properties.xyline.XYLineGeneralPropertiesTab; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.ui.property.svg.SVGElementComposite; +import org.simantics.selectionview.ComparableTabContributor; +import org.simantics.selectionview.SelectionProcessor; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder; +import org.simantics.sysdyn.ui.trend.SensitivityChartAxisAndVariablesTab; +import org.simantics.ui.selection.AnyVariable; +import org.simantics.ui.selection.WorkbenchSelectionElement; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * SelectionProcessor for processing selections for property view in system dynamics + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ResourceSelectionProcessor implements SelectionProcessor { + + private SpecialNodeType sharedFunctionsTestNode; + + @Override + public Collection process(Object selection, ReadGraph backend) { + List tabs = new ArrayList(); + SysdynResource sr = SysdynResource.getInstance(backend); + DiagramResource dr = DiagramResource.getInstance(backend); + ModelingResources mr = ModelingResources.getInstance(backend); + SimulationResource simu = SimulationResource.getInstance(backend); +// JFreeChartResource jfree = JFreeChartResource.getInstance(backend); + + // Test nodes + if(sharedFunctionsTestNode == null) + sharedFunctionsTestNode = new SpecialNodeType(sr.ModelingBrowseContext_SharedFunctionsFolder, Resource.class); + + try { + // Many elements + if (selection instanceof ArrayList && ((ArrayList) selection).size() > 1) { + List variables = new ArrayList(); + List dependencies = new ArrayList(); + List flows = new ArrayList(); + Resource model = null; + for(Object o : (ArrayList)selection) { + Resource r = AdaptionUtils.adaptToSingle(o, Resource.class); + if (r == null) + continue; + Resource component = backend.getPossibleObject(r, mr.ElementToComponent); + if (component != null) { + r = component; + } else { + // Try connection + Resource connection = backend.getPossibleObject(r, mr.DiagramConnectionToConnection); + if(connection != null) + r = connection; + } + + if(r != null) { + if(model == null) + model = backend.getPossibleObject(r, Layer0.getInstance(backend).PartOf); + if(model != null && model.equals( backend.getSingleObject(r, Layer0.getInstance(backend).PartOf))) { + if (backend.isInstanceOf(r, sr.Variable)) { + variables.add(r); + } else if (backend.isInstanceOf(r, sr.Dependency)) { + Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection); + dependencies.add(diaConnection); + } else if (backend.isInstanceOf(r, sr.Flow)) { + Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection); + flows.add(diaConnection); + } + } + } + } + + if (!variables.isEmpty()) + // Do we have at least one variable + tabs.add(new ComparableTabContributor( + new ArrayIndexesTab(), + 1, + variables, + "Indexes")); + else if (!dependencies.isEmpty()) { + // Dependencies only + tabs.add(new ComparableTabContributor( + new ArrayDependencyTab(), + 1, + dependencies, + "Dependency Properties")); + } + else if (!flows.isEmpty()) { + // Flows only + tabs.add(new ComparableTabContributor( + new ArrayFlowTab(), + 1, + flows, + "Flow Properties")); + } + return tabs; + } + + // Single element + Variable var = null; + WorkbenchSelectionElement wse = ISelectionUtils.filterSingleSelection(selection, WorkbenchSelectionElement.class); + if(wse != null) { + var = wse.getContent(new AnyVariable(backend)); + if(var == null) { + var = AdaptionUtils.adaptToSingle(selection, Variable.class); + if(var != null) { + Variable possibleActiveVariable = backend.syncRequest(new PossibleActiveVariableFromVariable(var)); + if(possibleActiveVariable != null) + var = possibleActiveVariable; + } + } + } + + Resource r = AdaptionUtils.adaptToSingle(selection, Resource.class); + if(r == null) { + // Selection is not directly a resource, try if it is a variable + var = AdaptionUtils.adaptToSingle(selection, Variable.class); + if(var != null) + r = var.getRepresents(backend); + } + + if(r == null) { + // SharedFunctionsFolder has properties but no adapted resource + SharedFunctionsFolder sff = AdaptionUtils.adaptToSingle(selection, SharedFunctionsFolder.class); + if (sff != null) { + return Collections.singleton(new ComparableTabContributor( + new SharedFunctionLibrariesTab(), + 2, + sff.data, + "Shared Functions")); + } + + return Collections.emptyList(); + } + + NodeContext nc = AdaptionUtils.adaptToSingle(selection, NodeContext.class); + if(nc != null) { + NodeType type = nc.getConstant(NodeType.TYPE); + if(type != null && type.equals(sharedFunctionsTestNode)) { + return Collections.singleton(new ComparableTabContributor( + new SharedFunctionLibrariesTab(), + 2, + r, + "Shared Functions")); + } + } + + // SVG elements in symbol editor + if (backend.isInstanceOf(r, dr.SVGElement)) + return Collections.singleton(SVGElementComposite.make(r, 1, "SVG")); + + // if r == diagram element, change it to component + if (backend.isInstanceOf(r, dr.Element)) { + Resource component = backend.getPossibleObject(r, mr.ElementToComponent); + if (component != null) { + r = component; + } else { + Resource connection = backend.getPossibleObject(r, mr.DiagramConnectionToConnection); + if(connection != null) + r = connection; + } + } + + + // Check that var has found the correct variable + if(r != null && var != null) { + if(!r.equals(var.getRepresents(backend))) + // Var found the wrong variable. This may happen with ModuleType editors + var = null; + } + + + // If shadow variable, display properties of the original variable + if(backend.isInstanceOf(r, sr.Shadow)) { + Resource original = backend.getPossibleObject(r, sr.Shadow_original); + if(original != null && var != null) { + r = original; + Variable parent = var.getParent(backend); + var = parent.getPossibleChild(backend, NameUtils.getSafeName(backend, r)); + } + } + + // If loop + if(backend.isInstanceOf(r, sr.Loop)) { + return Collections.singleton( + (new ComparableTabContributor( + new LoopTab(), + 1, + r, + "Loop"))); + } + + // Independent variable + if (backend.isInstanceOf(r, sr.IndependentVariable)) { + Resource activeExpression = backend.getPossibleObject(r, sr.IndependentVariable_activeExpression); + Resource expression = null; + if(activeExpression != null) + // if variable has active expression, display it + expression = activeExpression; + else if (backend.hasStatement(r, sr.Variable_expressionList)){ + // else display the first expression of the variable + Resource expressions = backend.getPossibleObject(r, sr.Variable_expressionList); + List expressionList = ListUtils.toList(backend, expressions); + if(expressionList.isEmpty()) { + System.err.println("expressionList is empty for " + r); + return Collections.emptyList(); + } + expression = expressionList.get(0); + } + tabs.add(new ComparableTabContributor( + new EquationTab(), + 3, + var != null ? var : r, + "Equation")); + if(expression != null && backend.isInstanceOf(expression, sr.WithLookupExpression)) { + // WithLookupExpression has its own extra tab for visual configuration + tabs.add(new ComparableTabContributor( + new LookupTableTab(), + 2, + expression, + "Lookup Table")); + } + + tabs.add(new ComparableTabContributor( + new ArrayIndexesTab(), + 1, + r, + "Indexes")); + + tabs.add(new ComparableTabContributor( + new VariableInformationTab(), + 0, + r, + "Additional Information")); + return tabs; + } + + // Input variable + if (backend.isInstanceOf(r, sr.Input)) { + tabs.add(new ComparableTabContributor( + new InputVariableTab(), + 2, + r, + "Input")); + + tabs.add(new ComparableTabContributor( + new ArrayIndexesTab(), + 1, + r, + "Indexes")); + + tabs.add(new ComparableTabContributor( + new VariableInformationTab(), + 0, + r, + "Additional Information")); + return tabs; + } + + // Enumeration + if (backend.isInstanceOf(r, sr.Enumeration)) { + Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class); + if(s == null) + s = r; + // give either variable or the actual resource + return Collections.singleton(new ComparableTabContributor( + new EnumerationTab(), + 2, + s, + "Enumeration")); + } + + // Configuration and model. They both show the properties of the configuration + if ( backend.isInstanceOf(r, sr.Configuration) || backend.isInstanceOf(r, sr.SysdynModel)) { + if(!backend.isInstanceOf(r, sr.SysdynModel)) + r = backend.getPossibleObject(r, SimulationResource.getInstance(backend).IsConfigurationOf); + if (r != null) + return Collections.singleton( + new ComparableTabContributor( + new ConfigurationTab(), + 0, + r, + "Model Properties")); + } + + // Module + if (backend.isInstanceOf(r, sr.Module)){ + tabs.add(new ComparableTabContributor( + new ModuleTab(), + 10, + r, + "Module Properties")); + tabs.add(new ComparableTabContributor( + new ModuleParameterTab(), + 9, + r, + "Parameters")); + tabs.add(new ComparableTabContributor( + new ModuleInputTab(), + 2, + r, + "Inputs")); + tabs.add(new ComparableTabContributor( + new ModuleOutputTab(), + 1, + r, + "Outputs")); + return tabs; + } + + // Playback experiment + if (backend.isInstanceOf(r, sr.PlaybackExperiment)) + return Collections.singleton( + new ComparableTabContributor( + new PlaybackExperimentTab(), + 0, + r, + "Experiment Properties")); + + // Game experiment + if (backend.isInstanceOf(r, sr.GameExperiment)) + return Collections.singleton( + new ComparableTabContributor( + new GameExperimentTab(), + 0, + r, + "Experiment Properties")); + + // Sensitivity analysis experiment + if (backend.isInstanceOf(r, sr.SensitivityAnalysisExperiment)) + return Collections.singleton( + new ComparableTabContributor( + new SensitivityAnalysisExperimentTab(), + 0, + r, + "Experiment Properties")); + + // Default experiment + if (backend.isInstanceOf(r, simu.Experiment)) + return Collections.singleton( + new ComparableTabContributor( + new ExperimentTab(), + 0, + r, + "Experiment Properties")); + + // History data + if (backend.isInstanceOf(r, sr.HistoryDataset)) + return Collections.singleton( + new ComparableTabContributor( + new HistoryDataTab(), + 0, + r, + "History Data Properties")); + + // Saved simulation result + if (backend.isInstanceOf(r, sr.Result)) + return Collections.singleton( + new ComparableTabContributor( + new ResultTab(), + 0, + r, + "Result Properties")); + + // Dependency + if (backend.isInstanceOf(r, sr.Dependency)) + if (backend.hasStatement(r, sr.Dependency_refersTo)) { + Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection); + return Collections.singleton( + new ComparableTabContributor( + new DependencyTab(), + 0, + diaConnection, + "Reference Properties")); + } else { + Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection); + return Collections.singleton( + new ComparableTabContributor( + new DependencyTab(), + 0, + diaConnection, + "Dependency Properties")); + } + + // Flow + if (backend.isInstanceOf(r, sr.Flow)) { + Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection); + return Collections.singleton( + new ComparableTabContributor( + new FlowTab(), + 0, + diaConnection, + "Flow Properties")); + } + + // Module symbol. Modules in modules-folder are actually symbol resources + if (backend.isInheritedFrom(r, sr.ModuleSymbol)) { + // Find the component resource + r = backend.getPossibleObject(r, mr.SymbolToComponentType); + if(r != null) + return Collections.singleton( + new ComparableTabContributor( + new ModuleTypeTab(), + 0, + r, + "Module Type Properties")); + } + + // Function + if (backend.isInstanceOf(r, sr.SysdynModelicaFunction)) { + tabs.add(new ComparableTabContributor( + new FunctionTab(), + 2, + r, + "Function")); + tabs.add(new ComparableTabContributor( + new ExternalFilesTab(), + 1, + r, + "External files")); + return tabs; + } + + // Function library + if (backend.isInstanceOf(r, sr.SysdynModelicaFunctionLibrary)) { + Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class); + if(s == null) + s = r; + // give either variable or the actual resource + return Collections.singleton(new ComparableTabContributor( + new FunctionLibraryTab(), + 2, + s, + "Function library")); + } + + // Try sensitivity chart before other charts + if (contributeSensitivityChart(backend, r, tabs)) { + return tabs; + } + + // Try normal charts + if (ChartSelectionTabContributor.contibuteTabs(backend, r, tabs)) { + return tabs; + } + + // Default experiment + if (backend.isInstanceOf(r, sr.AdditionalSymbols_MultilineText)) + return Collections.singleton( + new ComparableTabContributor( + new CommentTab(), + 0, + r, + "Comment")); + + } catch (ServiceException e) { + e.printStackTrace(); + } catch (ManyObjectsForFunctionalRelationException e) { + e.printStackTrace(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return Collections.emptyList(); + } + + public static boolean contributeSensitivityChart(ReadGraph backend, Resource r, List tabs) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(backend); + if(backend.isInstanceOf(r, jfree.ChartElement)) { + if(backend.hasStatement(r, jfree.ChartElement_component)) + r = backend.getSingleObject(r, jfree.ChartElement_component); + } + + if (backend.isInstanceOf(r, jfree.Chart)) { + + Collection plots = backend.syncRequest(new ObjectsWithType(r, Layer0.getInstance(backend).ConsistsOf, jfree.Plot)); + if(!plots.isEmpty()) { + Resource plot = plots.iterator().next(); + + if(backend.isInstanceOf(plot, SysdynResource.getInstance(backend).Charts_SensitivityPlot)) { + tabs.add(new ComparableTabContributor( + new XYLineGeneralPropertiesTab(), + 10, + r, + "General")); + tabs.add(new ComparableTabContributor( + new SensitivityChartAxisAndVariablesTab(), + 9, + r, + "Axis and Variables")); + return true; + } + } + } + return false; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResultTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResultTab.java new file mode 100644 index 00000000..306cd840 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResultTab.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.management.ISessionContext; + +public class ResultTab extends LabelPropertyTabContributor { + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SensitivityAnalysisExperimentTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SensitivityAnalysisExperimentTab.java new file mode 100644 index 00000000..2001b02f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SensitivityAnalysisExperimentTab.java @@ -0,0 +1,545 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.BuiltinKeys; +import org.simantics.browsing.ui.Column; +import org.simantics.browsing.ui.Column.Align; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.common.NodeContextBuilder.MapNodeContext; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.procedure.adapter.DisposableListener; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.jfreechart.chart.properties.RangeComposite; +import org.simantics.jfreechart.chart.properties.xyline.AxisAndVariablesExplorerComposite; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.factories.IntegerPropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.IntegerPropertyModifier; +import org.simantics.sysdyn.ui.properties.widgets.sensitivity.DistributionPropertyWidget; +import org.simantics.sysdyn.ui.properties.widgets.sensitivity.ParameterChildRule; +import org.simantics.sysdyn.ui.properties.widgets.sensitivity.VariableNameModifier; +import org.simantics.sysdyn.ui.validation.ParameterExistsValidator; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.RunnableWithObject; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.ui.validators.IntegerValidator; + +/** + * Tab for displaying sensitivity analysis experiment properties + * + * @author Tuomas Miettinen + * + */ +public class SensitivityAnalysisExperimentTab extends LabelPropertyTabContributor implements Widget { + + private GraphExplorerComposite explorer; + private WidgetSupportImpl parameterSupport = new WidgetSupportImpl(); + private ScrolledComposite propertyContainer; + private Composite parameterProperties; + private Composite content; + private Button remove; + private Resource experiment; + + private boolean dirty = false; + private boolean dirtyMethod = false; + + private DisposableListener> contentListener; + + @Override + public void createControls(Composite body, IWorkbenchSite site, + final ISessionContext context, final WidgetSupport support) { + support.register(this); + + Composite composite = new RemoveFocusBeforeExperimentComposite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite); + + // Scrolled composite for displaying properties of a selection in explorer + propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().grab(true, true).applyTo(propertyContainer); + GridLayoutFactory.fillDefaults().applyTo(propertyContainer); + propertyContainer.setExpandHorizontal(true); + propertyContainer.setExpandVertical(true); + + content = new Composite(propertyContainer, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(content); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(content); + + // Label + Composite labelComposite = new Composite(content, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(labelComposite); + GridLayoutFactory.fillDefaults().numColumns(8).applyTo(labelComposite); + Label label = new Label(labelComposite, SWT.NONE); + label.setText("Name"); + + TrackedText name = new TrackedText(labelComposite, support, SWT.BORDER); + name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel)); + name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName)); + name.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), name.getWidget()))); + GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget()); + + label = new Label(labelComposite, SWT.NONE); + label.setText("Number of runs"); + + TrackedText n = new TrackedText(labelComposite, support, SWT.BORDER); + n.setTextFactory(new IntegerPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_numberOfValues)); + n.addModifyListener(new IntegerPropertyModifier(context, SysdynResource.URIs.SensitivityAnalysisExperiment_numberOfValues)); + n.setInputValidator(new IntegerValidator()); + n.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), n.getWidget()))); + GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).applyTo(n.getWidget()); + + label = new Label(labelComposite, SWT.NONE); + label.setText("Method"); + + TrackedCombo methodSelector = new TrackedCombo(labelComposite, support, SWT.DROP_DOWN); + methodSelector.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, Resource input) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + Map items = new HashMap(); + + items.put("Halton", SR.HaltonSequenceGenerator); + items.put("Random", SR.RandomGenerator); + + return items; + } + + }); + methodSelector.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, Resource parameter) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + Resource method = graph.getPossibleObject(parameter, SR.SensitivityAnalysisExperiment_method); + if(method == null) + return null; + + if(graph.isInstanceOf(method, SR.RandomGenerator)) + return "Random"; + else if(graph.isInstanceOf(method, SR.HaltonSequenceGenerator)) + return "Halton"; + else + return ""; + + } + }); + methodSelector.addModifyListener(new ComboModifyListenerImpl() { + + @Override + public void applyText(WriteGraph graph, Resource input, String text) + throws DatabaseException { + if(text == null || text.isEmpty()) + return; + + SysdynResource SR = SysdynResource.getInstance(graph); + + Resource type = SR.RandomGenerator; + + if("Halton".equals(text)) + type = SR.HaltonSequenceGenerator; + + graph.deny(input, SR.SensitivityAnalysisExperiment_method); + + GraphUtils.create2(graph, type, + SR.SensitivityAnalysisExperiment_method_Inverse, input); + + dirtyMethod = true; + } + }); + methodSelector.addModifyListener(new TextModifyListener() { + + @Override + public void modifyText(TrackedModifyEvent e) { + if(dirtyMethod) { + support.update(); + dirtyMethod = false; + propertyContainer.setContent(content); + Point size = content.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } + } + }); + + label = new Label(labelComposite, SWT.NONE); + label.setText("Seed"); + + TrackedText seed = new TrackedText(labelComposite, support, SWT.BORDER); + seed.setTextFactory(new IntegerPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_randomSeed)); + seed.addModifyListener(new IntegerPropertyModifier(context, SysdynResource.URIs.SensitivityAnalysisExperiment_randomSeed)); + seed.setInputValidator(new IntegerValidator()); + seed.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), seed.getWidget()))); + GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).applyTo(seed.getWidget()); + + // (Ontology-based) GraphExplorer displaying range axis and variables mapped to those axis + explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter", "treeView").values(false, false, true), site, content, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE); + + explorer.setBrowseContexts(SysdynResource.URIs.SensitivityAnalysisExperiment_ParameterBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning + explorer.setColumns( new Column[] { new Column(ColumnKeys.SINGLE, Align.LEFT, 0, "", true) }); + explorer.finish(); + + + ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateSelection(context); + } + }); + + /* Listener for displaying information of the first parameter during view initialization + * The view does not have focus, so normal selection listener mechanisms do not work. + * Need to do it the hard way. + */ + Listener listener = new Listener() { + + boolean flag = false; + @Override + public void handleEvent(Event event) { + switch (event.type) { + case SWT.Activate: + case SWT.Show: + case SWT.Paint: + { + if(!flag && ((Tree) event.widget).getItems().length > 0) { + flag = true; + TreeItem item = ((Tree) event.widget).getItems()[0]; + IAdaptable adaptable = (IAdaptable) item.getData(); + MapNodeContext nc = (MapNodeContext) adaptable.getAdapter(NodeContext.class); + parameterSupport.fireInput(context, new StructuredSelection(nc.getConstant(BuiltinKeys.INPUT))); + propertyContainer.setContent(content); + Point size = content.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } + } + } + } + }; + + Tree tree = explorer.getExplorerControl(); + tree.addListener(SWT.Activate, listener); + tree.addListener(SWT.Show, listener); + tree.addListener(SWT.Paint,listener); + /* End listener for displaying information for first parameter during view initialization*/ + + explorer.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + if(contentListener != null) + contentListener.dispose(); + } + }); + + + GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer); + + Composite buttonComposite = new Composite(explorer, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(buttonComposite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite); + + Button addVariable = new Button(buttonComposite, support, SWT.NONE); + addVariable.setText("Add parameter"); + addVariable.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + + Resource distribution = GraphUtils.create2(graph, sr.UniformDistribution, + sr.UniformDistribution_minValue, 0.0, + sr.UniformDistribution_maxValue, 10.0); + + Resource parameter = GraphUtils.create2(graph, sr.SensitivityAnalysisExperiment_Parameter, + sr.SensitivityAnalysisExperiment_Parameter_propabilityDistribution, distribution, + sr.SensitivityAnalysisExperiment_Parameter_variable, ChartUtils.emptyVariableName, + L0.PartOf, input); + + Resource parameterList = graph.getPossibleObject(input, sr.SensitivityAnalysisExperiment_parameterList); + ListUtils.insertBack(graph, parameterList, Collections.singleton(parameter)); + } + }); + + remove = new Button(buttonComposite, parameterSupport, SWT.NONE); + remove.setText("Remove"); + remove.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if(input == null) + return; + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + + Resource experiment = graph.getPossibleObject(input, L0.PartOf); + Resource parameterList = graph.getPossibleObject(experiment, sr.SensitivityAnalysisExperiment_parameterList); + + if(ListUtils.toList(graph, parameterList).size() > 1) + ListUtils.removeElement(graph, parameterList, input); + + } + + }); + + propertyContainer.setContent(content); + Point tsize = content.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(tsize); + + + Group parameterPropertyGroup = new Group(content, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(parameterPropertyGroup); + GridLayoutFactory.fillDefaults().applyTo(parameterPropertyGroup); + + parameterProperties = new Composite(parameterPropertyGroup, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, false).applyTo(parameterProperties); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parameterProperties); + + // Label + label = new Label(parameterProperties, SWT.NONE); + label.setText("Variable:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + TrackedText variable = new TrackedText(parameterProperties, parameterSupport, SWT.BORDER); + variable.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_variable)); + variable.addModifyListener(new VariableNameModifier(variable.getWidget(), parameterSupport, SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_variable, SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_indexes)); + variable.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), variable.getWidget()))); + variable.setInputValidator(new ParameterExistsValidator(parameterSupport, variable)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(variable.getWidget()); + + label = new Label(parameterProperties, SWT.NONE); + label.setText("Range:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + RangeComposite rangeComposite = new RangeComposite(parameterProperties, context, parameterSupport, SWT.NONE) { + @Override + protected Resource getIndexRelation(ReadGraph graph) { + return SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_indexes; + } + }; + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeComposite); + +// TrackedText variable = new TrackedText(parameterProperties, parameterSupport, SWT.BORDER); +// variable.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_variable)); +// variable.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_variable)); +// variable.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), variable.getWidget()))); +// GridDataFactory.fillDefaults().grab(true, false).applyTo(variable.getWidget()); + + label = new Label(parameterProperties, SWT.NONE); + label.setText("Distribution:"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + TrackedCombo distributionSelector = new TrackedCombo(parameterProperties, parameterSupport, SWT.DROP_DOWN); + distributionSelector.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, Resource input) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + Map items = new HashMap(); + + items.put("Normal", SR.NormalDistribution); + items.put("Uniform", SR.UniformDistribution); + items.put("Interval", SR.Interval); + + return items; + } + + }); + + distributionSelector.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, Resource parameter) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + Resource distribution = graph.getPossibleObject(parameter, SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution); + if(distribution == null) + return null; + + if(graph.isInstanceOf(distribution, SR.UniformDistribution)) + return "Uniform"; + else if(graph.isInstanceOf(distribution, SR.NormalDistribution)) + return "Normal"; + else if(graph.isInstanceOf(distribution, SR.Interval)) + return "Interval"; + else + return ""; + + } + }); + + distributionSelector.addModifyListener(new ComboModifyListenerImpl() { + + @Override + public void applyText(WriteGraph graph, Resource input, String text) + throws DatabaseException { + if(text == null || text.isEmpty()) + return; + + SysdynResource SR = SysdynResource.getInstance(graph); + + Resource type = SR.UniformDistribution; + + if("Normal".equals(text)) + type = SR.NormalDistribution; + else if("Interval".equals(text)) + type = SR.Interval; + + graph.deny(input, SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution); + + GraphUtils.create2(graph, type, + SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse, input); + + dirty = true; + } + }); + + distributionSelector.addModifyListener(new TextModifyListener() { + + @Override + public void modifyText(TrackedModifyEvent e) { + if(dirty) { + parameterSupport.update(); + dirty = false; + propertyContainer.setContent(content); + Point size = content.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } + } + }); + + label = new Label(parameterProperties, SWT.NONE); + + DistributionPropertyWidget dpw = new DistributionPropertyWidget(parameterProperties, context, parameterSupport, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(dpw); + + } + + + /** + * Updates the content of propertyContainer + * @param context + */ + private void updateSelection(ISessionContext context) { + ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); + IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + parameterSupport.fireInput(context, selection); + + propertyContainer.setContent(content); + Point size = content.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } + + + @Override + public void setInput(ISessionContext context, Object input) { + experiment = AdaptionUtils.adaptToSingle(input, Resource.class); + if(contentListener == null) { + contentListener = new DisposableListener>() { + + @Override + public void execute(Collection result) { + if(remove != null && !remove.getWidget().isDisposed() && result != null) { + remove.getWidget().getDisplay().asyncExec(new RunnableWithObject(result) { + @Override + public void run() { + if(!remove.getWidget().isDisposed()) { + @SuppressWarnings("unchecked") + Collection result = (Collection) getObject(); + if(result.size() > 1) + remove.getWidget().setEnabled(true); + else + remove.getWidget().setEnabled(false); + } + } + }); + + } + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + }; + + SimanticsUI.getSession().asyncRequest(new Read> () { + + @SuppressWarnings("unchecked") + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + return (Collection) new ParameterChildRule().getChildren(graph, experiment); + } + + }, contentListener); + } + + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SharedFunctionLibrariesTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SharedFunctionLibrariesTab.java new file mode 100644 index 00000000..7b0301cb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SharedFunctionLibrariesTab.java @@ -0,0 +1,238 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.swt.AdaptableHintContext; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.AdaptionUtils; + +public class SharedFunctionLibrariesTab extends LabelPropertyTabContributor implements Widget { + + GraphExplorerComposite availableSharedFunctionLibraries; + GraphExplorerComposite usedSharedFunctionLibraries; + Resource model; + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + support.register(this); + + GridLayoutFactory.fillDefaults().numColumns(4).applyTo(body); + + + Composite available = new Composite(body, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(available); + GridDataFactory.fillDefaults().grab(true, true).applyTo(available); + Label label = new Label(available, SWT.None); + label.setText("Available Shared Function Libraries"); + availableSharedFunctionLibraries = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, available, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI) { + + @Override + protected void handleDrop(Object data, NodeContext target) { + if (!(data instanceof IStructuredSelection)) + return; + + IStructuredSelection iss = (IStructuredSelection)data; + if (iss == null || iss.isEmpty()) + return; + + for (Iterator iterator = iss.iterator(); iterator.hasNext();) { + Object o = iterator.next(); + if(o instanceof IAdaptable) { + IAdaptable a = (IAdaptable)o; + final SharedFunctionLibraryNode node = (SharedFunctionLibraryNode)a.getAdapter(SharedFunctionLibraryNode.class); + if(node != null) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + if(getModel() != null && node.data != null) + graph.deny(getModel(), Layer0.getInstance(graph).IsLinkedTo, node.data); + } + }); + } + } + } + } + }; + + availableSharedFunctionLibraries + .setBrowseContexts(SysdynResource.URIs.AvailableSharedFunctionLibraries); + availableSharedFunctionLibraries.setInputSource(new SingleSelectionInputSource( + Resource.class)); + + availableSharedFunctionLibraries.finish(); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + availableSharedFunctionLibraries); + + Composite middleButtons = new Composite(body, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(middleButtons); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(false, true).applyTo(middleButtons); + + Button add = new Button(middleButtons, support, SWT.NONE); + add.setText(" -> "); + + add.addSelectionListener(new SelectionListenerImpl(context) { + + List selectedLibraries; + + public void beforeApply() { + selectedLibraries = getSelectedResources(availableSharedFunctionLibraries); + } + + @Override + public void apply(WriteGraph graph, Resource input) + throws DatabaseException { + if(selectedLibraries != null) { + Layer0 l0 = Layer0.getInstance(graph); + for(Resource library : selectedLibraries) { + graph.claim(input, l0.IsLinkedTo, library); + } + } + } + }); + + Button remove = new Button(middleButtons, support, SWT.NONE); + remove.setText(" <- "); + + remove.addSelectionListener(new SelectionListenerImpl(context) { + + List selectedLibraries; + + public void beforeApply() { + selectedLibraries = getSelectedResources(usedSharedFunctionLibraries); + } + + @Override + public void apply(WriteGraph graph, Resource input) + throws DatabaseException { + if(selectedLibraries != null) { + Layer0 l0 = Layer0.getInstance(graph); + for(Resource library : selectedLibraries) { + graph.deny(input, l0.IsLinkedTo, library); + } + } + } + }); + + + Composite used = new Composite(body, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(used); + GridDataFactory.fillDefaults().grab(true, true).applyTo(used); + label = new Label(used, SWT.None); + label.setText("Selected Shared Function Libraries"); + + usedSharedFunctionLibraries = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, used, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI) { + + @Override + protected void handleDrop(Object data, NodeContext target) { + if (!(data instanceof IStructuredSelection)) + return; + + IStructuredSelection iss = (IStructuredSelection)data; + if (iss == null || iss.isEmpty()) + return; + + for (Iterator iterator = iss.iterator(); iterator.hasNext();) { + Object o = iterator.next(); + if(o instanceof IAdaptable) { + IAdaptable a = (IAdaptable)o; + final SharedFunctionLibraryNode node = (SharedFunctionLibraryNode)a.getAdapter(SharedFunctionLibraryNode.class); + if(node != null) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + if(getModel() != null && node.data != null) + graph.claim(getModel(), Layer0.getInstance(graph).IsLinkedTo, node.data); + } + }); + } + } + } + } + }; + + usedSharedFunctionLibraries + .setBrowseContexts(SysdynResource.URIs.SelectedSharedFunctionLibraries); + usedSharedFunctionLibraries.setInputSource(new SingleSelectionInputSource( + Resource.class)); + + usedSharedFunctionLibraries.finish(); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + usedSharedFunctionLibraries); + } + + + private List getSelectedResources(GraphExplorerComposite explorer) { + List result = new ArrayList(); + + ISelection selection = ((ISelectionProvider) explorer + .getAdapter(ISelectionProvider.class)).getSelection(); + if (selection == null) + return result; + IStructuredSelection iss = (IStructuredSelection) selection; + @SuppressWarnings("unchecked") + List selections = iss.toList(); + for(AdaptableHintContext ahc : selections) { + Resource resource = (Resource) ahc.getAdapter(Resource.class); + result.add(resource); + } + return result; + } + + private Resource getModel() { + return model; + } + + @Override + public void setInput(ISessionContext context, Object input) { + availableSharedFunctionLibraries.setInput(context, input); + usedSharedFunctionLibraries.setInput(context, input); + this.model = AdaptionUtils.adaptToSingle(input, Resource.class); + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynBasicColorProvider.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynBasicColorProvider.java new file mode 100644 index 00000000..e5444a8e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynBasicColorProvider.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import org.eclipse.jface.resource.ColorDescriptor; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.simantics.browsing.ui.swt.widgets.impl.ITrackedColorProvider; + +/** + * Color provider for sysdyn tool. Use this color provider to get a consistent look for the product. + * @author Teemu Lempinen + * + */ +public class SysdynBasicColorProvider implements ITrackedColorProvider { + + private final ResourceManager resourceManager; + + private final ColorDescriptor highlightColor = ColorDescriptor.createFrom(new RGB(254, 255, 197)); + private final ColorDescriptor inactiveColor = ColorDescriptor.createFrom(new RGB(255, 255, 255)); + private final ColorDescriptor invalidInputColor = ColorDescriptor.createFrom(new RGB(255, 128, 128)); + + public SysdynBasicColorProvider(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + @Override + public Color getEditingBackground() { + return resourceManager.createColor(inactiveColor); + } + + @Override + public Color getHoverBackground() { + return resourceManager.createColor(highlightColor); + } + + @Override + public Color getInactiveBackground() { + return resourceManager.createColor(inactiveColor); + } + + @Override + public Color getInvalidBackground() { + return resourceManager.createColor(invalidInputColor); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynPropertyPage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynPropertyPage.java new file mode 100644 index 00000000..59e61e5f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynPropertyPage.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.util.Set; + +import org.eclipse.ui.IWorkbenchPartSite; +import org.simantics.selectionview.StandardPropertyPage; + +public class SysdynPropertyPage extends StandardPropertyPage { + + public SysdynPropertyPage(IWorkbenchPartSite site, Set set) { + super(site, set); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java new file mode 100644 index 00000000..53f7c9aa --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java @@ -0,0 +1,375 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties; + +import java.awt.Color; +import java.awt.Font; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory; +import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.diagram.G2DUtils; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.CustomFontDialog; +import org.simantics.sysdyn.ui.properties.widgets.ValveOrientationGroup; +import org.simantics.sysdyn.ui.properties.widgets.ValveTextLocationGroup; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; +import org.simantics.utils.datastructures.Triple; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.ui.ISelectionUtils; +import org.simantics.utils.ui.validators.DoubleValidator; + +/** + * Information tab for additional information of variables. + * @author Teemu Lempinen + * + */ +public class VariableInformationTab extends LabelPropertyTabContributor implements Widget { + private Composite orientationComposite; + private WidgetSupport support; + private Resource component; + private org.simantics.browsing.ui.swt.widgets.Label sample; + private LocalResourceManager resourceManager; + + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + this.support = support; + support.register(this); + + // Create a ResourceManager to dispose images when the widget is disposed. + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), body); + + + final Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + Group informationGroup = new Group(composite, SWT.SHADOW_ETCHED_IN); + informationGroup.setText("Information"); + GridDataFactory.fillDefaults().grab(false, true).applyTo(informationGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(informationGroup); + + // Textual format documentation + TrackedText information = new TrackedText(informationGroup, support, SWT.MULTI | SWT.BORDER); + information.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasDescription)); + information.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasDescription)); + GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget()); + + // Orientation information for valves + orientationComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().span(1, 2).applyTo(orientationComposite); + GridLayoutFactory.fillDefaults().margins(3,3).applyTo(orientationComposite); + + // Range of a variable (e.g. from 0 to 10). Does not affect simulation, but the infor can be used for example in charts + Group rangeGroup = new Group(composite, SWT.SHADOW_ETCHED_IN); + rangeGroup.setText("Range"); + GridDataFactory.fillDefaults().applyTo(rangeGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(rangeGroup); + + Label label = new Label(rangeGroup, SWT.NONE); + label.setText("Start"); + + TrackedText rangeStart = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER); + rangeStart.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeStart)); + rangeStart.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeStart)); + rangeStart.setInputValidator(new DoubleValidator()); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStart.getWidget()); + + + label = new Label(rangeGroup, SWT.NONE); + label.setText("End"); + + + TrackedText rangeEnd = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER); + rangeEnd.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeEnd)); + rangeEnd.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeEnd)); + rangeEnd.setInputValidator(new DoubleValidator()); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeEnd.getWidget()); + + label = new Label(rangeGroup, SWT.NONE); + label.setText("Step"); + + TrackedText rangeStep = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER); + rangeStep.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeStep)); + rangeStep.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeStep)); + rangeStep.setInputValidator(new DoubleValidator()); + GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget()); + + + // Font options. FIXME: very bad appearance right now + + final Composite fontComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().applyTo(fontComposite); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(fontComposite); + Button b = new Button(fontComposite, support, SWT.PUSH); + b.setText("Choose Font"); + + // Sample text with selected font + sample = new org.simantics.browsing.ui.swt.widgets.Label(fontComposite, support, SWT.NONE); + sample.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName, "Sample")); + + b.addSelectionListener(new SelectionListenerImpl(context) { + + Font f; + Color color; + Object input; + + @Override + public void beforeApply() { + + Triple result = null; + + try { + result = SimanticsUI.getSession().syncRequest(new Read>(){ + + @Override + public Triple perform(ReadGraph graph) throws DatabaseException { + Resource component = ISelectionUtils.filterSingleSelection(input, Resource.class); + String name = NameUtils.getSafeName(graph, component); + + Resource element = graph.getPossibleObject(component, ModelingResources.getInstance(graph).ComponentToElement); + if(element != null) { + G2DResource g2d = G2DResource.getInstance(graph); + Resource fontResource = graph.getPossibleObject(element, g2d.HasFont); + Resource colorResource = graph.getPossibleObject(element, g2d.HasColor); + + Font font = null; + if(fontResource != null) + font = G2DUtils.getFont(graph, fontResource); + Color color = null; + if(colorResource != null) + color = G2DUtils.getColor(graph, colorResource); + + return new Triple(font, color, name); + } + + return null; + } + + }); + } catch (DatabaseException e) { + } + + + CustomFontDialog dialog = new CustomFontDialog(composite.getShell(), (result != null ? result.third : null)); + + if(result != null) { + if(result.first != null) { + dialog.setAWTFont(result.first); + f = result.first; + } + if(result.second != null) { + dialog.setColor(result.second); + color = result.second; + } + } + + dialog.open(); + if(dialog.getAWTFont() != null) + f = dialog.getAWTFont(); + if(dialog.getAWTColor() != null) { + color = dialog.getAWTColor(); + } + + FontData fd = dialog.getSWTFontData(); + if(fd != null) + sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd))); + RGB rgb = dialog.getRGB(); + if(rgb != null) + sample.setForeground(resourceManager.createColor(rgb)); + fontComposite.layout(); + } + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + Resource element = graph.getPossibleObject(input, ModelingResources.getInstance(graph).ComponentToElement); + if(element != null) { + G2DResource g2d = G2DResource.getInstance(graph); + graph.deny(element, g2d.HasFont); + if(f != null) + graph.claim(element, g2d.HasFont, G2DUtils.createFont(graph, f)); + graph.deny(element, g2d.HasColor); + if(color != null) + graph.claim(element, g2d.HasColor, G2DUtils.createColor(graph, color)); + } + } + + @Override + public void setInput(ISessionContext context, Object parameter) { + super.setInput(context, parameter); + input = parameter; + } + + }); + + + + } + + private Read> fontAndColorRead; + + @Override + public void setInput(ISessionContext context, Object input) { + component = AdaptionUtils.adaptToSingle(input, Resource.class); + // is the displayed variable a valve? + Boolean isValve = false; + try { + isValve = context.getSession().syncRequest(new Read() { + + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + return graph.isInstanceOf(component, sr.Valve); + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + // if it is a valve, display the orientation information + if(isValve) { + ValveOrientationGroup vog = new ValveOrientationGroup(orientationComposite, context, support, SWT.NONE); + vog.setInput(context, input); + ValveTextLocationGroup vtlg = new ValveTextLocationGroup(orientationComposite, context, support, SWT.NONE); + vtlg.setInput(context, input); + orientationComposite.getParent().layout(); + } + + // Read font and color information for sample text + if(fontAndColorRead == null) { + fontAndColorRead = new Read>() { + + @Override + public Pair perform(ReadGraph graph) throws DatabaseException { + Font font = null; + Color color = null; + if(component != null) { + Resource element = graph.getPossibleObject(component, ModelingResources.getInstance(graph).ComponentToElement); + if(element != null) { + G2DResource g2d = G2DResource.getInstance(graph); + Resource fontResource = graph.getPossibleObject(element, g2d.HasFont); + if(fontResource != null) + font = G2DUtils.getFont(graph, fontResource); + Resource colorResource = graph.getPossibleObject(element, g2d.HasColor); + if(colorResource != null) + color = G2DUtils.getColor(graph, colorResource); + } + } + return new Pair(font, color); + } + }; + + SimanticsUI.getSession().asyncRequest(fontAndColorRead, new Listener>() { + + @Override + public void execute(final Pair result) { + final Display device; + try { + device = sample.getWidget().getDisplay(); + } catch (SWTException e) { + // Widget is disposed, the GUI probably did'n function as fast as the user commanded. + // Thus do nothing. + return; + } + + device.asyncExec(new Runnable() { + + @Override + public void run() { + try { + if(sample.getWidget().isDisposed()) + return; + } catch (SWTException e) { + // Widget is disposed, the GUI probably did'n function as fast as the user commanded. + // Thus do nothing. + return; + } + if(result.first != null) { + FontData fd = toSwtFontData(result.first); + sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd))); + } + if(result.second != null) { + RGB rgb = new RGB(result.second.getRed(), result.second.getGreen(), + result.second.getBlue()); + sample.setForeground(resourceManager.createColor(rgb)); + } + try { + sample.getWidget().getParent().getParent().layout(); + } catch (SWTException e) { + + } + } + }); + + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return sample == null || sample.getWidget().isDisposed(); + } + + }); + } + } + + /** + * Create SWT FontData based on AWT Font + * @param font AWT Font + * @return SWT FontData based on AWT Font + */ + private static FontData toSwtFontData(Font font) { + FontData fontData = new FontData(); + fontData.setName(font.getFamily()); + fontData.setStyle(font.getStyle()); + fontData.setHeight(font.getSize()); + return fontData; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrayExpressionCombo.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrayExpressionCombo.java new file mode 100644 index 00000000..42607db5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrayExpressionCombo.java @@ -0,0 +1,191 @@ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; + +public class ArrayExpressionCombo extends TrackedCombo { + + int lastSelectedIndex = -2; + + public ArrayExpressionCombo(Composite parent, WidgetSupport support, + int style) { + super(parent, support, style); + + /* + this.setInputValidator(new VariableNameValidator(support)); + */ + + this.setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, final Resource input) throws DatabaseException { + Map map = new LinkedHashMap(); + if(input == null) { + return map; + } + + Layer0 l0 = Layer0.getInstance(graph); + String name = graph.getPossibleRelatedValue(input, l0.HasName); + if(name == null) + return map; + + SysdynResource sr = SysdynResource.getInstance(graph); + + String defaultRange = getDefaultRange(graph, input); + for(Resource expression : getExpressions(graph, input)) { + String arrayRange = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange); + if(arrayRange != null) { + map.put(name + arrayRange, expression); + } else if(defaultRange != null) { + map.put(name + defaultRange, expression); + } else { + map.put(name, expression); + } + } + if(map.isEmpty()) { + map.put(name, input); + } + return map; + } + + }); + + + this.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + String name = graph.getPossibleRelatedValue(input, Layer0.getInstance(graph).HasName); + if(name == null) + return ""; + + String defaultRange = getDefaultRange(graph, input); + if(defaultRange == null) + return name; + + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource activeExpression = graph.getPossibleObject(input, sr.IndependentVariable_activeExpression); + Resource expression; + if(activeExpression == null) { + ArrayList expressions = getExpressions(graph, input); + if(expressions == null || expressions.isEmpty()) + return name; + expression = expressions.get(0); + } else { + expression = activeExpression; + } + String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange); + if(range != null) + return name + range; + else + return name + defaultRange; + } + }); + + } + + + @Override + public void setInput(ISessionContext context, Object input) { + super.setInput(context, input); + + if(selectionFactory != null) { + selectionFactory.listen(context, input, new Listener() { + + @Override + public void execute(final String result) { + if(getWidget().isDisposed()) return; + getWidget().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + Combo combo = getWidget(); + if(combo != null && !combo.isDisposed() && result != null) { + Object o = getWidget().getData(result); + if(o != null) + lastSelectedIndex = (Integer)o; + } + + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return getWidget().isDisposed(); + } + + }); + } + } + + private ArrayList getExpressions(ReadGraph graph, Resource variable) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource hasExpressions = graph.getPossibleObject(variable, sr.Variable_expressionList); + if(hasExpressions == null) + return new ArrayList(); + else + return new ArrayList(ListUtils.toList(graph, hasExpressions)); + } + + public static String getDefaultRange(ReadGraph graph, Resource variable) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource hasArrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList); + + if(hasArrayIndexes == null) + return null; + + Iterator iterator = ListUtils.toList(graph, hasArrayIndexes).iterator(); + if(!iterator.hasNext()) + return null; + + StringBuilder sb = new StringBuilder(); + sb.append("["); + + while(iterator.hasNext()) { + sb.append(NameUtils.getSafeName(graph, iterator.next())); + if(iterator.hasNext()) { + sb.append(", "); + } + } + sb.append("]"); + return sb.toString(); + } + + /** + * Get the index that has previously been selected + * @return + */ + public int getLastSelectedIndex() { + return lastSelectedIndex; + } + + public void setLastSelectedIndex(int lastSelectedIndex) { + this.lastSelectedIndex = lastSelectedIndex; + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrowHeadWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrowHeadWidget.java new file mode 100644 index 00000000..76981357 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrowHeadWidget.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Widget for showing arrow head in dependencies. + * @author Tuomas Miettinen + * + */ +public class ArrowHeadWidget implements Widget{ + + List variables = null; + org.simantics.browsing.ui.swt.widgets.Button arrowheadButton; + + public ArrowHeadWidget(Composite parent, WidgetSupport support, int style) { + support.register(this); + arrowheadButton = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK); + arrowheadButton.setText("Arrowhead"); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void setInput(ISessionContext context, Object input) { + if(input instanceof ISelection) { + ISelection selection = (ISelection)input; + if(selection instanceof IStructuredSelection) { + List resources = ISelectionUtils.filterSelection(selection, Resource.class); + if(resources != null && !resources.isEmpty()) { + variables = resources; + } else { + List resourceLists = ISelectionUtils.filterSelection(selection, ArrayList.class); + variables = resourceLists.get(0); + } + } + } + + if(variables == null) return; + + try { + context.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + // Determine if there are arrowheads in some of the variables. + boolean hasArrowheads = false, hasNotArrowheads = false; + for (Resource variable : variables) { + if (!graph.hasStatement(variable, sr.DependencyConnection_hideArrow)) { + hasArrowheads = true; + } else { + hasNotArrowheads = true; + } + } + + // If some have arrowheads but others don't, the check box is grayed. + final Button button = getWidget(); + final boolean arrowhead = hasArrowheads; + final boolean mixedArrowheads = hasArrowheads && hasNotArrowheads; + button.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(button.isDisposed()) return; + button.setSelection(arrowhead); + button.setGrayed(mixedArrowheads); + } + }); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // Multiple selections + arrowheadButton.addSelectionListener(new SelectionListenerImpl>(context) { + + @Override + public void apply(WriteGraph graph, ArrayList inputs) throws DatabaseException { + if (inputs == null) + return; + + final SysdynResource sr = SysdynResource.getInstance(graph); + boolean nextState = true; // The next state of the checkbox + for (Resource variable : variables) { + if (!graph.hasStatement(variable, sr.DependencyConnection_hideArrow)) { + nextState = false; // The next state is true iff all have hideArrow. + break; + } + } + + try { + if (nextState) { + for (Resource input : inputs) { + graph.deny(input, sr.DependencyConnection_hideArrow); + } + } else { + for (Resource input : inputs) { + graph.claim(input, SysdynResource.getInstance(graph).DependencyConnection_hideArrow, null, input); + } + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // Get the button out of the grayed state. + final Button button = getWidget(); + button.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + button.setGrayed(false); + } + }); + } + }); + + // One selection + arrowheadButton.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if (input == null) + return; + + final SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.hasStatement(input, sr.DependencyConnection_hideArrow)) { + graph.deny(input, sr.DependencyConnection_hideArrow); + } else { + graph.claim(input, SysdynResource.getInstance(graph).DependencyConnection_hideArrow, null, input); + } + } + }); + } + + public Button getWidget() { + return arrowheadButton.getWidget(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartTableWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartTableWidget.java new file mode 100644 index 00000000..b600df86 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartTableWidget.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.awt.event.MouseEvent; +import java.awt.geom.Point2D; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.tableParser.ParseException; +import org.simantics.sysdyn.tableParser.TableParser; +import org.simantics.sysdyn.tableParser.Token; +import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupInputOutputTable; +import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupInputOutputTable.InputOutput; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ISelectionUtils; + +public class ChartTableWidget implements Widget { + + Text input, output; + Button add; + LookupInputOutputTable table; + Resource expression; + + public ChartTableWidget(Composite parent, WidgetSupport support, int style) { + support.register(this); + Composite valueTableComposite = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(valueTableComposite); + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(valueTableComposite); + + table = new LookupInputOutputTable(valueTableComposite, SWT.NONE); + GridDataFactory.fillDefaults().span(3, 1).grab(false, true).applyTo(table); + table.getTableViewer().getTable().addMouseListener(new MouseListener() { + + @Override + public void mouseUp(org.eclipse.swt.events.MouseEvent e) { + if(e.button == MouseEvent.BUTTON3) { + Table t = (Table)e.widget; + TableItem item = (TableItem)t.getItem(new org.eclipse.swt.graphics.Point(e.x, e.y)); + table.removeItem(t.indexOf(item)); + tableModified(); + } + } + @Override + public void mouseDown(org.eclipse.swt.events.MouseEvent e) { } + @Override + public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) { } + }); + + input = new Text(valueTableComposite, SWT.BORDER | SWT.RIGHT); + input.setText(""); + output = new Text(valueTableComposite, SWT.BORDER | SWT.RIGHT); + output.setText(""); + + add = new Button(valueTableComposite, SWT.None); + add.setText("Add"); + add.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + try { + Double in = Double.parseDouble(input.getText()); + Double out = Double.parseDouble(output.getText()); + table.addLocation(new Point2D.Double(in, out)); + tableModified(); + } catch (NumberFormatException e1) { + } + input.setText(""); + output.setText(""); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + }); + + FocusListener flistener = new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + Text text = (Text)e.widget; + text.setSelection(0, text.getCharCount()); + } + @Override + public void focusLost(FocusEvent e) { } + }; + + + KeyListener listener = new KeyListener() { + + @Override + public void keyPressed(KeyEvent e) { + if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + try { + Double in = Double.parseDouble(input.getText()); + Double out = Double.parseDouble(output.getText()); + table.addLocation(new Point2D.Double(in, out)); + tableModified(); + } catch (NumberFormatException e1) { + if(input.getText().isEmpty() && output.getText().isEmpty()) { + add.forceFocus(); + return; + } + } + input.setText(""); + output.setText(""); + input.setFocus(); + } + } + + @Override + public void keyReleased(KeyEvent e) { } + + }; + + input.addFocusListener(flistener); + input.addKeyListener(listener); + output.addFocusListener(flistener); + output.addKeyListener(listener); + } + + @Override + public void setInput(ISessionContext context, Object input) { + + expression = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class); + + + try { + SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(!graph.isInstanceOf(expression, sr.WithLookupExpression)) + return null; + return graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_lookup); + } + }, new Listener() { + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public void execute(String lookup) { + if(lookup == null) return; + TableParser parser = new TableParser(new StringReader("")); + parser.ReInit(new StringReader(lookup)); + table.clearTable(); + try { + parser.table(); + ArrayList xTokens = parser.getXTokens(); + ArrayList yTokens = parser.getYTokens(); + for(int i = 0; i < xTokens.size(); i++) { + table.addLocation(new Point2D.Double( + Double.parseDouble(xTokens.get(i).image), + Double.parseDouble(yTokens.get(i).image))); + } + } catch (ParseException e1) { + } + } + + @Override + public boolean isDisposed() { + return table.isDisposed(); + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + table.addListener(SWT.Modify, new org.eclipse.swt.widgets.Listener() { + + @Override + public void handleEvent(Event event) { + tableModified(); + } + }); + } + + + @SuppressWarnings("unchecked") + private void tableModified() { + StringBuilder b = new StringBuilder(); + b.append("{"); + ArrayList inputOutputList = (ArrayList)table.getTableViewer().getInput(); + Collections.sort(inputOutputList, table.new InputOutputComparator()); + Iterator iterator = inputOutputList.iterator(); + while(iterator.hasNext()){ + InputOutput io = iterator.next(); + b.append("{" + io.getInput(String.class) + "," + io.getOutput(String.class) + "}"); + if(iterator.hasNext()) + b.append(","); + } + b.append("}"); + final String table = b.toString(); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + graph.claimLiteral(expression, sr.WithLookupExpression_lookup, table); + } + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartWidget.java new file mode 100644 index 00000000..2dd769dc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartWidget.java @@ -0,0 +1,240 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.GridLayout; +import java.awt.geom.Ellipse2D; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.swing.JComponent; +import javax.swing.JPanel; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.general.SeriesChangeEvent; +import org.jfree.data.general.SeriesChangeListener; +import org.jfree.data.xy.XYDataItem; +import org.jfree.data.xy.XYDataset; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.tableParser.ParseException; +import org.simantics.sysdyn.tableParser.TableParser; +import org.simantics.sysdyn.tableParser.Token; +import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupChartPanel; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ISelectionUtils; +import org.simantics.utils.ui.SWTAWTComponent; + +public class ChartWidget implements Widget { + + JFreeChart chart; + LookupChartPanel chartPanel; + SWTAWTComponent swtawtcomponent; + + public ChartWidget(Composite parent, WidgetSupport support, int style) { + support.register(this); + chartPanel = new LookupChartPanel(createChart()); + chartPanel.setMouseZoomable(true, false); + chartPanel.setDomainZoomable(false); + chartPanel.setRangeZoomable(false); + + swtawtcomponent = new SWTAWTComponent(parent, SWT.BORDER) { + @Override + protected JComponent createSwingComponent() { + JPanel panel = new JPanel(); + panel.setLayout(new GridLayout(1, 1)); + panel.add(chartPanel); + panel.doLayout(); + return panel; + } + }; + GridDataFactory.fillDefaults().grab(true, true).applyTo(swtawtcomponent); + swtawtcomponent.populate(); + + } + + @Override + public void setInput(ISessionContext context, Object input) { + + final Resource expression = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class); + + class Auxiliary { + Double minX, minY, maxX, maxY; + String table; + } + + try { + SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Auxiliary perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(!graph.isInstanceOf(expression, sr.WithLookupExpression)) + return null; + Auxiliary auxiliary = new Auxiliary(); + auxiliary.minX = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_minX); + auxiliary.maxX = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_maxX); + auxiliary.minY = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_minY); + auxiliary.maxY = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_maxY); + auxiliary.table = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_lookup); + return auxiliary; + } + }, new Listener() { + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public void execute(Auxiliary result) { + if(result == null) return; + XYDataset dataset = createDataset(result.table); + chartPanel.resetChart(dataset); + chartPanel.addSeriesChangeListener(new _SeriesChangeListener(expression)); + + XYPlot plot = (XYPlot) chart.getPlot(); + ValueAxis rangeAxis = plot.getRangeAxis(); + rangeAxis.setAutoRange(false); + if(result.minY == null) result.minY = rangeAxis.getLowerBound(); + if(result.maxY == null) result.maxY = rangeAxis.getUpperBound(); + rangeAxis.setRange(result.minY, result.maxY); + ValueAxis domainAxis = plot.getDomainAxis(); + domainAxis.setAutoRange(false); + if(result.minX == null) result.minX = domainAxis.getLowerBound(); + if(result.maxX == null) result.maxX = domainAxis.getUpperBound(); + domainAxis.setRange(result.minX, result.maxX); + + } + + @Override + public boolean isDisposed() { + return swtawtcomponent.isDisposed(); + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + private JFreeChart createChart() { + XYDataset dataset = createDataset(null); + chart = ChartFactory.createXYLineChart(null, null, null, + dataset, PlotOrientation.VERTICAL, false, true, false); + XYPlot plot = (XYPlot) chart.getPlot(); + XYLineAndShapeRenderer renderer + = (XYLineAndShapeRenderer) plot.getRenderer(); + renderer.setBaseShapesVisible(true); + renderer.setDrawOutlines(true); + renderer.setUseFillPaint(true); + renderer.setBaseFillPaint(Color.white); + renderer.setSeriesStroke(0, new BasicStroke(3.0f)); + renderer.setSeriesOutlineStroke(0, new BasicStroke(2.0f)); + renderer.setSeriesShape(0, new Ellipse2D.Double(-5.0, -5.0, 10.0, 10.0)); + return chart; + } + + public XYDataset createDataset(String table) { + XYSeries series = new XYSeries("Series"); + + if(table != null) { + TableParser parser = new TableParser(new StringReader("")); + parser.ReInit(new StringReader(table)); + try { + parser.table(); + ArrayList xTokens = parser.getXTokens(); + ArrayList yTokens = parser.getYTokens(); + for(int i = 0; i < xTokens.size(); i++) { + series.add( + Double.parseDouble(xTokens.get(i).image), + Double.parseDouble(yTokens.get(i).image)); + } + } catch (ParseException e1) { + } + } + + XYSeriesCollection dataset = new XYSeriesCollection(); + dataset.addSeries(series); + return dataset; + } + + public LookupChartPanel getChartPanel() { + return this.chartPanel; + } + + public JFreeChart getChart() { + return this.chart; + } + + private class _SeriesChangeListener implements SeriesChangeListener { + + Resource expression; + + public _SeriesChangeListener(Resource expression) { + this.expression = expression; + } + @Override + public void seriesChanged(SeriesChangeEvent event) { + if(chartPanel.isDragging()) return; + + StringBuilder b = new StringBuilder(); + b.append("{"); + XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset(); + XYSeries series = collection.getSeries(0); + if(series.isEmpty()) + return; + Iterator iterator = series.getItems().iterator(); + while(iterator.hasNext()){ + XYDataItem item = (XYDataItem)iterator.next(); + b.append("{" + item.getX() + "," + item.getY() + "}"); + if(iterator.hasNext()) + b.append(","); + } + b.append("}"); + final String table = b.toString(); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + graph.claimLiteral(expression, sr.WithLookupExpression_lookup, table); + } + }); + + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ColumnKeys.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ColumnKeys.java new file mode 100644 index 00000000..1a9dda4b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ColumnKeys.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import org.simantics.browsing.ui.Column; +import org.simantics.browsing.ui.Column.Align; + +public class ColumnKeys { + + public static final String ENUMERATION = "Enumeration"; + public static final String INDEXES = "Indexes"; + public static final String SHOW_IN_CHARTS = "ShowInCharts"; + public static final String REPLACED_WITH = "Replaced with"; + public static final String MODULE_PARAMETER = "Parameter in Module"; + public static final String VALUE = "Value"; + + public static String[] ENUMERATION_COLUMNS_KEYS = { ENUMERATION, INDEXES }; + public static Column[] ENUMERATION_TABLE_COLUMNS = new Column[] { + new Column(ENUMERATION, Align.LEFT, 100, "Enumeration", false), + new Column(INDEXES, Align.LEFT, 100, "Indexes", true), + }; + + + public static String[] ENUMERATION_INDEX_COLUMNS_KEYS = { ENUMERATION, SHOW_IN_CHARTS }; + public static Column[] ENUMERATION_INDEX_TABLE_COLUMNS = new Column[] { + new Column(ENUMERATION, Align.LEFT, 100, "Enumeration", true), + new Column(SHOW_IN_CHARTS, Align.LEFT, 20, "Show in charts", false), + }; + + public static String[] ENUMERATION_REDECLARATION_KEYS = { ENUMERATION, REPLACED_WITH }; + public static Column[] ENUMERATION_REDECLARATION_COLUMNS = new Column[] { + new Column(ENUMERATION, Align.LEFT, 200, "Enumeration in module", false), + new Column(REPLACED_WITH, Align.LEFT, 200, "Replaced with", true), + }; + + public static String[] MODULE_PARAMETER_KEYS = { MODULE_PARAMETER, VALUE }; + public static Column[] MODULE_PARAMETER_COLUMNS = new Column[] { + new Column(MODULE_PARAMETER, Align.LEFT, 200, MODULE_PARAMETER, false), + new Column(VALUE, Align.LEFT, 200, VALUE, true), + }; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java new file mode 100644 index 00000000..51bcf324 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java @@ -0,0 +1,362 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.awt.Color; +import java.awt.Font; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.nebula.widgets.tablecombo.TableCombo; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.simantics.utils.ui.gfx.ColorImageDescriptor; + +/** + * Custom dialog for selecting font and font color. Similar to SWT FontDialog. + * @author Teemu Lempinen + * + */ +public class CustomFontDialog extends Dialog { + + private Map systemColors = createColorMap(); + + private FontData resultSWTFontData; + private Font awtFont; + private Font resultAWTFont; + private Color color; + private Color resultAWTColor; + + private FontSelectionComposite vpc; + private TableCombo tc; + + private String example = "Example"; + private Label sample; + private Group sampleGroup; + private RGB rgb; + + private LocalResourceManager resourceManager; + + + // Default color map + protected static Map createColorMap() { + LinkedHashMap colors = new LinkedHashMap(); + colors.put("Black", SWT.COLOR_BLACK); + colors.put("White", SWT.COLOR_WHITE); + colors.put("Blue", SWT.COLOR_BLUE); + colors.put("Dark Blue", SWT.COLOR_DARK_BLUE); + colors.put("Red", SWT.COLOR_RED); + colors.put("Dark Red", SWT.COLOR_DARK_RED); + colors.put("Yellow", SWT.COLOR_YELLOW); + colors.put("Dark Yellow", SWT.COLOR_DARK_YELLOW); + colors.put("Gray", SWT.COLOR_GRAY); + colors.put("Dark Gray", SWT.COLOR_DARK_GRAY); + colors.put("Green", SWT.COLOR_GREEN); + colors.put("Dark Green", SWT.COLOR_DARK_GREEN); + colors.put("Cyan", SWT.COLOR_CYAN); + colors.put("Dark Cyan", SWT.COLOR_DARK_CYAN); + colors.put("Magenta", SWT.COLOR_MAGENTA); + colors.put("Dark Magenta", SWT.COLOR_DARK_MAGENTA); + return colors; + } + + /** + * Creates a font dialog with sample text + * @param parentShell + * @param example Sample text in the dialog. Null example => "Example" + */ + public CustomFontDialog(Shell parentShell, String example) { + super(parentShell); + if(example != null) + this.example = example; + } + + /** + * Sets the initial font for this dialog + * @param awtFont Current AWT font + */ + public void setAWTFont(java.awt.Font awtFont) { + this.awtFont = awtFont; + this.resultAWTFont = awtFont; + } + + /** + * Get selected font as AWT font + * @return AWT font + */ + public java.awt.Font getAWTFont() { + return resultAWTFont; + } + + /** + * Get selected font as SWT font dta + * @return + */ + public FontData getSWTFontData() { + return resultSWTFontData; + } + + /** + * Set initial color for this dialog + * @param color AWT color + */ + public void setColor(Color color) { + this.color = color; + this.resultAWTColor = color; + } + + /** + * Get selected color as AWT color + * @return + */ + public Color getAWTColor() { + return resultAWTColor; + } + + /** + * Get selected color as RGB + * @return + */ + public RGB getRGB() { + return rgb; + } + + + /** + * Creates font choosing area + * @param parent Parent composite + */ + protected void createFontChooser(Composite parent) { + vpc = new FontSelectionComposite(parent, SWT.NONE); + vpc.setFont(awtFont, false); + GridDataFactory.fillDefaults().span(2, 1).applyTo(vpc); + + vpc.addFontModifiedListener(new FontModifyListener() { + + @Override + public void swtFontDataChanged(FontData fd) { + sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd))); + sampleGroup.layout(); + } + + @Override + public void awtFontChanged(Font font) { + } + }); + + } + + /** + * Creates a TableCombo for choosing a color for a font + * @param parent Parent composite + */ + protected void createColorChooser(Composite parent) { + // Create a ResourceManager to dispose images when the widget is disposed. + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent); + + Composite colorComposite = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorComposite); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(colorComposite); + + Label label = new Label(colorComposite, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label); + label.setText("Color: "); + + tc = new TableCombo(colorComposite, SWT.BORDER | SWT.READ_ONLY); + GridDataFactory.fillDefaults().hint(170, SWT.DEFAULT).applyTo(tc); + + tc.defineColumns(2); + tc.setDisplayColumnIndex(1); + tc.setToolTipText("this is tooltip"); + + createColorItems(tc.getTable()); + + if(this.color != null) { + for(int i = 0; i < tc.getTable().getItemCount(); i++) { + TableItem ti = tc.getTable().getItem(i); + RGB rgb = (RGB) ti.getData(); + if(rgb.red == this.color.getRed() && + rgb.green == this.color.getGreen() && + rgb.blue == this.color.getBlue()) { + tc.setText(ti.getText(1)); + tc.setForeground(resourceManager.createColor(rgb)); + break; + } + } + } + + // add listener + tc.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] selection = tc.getTable().getSelection(); + if(selection.length == 1) { + rgb = (RGB) selection[0].getData(); + org.eclipse.swt.graphics.Color swtColor = resourceManager.createColor(rgb); + sample.setForeground(swtColor); + tc.setForeground(swtColor); + } + tc.getTextControl().setSelection(0); + tc.getParent().forceFocus(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + } + + /** + * Creates a sample text area + * @param parent Parent composite + */ + protected void createSampleArea(Composite parent) { + sampleGroup = new Group(parent, SWT.NONE); + sampleGroup.setText("Sample"); + GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 70).applyTo(sampleGroup); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(sampleGroup); + + sample = new Label(sampleGroup, SWT.NONE); + sample.setText(example); + if(awtFont != null) { + sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(toSwtFontData(awtFont)))); + } + if(rgb != null) { + sample.setForeground(resourceManager.createColor(rgb)); + } + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, true).applyTo(sample); + } + + @Override + protected Control createDialogArea(Composite parent) + { + Composite composite = ( Composite )super.createDialogArea(parent); + composite.getShell().setText("Choose Font"); + + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite); + + // Init SWT RGB, if AWT color has been set + if(color != null) + this.rgb = new RGB(color.getRed(), color.getGreen(), color.getBlue()); + + // Font selection composite + createFontChooser(composite); + + // Color selection + createColorChooser(composite); + + // Sample text + createSampleArea(composite); + + //Set the dialog position in the middle of the monitor + setDialogLocationToMonitorCenter(); + + return composite; + } + + @Override + protected void cancelPressed() { + resultAWTFont = awtFont; + resultAWTColor = color; + if(resultAWTFont != null) + resultSWTFontData = toSwtFontData(resultAWTFont); + + setReturnCode(CANCEL); + close(); + } + + @Override + protected void okPressed() { + resultAWTFont = vpc.getAWTFont(); + resultSWTFontData = toSwtFontData(resultAWTFont); + + TableItem[] selection = tc.getTable().getSelection(); + if(selection.length == 1) { + RGB rgb = (RGB) selection[0].getData(); + resultAWTColor = new Color(rgb.red, rgb.green, rgb.blue); + } + + setReturnCode(OK); + close(); + } + + /** + * Sets the dialog location to the middle of the screen + */ + protected void setDialogLocationToMonitorCenter() { + Rectangle monitorArea = getShell().getDisplay().getPrimaryMonitor().getBounds(); + Rectangle shellArea = getShell().getBounds(); + int x = monitorArea.x + (monitorArea.width - shellArea.width)/2; + int y = monitorArea.y + (monitorArea.height - shellArea.height)/2; + getShell().setLocation(x,y); + } + + /** + * Builds SWT FontData from AWT font. Simple conversion. + * + * @param font AWT font + * @param height Height for the created data (or -1 if inherited directly from awt font, size matching not guaranteed) + * @return + */ + protected static FontData toSwtFontData(Font font) { + FontData fontData = new FontData(); + fontData.setName(font.getFontName()); + fontData.setStyle(font.getStyle()); + fontData.setHeight(font.getSize()); + return fontData; + } + + /** + * Creates color items for color combo + * @param table + */ + protected void createColorItems(Table table) { + Image image; + TableItem ti; + int code; + RGB color; + Display display = Display.getCurrent(); + for(String text : systemColors.keySet()) { + code = systemColors.get(text); + color = display.getSystemColor(code).getRGB(); + image = resourceManager.createImage(new ColorImageDescriptor(color.red, color.green, color.blue, 25, 15, false)); + + ti = new TableItem(table, SWT.NONE); + ti.setImage(0, image); + ti.setText(1, text); + ti.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); + ti.setData(color); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/DelayMarkWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/DelayMarkWidget.java new file mode 100644 index 00000000..e5d4e0ec --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/DelayMarkWidget.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Widget for Delay marks in dependencies. + * @author Tuomas Miettinen + * + */ +public class DelayMarkWidget implements Widget{ + + List variables = null; + org.simantics.browsing.ui.swt.widgets.Button delayMarkButton; + + public DelayMarkWidget(Composite parent, WidgetSupport support, int style) { + support.register(this); + delayMarkButton = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK); + delayMarkButton.setText("Delay mark"); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public void setInput(ISessionContext context, Object input) { + if(input instanceof ISelection) { + ISelection selection = (ISelection)input; + if(selection instanceof IStructuredSelection) { + List resources = ISelectionUtils.filterSelection(selection, Resource.class); + if(resources != null && !resources.isEmpty()) { + variables = resources; + } else { + List resourceLists = ISelectionUtils.filterSelection(selection, ArrayList.class); + variables = resourceLists.get(0); + } + } + } + + if(variables == null) return; + + try { + context.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + // Determine if there are delay marks in some of the variables. + boolean hasDelayMarks = false, hasNotDelayMarks = false; + for (Resource variable : variables) { + if (graph.hasStatement(variable, sr.DependencyConnection_delayMark)) { + hasDelayMarks = true; + } else { + hasNotDelayMarks = true; + } + } + + // If some have delay marks but others don't, the check box is grayed. + final Button button = getWidget(); + final boolean delayMark = hasDelayMarks; + final boolean mixedDelayMarks = hasDelayMarks && hasNotDelayMarks; + button.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(button.isDisposed()) return; + button.setSelection(delayMark); + button.setGrayed(mixedDelayMarks); + } + }); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // Multiple selections + delayMarkButton.addSelectionListener(new SelectionListenerImpl>(context) { + + @Override + public void apply(WriteGraph graph, ArrayList inputs) throws DatabaseException { + if (inputs == null) + return; + + final SysdynResource sr = SysdynResource.getInstance(graph); + boolean nextState = true; // The next state of the checkbox + for (Resource variable : variables) { + if (graph.hasStatement(variable, sr.DependencyConnection_delayMark)) { + nextState = false; // The next state is true iff at least one has the delay mark. + break; + } + } + + try { + if (nextState) { + for (Resource input : inputs) { + graph.claim(input, SysdynResource.getInstance(graph).DependencyConnection_delayMark, null, input); + } + } else { + for (Resource input : inputs) { + graph.deny(input, sr.DependencyConnection_delayMark); + } + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // Get the button out of the grayed state. + final Button button = getWidget(); + button.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + button.setGrayed(false); + } + }); + } + }); + + // One selection + delayMarkButton.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + if (input == null) + return; + + final SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.hasStatement(input, sr.DependencyConnection_delayMark)) { + graph.deny(input, sr.DependencyConnection_delayMark); + } else { + graph.claim(input, SysdynResource.getInstance(graph).DependencyConnection_delayMark, null, input); + } + } + }); + } + + public Button getWidget() { + return delayMarkButton.getWidget(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/EquivalentUnitsWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/EquivalentUnitsWidget.java new file mode 100644 index 00000000..13106559 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/EquivalentUnitsWidget.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.issues.ontology.IssueResource; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Widget for equivalent units selection. + * @author Tuomas Miettinen + * + */ +public class EquivalentUnitsWidget implements Widget{ + + Resource model = null; + org.simantics.browsing.ui.swt.widgets.Button unitEquivalents; + + public EquivalentUnitsWidget(Composite parent, WidgetSupport support, int style) { + support.register(this); + unitEquivalents = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK); + unitEquivalents.setText("Unit equivalents"); + unitEquivalents.getWidget().setToolTipText("Supported equivalent units:\n" + + "$, $s, dollar, dollars, usd\n"+ + "\u20ac, \u20acs, eur, euro, euros, e, ecu\n"+ + "£, £s, pound, pounds, gbp\n"+ + "Unit, Units\n"+ + "Person, People, Persons\n"+ + "second, seconds, sec, s\n"+ + "minute, minutes, min\n"+ + "hour, hours, h, hr\n"+ + "day, days, d\n"+ + "month, months, mon, mth, mo, mos\n"+ + "year, years, a, y, yr"); + + } + + @Override + public void setInput(ISessionContext context, Object input) { + if(input instanceof ISelection) { + ISelection selection = (ISelection)input; + if(selection instanceof IStructuredSelection) { + Resource resource = ISelectionUtils.filterSingleSelection(selection, Resource.class); + if(resource != null) { + model = resource; + } + } + } + + if(model == null) return; + + try { + context.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + // Determine if unit validation is enabled. + SysdynResource sr = SysdynResource.getInstance(graph); + final Resource unitIssueSource = graph.syncRequest( + new PossibleObjectWithType(model, + Layer0X.getInstance(graph).Activates, + sr.Validations_Units_UnitIssueSource)); + IssueResource ISSUE = IssueResource.getInstance(graph); + final Boolean issueSource_active = graph.getPossibleRelatedValue(unitIssueSource, ISSUE.IssueSource_active, Bindings.BOOLEAN); + + Boolean result = false; + if(unitIssueSource != null) { + result = graph.getPossibleRelatedValue(unitIssueSource, sr.Validations_Units_UnitIssueSource_allowEquivalents, Bindings.BOOLEAN); + } + + final boolean enable = result; + final Button button = getWidget(); + button.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(button.isDisposed()) return; + + // Is unit validation is enabled, enable the button. + getWidget().setEnabled(unitIssueSource!=null && issueSource_active); + if(Boolean.TRUE.equals(enable)) + button.setSelection(true); + else + button.setSelection(false); + } + }); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + unitEquivalents.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, Resource model) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource unitIssueSource = graph.syncRequest( + new PossibleObjectWithType(model, + Layer0X.getInstance(graph).Activates, + sr.Validations_Units_UnitIssueSource)); + if(unitIssueSource == null) + return; + + Boolean result = graph.getPossibleRelatedValue(unitIssueSource, sr.Validations_Units_UnitIssueSource_allowEquivalents, Bindings.BOOLEAN); + if(result == null) + result = false; + graph.claimLiteral(unitIssueSource, sr.Validations_Units_UnitIssueSource_allowEquivalents, Boolean.FALSE.equals(result)); + } + }); + } + + public Button getWidget() { + return unitEquivalents.getWidget(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionTypes.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionTypes.java new file mode 100644 index 00000000..7b3b20bf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionTypes.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +/** + * Expression type representations + * @author Teemu Lempinen + * + */ +public class ExpressionTypes { + + public static enum ExpressionType {Auxiliary, Parameter, Constant, Lookup, WithLookup, Stock, Delay, Empty}; + + public static ExpressionType[] auxiliaryExpressions = new ExpressionType[] { + ExpressionType.Auxiliary, + ExpressionType.Parameter, + ExpressionType.Constant, + ExpressionType.Delay, + // ExpressionType.Lookup, + ExpressionType.WithLookup}; + + public static ExpressionType[] valveExpressions = new ExpressionType[] { + ExpressionType.Auxiliary, + ExpressionType.Parameter, + ExpressionType.Constant, + ExpressionType.Delay, + ExpressionType.WithLookup}; + + public static ExpressionType[] stockExpressions = new ExpressionType[] { + ExpressionType.Stock}; + + public static ExpressionType getExpressionType(final Resource expression) { + try { + return SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public ExpressionType perform(ReadGraph graph) throws DatabaseException { + return getExpressionType(graph, expression); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + return null; + } + + } + + public static ExpressionType getExpressionType(ReadGraph graph, final Resource expression) throws DatabaseException { + ExpressionType et = null; + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.isInstanceOf(expression, sr.NormalExpression)) { + et = ExpressionType.Auxiliary; + } else if (graph.isInstanceOf(expression, sr.StockExpression)) { + et = ExpressionType.Stock; + } else if (graph.isInstanceOf(expression, sr.ParameterExpression)) { + et = ExpressionType.Parameter; + } else if (graph.isInstanceOf(expression, sr.ConstantExpression)) { + et = ExpressionType.Constant; + } else if (graph.isInstanceOf(expression, sr.DelayExpression)) { + et = ExpressionType.Delay; + } else if (graph.isInstanceOf(expression, sr.LookupExpression)) { + et = ExpressionType.Lookup; + } else if (graph.isInstanceOf(expression, sr.WithLookupExpression)) { + et = ExpressionType.WithLookup; + } else { + et = ExpressionType.Empty; + } + return et; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionWidget.java new file mode 100644 index 00000000..07b448bf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionWidget.java @@ -0,0 +1,272 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.Timer; + +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Table; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType; +import org.simantics.sysdyn.ui.properties.widgets.expressions.AuxiliaryExpression; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ConstantExpression; +import org.simantics.sysdyn.ui.properties.widgets.expressions.DelayExpression; +import org.simantics.sysdyn.ui.properties.widgets.expressions.EmptyExpression; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionComposite; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionWidgetInput; +import org.simantics.sysdyn.ui.properties.widgets.expressions.IExpression; +import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupExpression; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ParameterExpression; +import org.simantics.sysdyn.ui.properties.widgets.expressions.StockExpression; +import org.simantics.sysdyn.ui.properties.widgets.expressions.WithLookupExpression; +import org.simantics.sysdyn.ui.utils.ExpressionUtils; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * Widget for displaying an expression. Widget creates the IExpression for displaying + * properties for each expression type and adds validation, saving and other services + * to the active IExpression. + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ExpressionWidget implements Widget { + + private ExpressionWidgetInput input; + private Resource expr; + private Variable variable; + private Composite parent; + private Map data; + private IExpression expression; + private ModifyListener modifyListener; + private FocusListener focusListener; + private Table variableTable; + private VerifyKeyListener verifyKeyListener; + private Timer validationTimer; + private static int VALIDATION_DELAY_TIME = 500; + private final LocalResourceManager resourceManager; + + /** + * Create a new expression widget + * @param parent + * @param support + * @param style + */ + public ExpressionWidget(Composite parent, WidgetSupport support, int style) { + support.register(this); + this.parent = parent; + if (parent instanceof ExpressionComposite) { + ExpressionComposite expressionComposite = (ExpressionComposite)parent; + expressionComposite.setExpressionWidget(this); + } + this.data = new HashMap(); + + // Create a ResourceManager to dispose images when the widget is disposed. + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), this.parent); + + /* + * Create a validation timer for expression fields. Validation timer + * validates the field as the modeler is typing an expression + */ + validationTimer = new Timer(VALIDATION_DELAY_TIME, new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if(variableTable == null || variableTable.isDisposed()) + return; + variableTable.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + validateFields(); + } + }); + } + }); + validationTimer.setRepeats(false); + } + + @Override + public void setInput(ISessionContext context, Object input) { + // Update IExpression based on the newly selected expression + ExpressionWidgetInput i = AdaptionUtils.adaptToSingle(input, ExpressionWidgetInput.class); + this.input = i; + expr = i.expression; + variable = i.variable; + ExpressionType et = ExpressionTypes.getExpressionType(expr); + displayExpression(et.toString(), true); + } + + /** + * Displays IExpression corresponding to expressionType. + * @param expressionType Expression type + * @param original Is the displayed expression for a newly selected expression (true) or did the + * expression change its type (false) + */ + public void displayExpression(String expressionType, boolean original) { + if(expressionType == null || parent.isDisposed()) { + return; + } + + // Get up-to-date data to data-map + if(this.expression != null) expression.updateData(data); + + // Create the new expression + ExpressionType et = ExpressionType.valueOf(expressionType); + IExpression exp = null; + switch (et) { + case Auxiliary: + exp = new AuxiliaryExpression(input); break; + case Parameter: + exp = new ParameterExpression(input); break; + case Constant: + exp = new ConstantExpression(input); break; + case Lookup: + exp = new LookupExpression(); break; + case WithLookup: + exp = new WithLookupExpression(input); break; + case Stock: + exp = new StockExpression(input); break; + case Delay: + exp = new DelayExpression(input); break; + default: + exp = new EmptyExpression(); + } + + if (exp != null) { + // If expression was created, remove the old one + for(Control c : parent.getChildren()) { + c.dispose(); + } + + // If a completely new expression was selected, read data + if(original) + exp.readData(expr, data); + + // Create the visual representation of the expression type + exp.createExpressionFields(parent, data, variableTable); + + // Add listeners + if(modifyListener != null) + exp.addModifyListener(modifyListener); + if(focusListener != null) + exp.addFocusListener(focusListener); + if(verifyKeyListener != null) + exp.addVerifyKeyListener(verifyKeyListener); + this.expression = exp; + this.parent.layout(); + validateFieldsTimed(); + + save(); + } + } + + /** + * Get current IExpression + * @return current IExpression + */ + public IExpression getExpression() { + return expression; + } + + /** + * Set the variable table that contains information about variables that are connected + * to this expression + * @param table + */ + public void setVariableTable(Table table) { + this.variableTable = table; + } + + /** + * Set timed field validation with default delay time + */ + public void validateFieldsTimed() { + validateFieldsTimed(VALIDATION_DELAY_TIME); + } + + /** + * Set timed field validation + * @param delay Delay time for validation + */ + public void validateFieldsTimed(int delay) { + validationTimer.setDelay(delay); + if(!validationTimer.isRunning()) + validationTimer.start(); + else + validationTimer.restart(); + } + + /** + * Validates expression fields in current IExpression + */ + public void validateFields() { + if(this.variableTable == null) return; + + try { + // Find the variable for this experession + Resource variable = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + return graph.getPossibleObject(expr, l0.PartOf); + } + }); + // Validate the variable + if(variable != null) + ExpressionUtils.validateExpressionFields(variable, expression, variableTable, resourceManager); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + public void addModifyListener(ModifyListener listener) { + this.modifyListener = listener; + } + + public void addVerifyKeyListener(VerifyKeyListener listener) { + this.verifyKeyListener = listener; + } + + public void addFocusListener(FocusListener listener) { + this.focusListener = listener; + } + + public void save() { + if(this.expression != null) + this.expression.save(expr, data); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontModifyListener.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontModifyListener.java new file mode 100644 index 00000000..eb1e11b1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontModifyListener.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.awt.Font; + +import org.eclipse.swt.graphics.FontData; + +/** + * Font change listening interface + * @author Teemu Lempinen + * + */ +public interface FontModifyListener { + + /** + * Called when font is changed + * @param font New font as AWT font + */ + public void awtFontChanged(Font font); + + /** + * Called when font is changed + * @param font New font data as SWT font data + */ + public void swtFontDataChanged(FontData font); +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontSelectionComposite.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontSelectionComposite.java new file mode 100644 index 00000000..9a8f4388 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontSelectionComposite.java @@ -0,0 +1,681 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.awt.Font; +import java.awt.GraphicsEnvironment; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.TreeMap; + +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +/** + * Composite for displaying font selection tools. By default, the composite contains + * font family, font style and font size. + * + * @author Teemu Lempinen + * + */ +public class FontSelectionComposite extends Composite { + + + protected Text fontName, fontStyle, fontSize; + protected ArrayList familyIndex = new ArrayList(); + protected TreeMap> fonts = getFonts(familyIndex); + protected Table fontFamilyTable, fontStyleTable, fontSizeTable; + protected String[] sizes = new String[] {"8", "9", "10", "11", "12", "14", "16", "18", "20", "24", "26", "28", "36", "48", "72"}; + + private ListenerList modifyListeners; + + private final LocalResourceManager resourceManager; + + /** + * Gets all available fonts + * @param familyIndex Optional list for indexing font families + * @return Tree where key is font family name and object a list of fonts belonging to that family + */ + private static TreeMap> getFonts(ArrayList familyIndex) { + TreeMap> fonts = new TreeMap>(); + + GraphicsEnvironment gEnv = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + Font allFonts[] = gEnv.getAllFonts(); + + for(Font font : allFonts) { + String family = font.getFamily(Locale.ROOT); + if(!fonts.containsKey(family)) { + if(familyIndex != null) + familyIndex.add(family); + fonts.put(family, new ArrayList()); + } + + boolean add = true; + for(Font f : fonts.get(family)) { + if(f.getFontName().equals(font.getFontName())) { + add = false; + break; + } + } + + if(add) + fonts.get(family).add(font); + } + return fonts; + } + + /** + * Composite containing components for selecting a font + * + * @param parent Parent composite + * @param style SWT style + */ + public FontSelectionComposite(Composite parent, int style) { + super(parent, style); + + // Create a ResourceManager to dispose images when the widget is disposed. + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), this); + + modifyListeners = new ListenerList(); + + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(this); + GridDataFactory.fillDefaults().applyTo(this); + + /* + * Two-row layout. First row consists of editable text boxes, + * second row consists of tables containing possible options + */ + + // First row + fontName = new Text(this, SWT.BORDER); + GridDataFactory.fillDefaults().applyTo(fontName); + + fontStyle = new Text(this, SWT.BORDER); + GridDataFactory.fillDefaults().applyTo(fontStyle); + + fontSize = new Text(this, SWT.BORDER); + GridDataFactory.fillDefaults().applyTo(fontSize); + + // Second row + fontFamilyTable = new Table (this, SWT.VIRTUAL | SWT.BORDER | SWT.FULL_SELECTION); + fontFamilyTable.setLinesVisible (false); + fontFamilyTable.setHeaderVisible (false); + GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 100).applyTo(fontFamilyTable); + fontFamilyTable.setItemCount(familyIndex.size()); + TableColumn column = new TableColumn (fontFamilyTable, SWT.NONE); + column.setWidth(200); + + + fontStyleTable = new Table (this, SWT.BORDER | SWT.FULL_SELECTION); + fontStyleTable.setLinesVisible (false); + fontStyleTable.setHeaderVisible (false); + GridDataFactory.fillDefaults().hint(100, 100).applyTo(fontStyleTable); + column = new TableColumn (fontStyleTable, SWT.NONE); + setFontStyleTableWidth(); + + + + fontSizeTable = new Table (this, SWT.VIRTUAL | SWT.BORDER | SWT.FULL_SELECTION); + fontSizeTable.setLinesVisible (false); + fontSizeTable.setHeaderVisible (false); + GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 100).applyTo(fontSizeTable); + column = new TableColumn (fontSizeTable, SWT.NONE); + column.setWidth(70); + for(String size : sizes) { + TableItem item = new TableItem(fontSizeTable, SWT.NONE); + item.setText(0, size); + } + + // Listeners for components + addFontFamilyListeners(); + addFontStyleListeners(); + addFontSizeListeners(); + } + + + /** + * Set controls to display given font + */ + public void setFont(Font font, boolean notify) { + if(font == null) + return; + + Object[] listeners = new Object[0]; + if(!notify) { + listeners = modifyListeners.getListeners(); + for(Object listener : listeners) + modifyListeners.remove(listener); + } + + String fontFamily = font.getFamily(Locale.ROOT); + String fontName = font.getFontName(Locale.ROOT); + this.fontName.setText(fontFamily); + this.fontFamilyTable.setTopIndex(this.fontFamilyTable.getSelectionIndex()); + + String style = "Regular"; + if(fontName.length() > fontFamily.length()) + style = fontName.substring(fontFamily.length() + 1); + this.fontStyle.setText(style); + + int size = font.getSize(); + fontSize.setText("" + size); + + for(int i = 0; i < sizes.length; i++) { + if(sizes[i].equals("" + size)) { + fontSizeTable.select(i); + fontSizeTable.setTopIndex(i); + fontChanged(); + break; + } + } + + if(!notify) { + for(Object listener : listeners) + modifyListeners.add(listener); + } + } + + /** + * Get the AWT font defined in this composite + * @return AWT font + */ + public Font getAWTFont() { + String family = fontName.getText(); + String style = fontStyle.getText(); + if(style.equals("Regular")) + style = null; + + int stylebits = 0; + if(style != null) { + if(style.toLowerCase().contains("bold")) + stylebits |= SWT.BOLD; + if(style.toLowerCase().contains("italic")) + stylebits |= SWT.ITALIC; + } + + String name = family + (style != null ? " " + style : ""); + + int size = 10; + try { + size = Integer.parseInt(fontSize.getText()); + } catch (NumberFormatException e) { + } + + if(name != null && name.length() > 0) + return new Font(name, stylebits, size); + else + return null; + } + + /** + * Adds listeners for font family name text and table + */ + protected void addFontFamilyListeners() { + + // Font name modify listener + fontName.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + Text text = (Text) e.widget; + String name = text.getText(); + fontFamilyTextModified(name, false); + } + }); + + // Font name key listener for auto-completion + fontName.addKeyListener(new KeyListener() { + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + if ((e.character == ' ') && ((e.stateMask & SWT.CTRL) != 0) ) { + fontFamilyTextModified(fontName.getText(), true); + e.doit = false; + } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) { + fontChanged(); + } + } + }); + + // Call listener when editing has ended + fontName.addListener(SWT.FocusOut, new Listener() { + public void handleEvent(Event e) { + fontChanged(); + } + }); + + // Font family data listener for lazy initialization of the table + fontFamilyTable.addListener (SWT.SetData, new Listener () { + public void handleEvent (Event event) { + TableItem item = (TableItem) event.item; + int index = fontFamilyTable.indexOf (item); + + String family = familyIndex.get(index); + item.setText (family); + + Font font = fonts.get(family).get(0); + if(font.canDisplay('a')) { + FontData fontData = toSwtFontData(font, 10); + org.eclipse.swt.graphics.Font swtFont = resourceManager.createFont(FontDescriptor.createFrom(fontData)); + item.setFont(swtFont); + } + } + }); + + + // Updates selected font to font name text + fontFamilyTable.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] selection = fontFamilyTable.getSelection(); + + if(selection.length > 0) { + String family = selection[0].getText(); + fontName.setText(family); + fontChanged(); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + /* + * Forces focus to font name texts and starts editing it, + * if user presses a letter when focus is in font family table + */ + fontFamilyTable.addKeyListener(new KeyListener() { + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + if(Character.isLetter(e.character)) { + fontName.forceFocus(); + fontName.setTextChars(new char[] {e.character}); + fontName.setSelection(1, 1); + } + } + }); + } + + /** + * Implements interactions between font name text and font family table, when + * the text in font name text has been changed. + * @param name New name + * @param autoComplete Has autocomplete been called + */ + protected void fontFamilyTextModified(String name, boolean autoComplete) { + if(name.isEmpty()) + return; + for(int i = 0; i < familyIndex.size(); i++) { + String family = familyIndex.get(i); + if(family.equals(name)) { + //complete match + fontFamilyTable.select(i); + selectFontFamily(name); + break; + } else if(family.toLowerCase().equals(name.toLowerCase())) { + // Wrong case but correct name + fontName.setText(family); + fontName.setSelection(family.length(), family.length()); + fontFamilyTable.setTopIndex(i); + fontChanged(); + break; + } else if(family.toLowerCase().startsWith(name.toLowerCase())) { + if(autoComplete) { + // Fill in the rest of the name + fontName.setText(family); + fontName.setSelection(family.length()); + fontChanged(); + // The beginning is correct, help user by displaying the nearest name + } else { + fontFamilyTable.setTopIndex(i); + } + break; + } + } + } + + + /** + * Adds listeners for font style text and table + */ + protected void addFontStyleListeners() { + + // Font style modify listener + fontStyle.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + Text text = (Text) e.widget; + String name = text.getText(); + fontStyleTextModified(name, false); + } + }); + + // Font style key listener for auto-complete + fontStyle.addKeyListener(new KeyListener() { + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + if ((e.character == ' ') && ((e.stateMask & SWT.CTRL) != 0) ) { + fontStyleTextModified(fontStyle.getText(), true); + e.doit = false; + } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) { + fontChanged(); + } + } + }); + + // Update selected style to font style text + fontStyleTable.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] selection = fontStyleTable.getSelection(); + + if(selection.length > 0) { + String family = selection[0].getText(); + fontStyle.setText(family); + fontChanged(); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + /* + * Forces focus to font style text and starts editing it, + * if user presses a letter when focus is in font style table + */ + fontStyleTable.addKeyListener(new KeyListener() { + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + if(Character.isLetter(e.character)) { + fontStyle.forceFocus(); + fontStyle.setTextChars(new char[] {e.character}); + fontStyle.setSelection(1, 1); + e.doit = false; + } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) { + fontChanged(); + } + } + }); + } + + /** + * Handles interactions between font style text and font style table, when + * font style text has been changed + * + * @param name New text for font style + * @param autoComplete is auto-completion used + */ + protected void fontStyleTextModified(String name, boolean autoComplete) { + if(name.isEmpty()) + return; + + for(int i = 0; i < fontStyleTable.getItemCount(); i++) { + TableItem item = fontStyleTable.getItem(i); + String style = item.getText(); + + if(style.equals(name)) { + //complete match + fontStyleTable.select(i); + break; + } else if(style.toLowerCase().equals(name.toLowerCase())) { + // Wrong case, correct style. -> fix the case + fontStyle.setText(style); + fontStyle.setSelection(style.length()); + fontStyleTable.setTopIndex(i); + fontChanged(); + break; + } else if(style.toLowerCase().startsWith(name.toLowerCase())) { + // The beginning of the word is correct + fontStyleTable.setTopIndex(i); + if(autoComplete) { + // Fill in the rest of the name + fontStyle.setText(style); + fontStyle.setSelection(style.length()); + fontChanged(); + // The beginning is correct, help user by displaying the nearest name + } else { + fontStyleTable.setTopIndex(i); + } + break; + } + } + } + + + /** + * Listeners for font size text and font size table + */ + protected void addFontSizeListeners() { + + // Select an item from size table, if there is a matching item + fontSize.addKeyListener(new KeyListener() { + + @Override + public void keyReleased(KeyEvent e) { + Text text = (Text) e.widget; + String size = text.getText(); + + for(int i = 0; i < sizes.length; i++) { + if(sizes[i].equals(size)) { + fontSizeTable.select(i); + fontSizeTable.setTopIndex(i); + fontChanged(); + break; + } + } + } + + @Override + public void keyPressed(KeyEvent e) { + } + }); + + // Change the text in size text according to the selection in size table + fontSizeTable.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + fontSize.setText(fontSizeTable.getSelection()[0].getText()); + fontChanged(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + // Change focus from table to text, if user starts to write a number + fontSizeTable.addKeyListener(new KeyListener() { + + @Override + public void keyReleased(KeyEvent e) { } + + @Override + public void keyPressed(KeyEvent e) { + if(Character.isDigit(e.character)) { + fontSize.setTextChars(new char[]{e.character}); + fontSize.setSelection(1); + fontSize.forceFocus(); + e.doit = false; + } + } + }); + + } + + /** + * Creates the contents of fontStyleTable according to the selected font family + * @param family Selected font family + */ + protected void selectFontFamily(String family) { + String old = fontStyle.getText(); + String selection = null, optionalSelection = null; + + // Clear the table + fontStyleTable.removeAll(); + + if(familyIndex.indexOf(family) > -1) { + for(int i = 0; i < fonts.get(family).size(); i++) { + Font font = fonts.get(family).get(i); + + String name = font.getFontName(Locale.ROOT); + + // Style is "Regular", unless otherwise defined + String style = "Regular"; + if(name.length() > family.length()) + style = name.substring(family.length() + 1); + + // If previous font was bold, try to conserve the style + if(old.equals(style)) + selection = style; + else if((!old.isEmpty() && style.contains(old)) || optionalSelection == null) + optionalSelection = style; + + TableItem item = new TableItem (fontStyleTable, SWT.NONE); + item.setText (0, style); + item.setData(font); + + // If the font is not symbolic, use the font in the created item + if(font.canDisplay('a')) { + FontData fontData = toSwtFontData(font, 10); + org.eclipse.swt.graphics.Font swtFont = resourceManager.createFont(FontDescriptor.createFrom(fontData)); + item.setFont(swtFont); + } + } + fontStyleTable.setItemCount(fonts.get(family).size()); + + if(selection == null) + selection = optionalSelection; + + fontStyle.setText(selection); + fontStyle.setSelection(selection.length(), selection.length()); + + setFontStyleTableWidth(); + } + } + + /** + * Set width for style table column. Width can change, if scroll bar appears + */ + protected void setFontStyleTableWidth() { + Rectangle area = fontStyleTable.getClientArea(); + Point size = fontStyleTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); + ScrollBar vBar = fontStyleTable.getVerticalBar(); + int width = 100; + if (area.height == 0 || size.y <= area.height) { + Point vBarSize = vBar.getSize(); + width += vBarSize.x; + } + fontStyleTable.getColumn(0).setWidth(width); + } + + + /** + * Builds SWT FontData from AWT font. Simple conversion. + * + * @param font AWT font + * @param height Height for the created data (or -1 if inherited directly from awt font, size matching not guaranteed) + * @return + */ + protected static FontData toSwtFontData(Font font, int height) { + FontData fontData = new FontData(); + fontData.setName(font.getFontName()); + fontData.setStyle(font.getStyle()); + fontData.setHeight(height > 0 ? height : font.getSize()); + return fontData; + } + + + public void addFontModifiedListener(FontModifyListener listener) { + modifyListeners.add(listener); + } + + public void removeFontModifiedListener(FontModifyListener listener) { + modifyListeners.remove(listener); + } + + public List getFontModifiedListener() { + ArrayList listeners = new ArrayList(modifyListeners.size()); + for(Object l : modifyListeners.getListeners()) + listeners.add((FontModifyListener)l); + return listeners; + } + + /** + * Called when some property of the font definiton has changed. + * Calls font change listeners. + */ + protected void fontChanged() { + Font font = getAWTFont(); + if(font != null) { + + int style = 0; + style |= (font.getFontName(Locale.ROOT).contains("Bold") ? SWT.BOLD : 0); + style |= (font.getFontName(Locale.ROOT).contains("Italic") ? SWT.ITALIC : 0); + FontData fontData = new FontData(font.getFamily(Locale.ROOT), font.getSize(), style); + + Object[] listenersArray = modifyListeners.getListeners(); + for (int i = 0; i < listenersArray.length; i++) { + ((FontModifyListener)listenersArray[i]).awtFontChanged(font); + ((FontModifyListener)listenersArray[i]).swtFontDataChanged(fontData); + } + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FunctionLabelFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FunctionLabelFactory.java new file mode 100644 index 00000000..2b4cdcbf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FunctionLabelFactory.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.utils.datastructures.Quad; + + + +public class FunctionLabelFactory extends ReadFactoryImpl { + + private final String propertyURI; + private boolean end; + + public FunctionLabelFactory(String propertyURI, boolean end) { + this.propertyURI = propertyURI; + this.end = end; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Quad((Resource) inputContents, propertyURI, getClass(), end); + } + + + @Override + public String perform(ReadGraph graph, Resource resource) throws DatabaseException { + String value = graph.getPossibleRelatedValue(resource, graph.getResource(propertyURI)); + if(end) { + return "end " + value + ";"; + } else { + return "function " + value; + } + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/IsOutputWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/IsOutputWidget.java new file mode 100644 index 00000000..5297182d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/IsOutputWidget.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.ui.ISelectionUtils; + +public class IsOutputWidget implements Widget{ + + Resource variable = null; + org.simantics.browsing.ui.swt.widgets.Button isOutputButton; + + public IsOutputWidget(Composite parent, WidgetSupport support, int style) { + support.register(this); + isOutputButton = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK); + isOutputButton.setText("Is Output"); + } + + @Override + public void setInput(ISessionContext context, Object input) { + if(input instanceof ISelection) { + ISelection selection = (ISelection)input; + if(selection instanceof IStructuredSelection) { + Resource resource = ISelectionUtils.filterSingleSelection(selection, Resource.class); + if(resource != null) { + variable = resource; + } + } + } + + if(variable == null) return; + + try { + context.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + final boolean isOutput = graph.hasStatement(variable, sr.IsOutput); + final Button button = getWidget(); + button.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(button.isDisposed()) return; + + if(isOutput) + button.setSelection(true); + else + button.setSelection(false); + } + }); + + + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + isOutputButton.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.hasStatement(input, sr.IsOutput)) { + graph.deny(input, sr.IsOutput); + } else { + graph.claim(input, SysdynResource.getInstance(graph).IsOutput, null, input); + } + } + }); + } + + public Button getWidget() { + return isOutputButton.getWidget(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ShortcutTabWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ShortcutTabWidget.java new file mode 100644 index 00000000..56488ec7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ShortcutTabWidget.java @@ -0,0 +1,322 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Locale; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.AsyncListener; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.validation.ValidationUtils; +import org.simantics.sysdyn.utils.Function; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ISelectionUtils; + +public class ShortcutTabWidget implements Widget { + + TabFolder tabFolder; + TabItem variables; + TabItem functions; + Table variableTable; + Table functionTable; + Composite composite; + TableItem item2; + + CopyOnWriteArrayList dependencyListeners = + new CopyOnWriteArrayList(); + + private final LocalResourceManager resourceManager; + + public ShortcutTabWidget(Composite parent, WidgetSupport support, int style) { + if(support!=null) + support.register(this); + + composite = new Composite(parent, style); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); + + tabFolder = new TabFolder (composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(tabFolder); + GridLayoutFactory.fillDefaults().applyTo(tabFolder); + variables = new TabItem(tabFolder, SWT.NULL); + variables.setText("Variables"); + variableTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.NO_FOCUS | SWT.HIDE_SELECTION); + + variables.setControl(variableTable); + + functions = new TabItem(tabFolder, SWT.NULL); + functions.setText("Functions"); + + functionTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.NO_FOCUS | SWT.HIDE_SELECTION); + + // Create a ResourceManager to dispose images when the widget is disposed. + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), functionTable); + + functions.setControl(functionTable); + + // Add the functions only after we know which variable is connected to this widget. + } + + public Composite getWidget() { + return composite; + } + + private void addFunctions(Resource model) { + TableItem item; + + ArrayList functionList = Function.getUserDefinedFunctions(model); + functionList.addAll(Function.getSharedFunctions(model)); + functionList.addAll(Function.getAllBuiltInFunctions()); + + Collections.sort(functionList); + + for(Function function : functionList){ + item = new TableItem(functionTable, SWT.NONE); + item.setText(function.getName() + "()"); + String parameterList = Function.inputListToString(function.getInputList()); + item.setData(function.getName() + "(" + parameterList + ")"); + item.setImage(getImage(this.resourceManager, function)); + } + + } + + @Override + public void setInput(ISessionContext context, Object input) { + if(input instanceof IStructuredSelection) { + final Resource variable = ISelectionUtils.filterSingleSelection(input, Resource.class); + if(variable != null) { + + // Fill the function table + try { + Resource model = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return graph.syncRequest(new PossibleModel(variable)); + } + }); + addFunctions(model); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // Fill the variable table + SimanticsUI.getSession().asyncRequest(new Read>() { + + @Override + public HashSet perform(ReadGraph graph) + throws DatabaseException { + return ValidationUtils.getDependencies(graph, variable); + } + }, new AsyncListener>() { + + @Override + public void execute(AsyncReadGraph graph, + HashSet result) { + + final HashSet dependencies = result; + variableTable.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(variableTable.isDisposed()) return; + + TableItem[] items = variableTable.getItems(); + + // Remove deleted dependencies and create the list of current dependencies (itemStrings) + ArrayList itemStrings = new ArrayList(); + for(TableItem i : items) { + String text = i.getText(); + if(dependencies.contains(text)) + itemStrings.add(text); + else + variableTable.remove(variableTable.indexOf(i)); + } + + // Add all new dependencies + TableItem item; + for(String d : dependencies) { + if(!itemStrings.contains(d)) { + item = new TableItem(variableTable, SWT.NONE); + item.setText(d); + item.setData(d); + } + } + + sort(); + + String selfName = getName(); + + // Time and self are not added if selfName (we have an error or a stock). + if (selfName != null) + { + item = new TableItem(variableTable, SWT.NONE); + item.setText(selfName); + item.setData(selfName); + + item = new TableItem(variableTable, SWT.NONE); + item.setText("time"); + item.setData("time"); + } + + synchronized(dependencyListeners) { + for(Runnable listener : dependencyListeners) + listener.run(); + } + } + }); + } + + /** + * Sort items to alphabetical order. + */ + private void sort() { + TableItem[] connectedVariables = variableTable.getItems(); + Collator collator = Collator.getInstance(Locale.getDefault()); + for (int i = 1; i < connectedVariables.length; i++) { + String value1 = connectedVariables[i].getText(0); + for (int j = 0; j < i; j++) { + String value2 = connectedVariables[j].getText(0); + if (collator.compare(value1, value2) < 0) { + String value = connectedVariables[i].getText(0); + connectedVariables[i].dispose(); + TableItem item2 = new TableItem(variableTable, SWT.NONE, j); + item2.setText(value); + item2.setData(value); + connectedVariables = variableTable.getItems(); + break; + } + } + } + } + + /** + * Get the name of the respective variable. + */ + private String getName() { + String selfName = null; + try { + selfName = SimanticsUI.getSession().syncRequest(new Read() { + @Override + public String perform(ReadGraph graph) + throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Object selfName = graph.getPossibleRelatedValue(variable, l0.HasName); + if (selfName instanceof String) { + return (String)selfName; + } + return null; + } + }); + } + catch (DatabaseException e) { + e.printStackTrace(); + } + return selfName; + } + + @Override + public void exception(AsyncReadGraph graph, + Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return variableTable.isDisposed(); + } + }); + } + } + } + + + + public void addFocusListener(FocusListener listener) { + this.functionTable.addFocusListener(listener); + this.variableTable.addFocusListener(listener); + } + + public void addMouseListener(MouseListener listener) { + this.functionTable.addMouseListener(listener); + this.variableTable.addMouseListener(listener); + } + + public void addDependencyListener(Runnable listener) { + synchronized(dependencyListeners) { + dependencyListeners.add(listener); + } + } + + public void removeDependencyListener(Runnable listener) { + synchronized(dependencyListeners) { + dependencyListeners.remove(listener); + } + } + + public Table getVariableTable() { + return variableTable; + } + + /** + * Get the icon image for each type of Modelica function. + * @param rm LocalResourceManager for which the image is created. + * @param function Modelica function + * @return Image to be shown e.g. in assistive text feed and ShortcutTab + */ + public static Image getImage(LocalResourceManager rm, Function function) { + switch (function.getType()) { + case USER_DEFINED: + return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/function.png"))); + case SHARED: + return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/functionLink.png"))); + case VENSIM: + return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/vensimFunction.png"))); + case SYSDYN: + return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/sysdynFunction.png"))); + case MODELICA: + return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/modelicaFunction.png"))); + case MODELICA_ARRAY: + return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/modelicaArrayFunction.png"))); + default: + return null; + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/UnitComboWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/UnitComboWidget.java new file mode 100644 index 00000000..d2a770fc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/UnitComboWidget.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.TrackedCombo; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; + +public class UnitComboWidget extends TrackedCombo { + + public UnitComboWidget(Composite parent, WidgetSupport support, int style) { + super(parent, support, style); + + + // Add all units used in the model to the unit combo + setItemFactory(new ReadFactoryImpl>() { + + @Override + public Map perform(ReadGraph graph, final Resource input) throws DatabaseException { + Map map = new HashMap(); + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource model = graph.getPossibleObject(input, l0.PartOf); + if (model != null) { + Collection variables = graph.getObjects(model, l0.ConsistsOf); + for(Resource v : variables) { + Object unit = graph.getPossibleRelatedValue(v, sr.Variable_unit); + if (unit != null && !map.keySet().contains(unit)) { + map.put((String)unit, (String)unit); + + } + } + } + return map; + } + }); + + // Set initial selection of unit combo + setSelectionFactory(new ReadFactoryImpl() { + + @Override + public String perform(ReadGraph graph, final Resource input) throws DatabaseException { + String unit = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).Variable_unit); + if(unit == null) + return ""; + else + return unit; + } + }); + + // Modify unit + addModifyListener(new ComboModifyListenerImpl() { + + @Override + public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException { + graph.denyValue(input, SysdynResource.getInstance(graph).Variable_unit); + graph.claimLiteral(input, SysdynResource.getInstance(graph).Variable_unit, text); + + Resource conf = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf); + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, conf); + sm.getMapping().domainModified(input); + sm.update(graph); + } + }); + + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveOrientationGroup.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveOrientationGroup.java new file mode 100644 index 00000000..dbdf9514 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveOrientationGroup.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.WidgetImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.datastructures.Quad; + +public class ValveOrientationGroup extends WidgetImpl { + + Group group; + Button vertical, horizontal; + + public ValveOrientationGroup(Composite parent, ISessionContext context, WidgetSupport support, int style) { + super(support); + group = new Group(parent, SWT.NONE); + group.setText("Valve orientation"); + GridDataFactory.fillDefaults().applyTo(group); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(group); + + horizontal = new Button(group, support, SWT.RADIO); + horizontal.setText("Horizontal"); + horizontal.setSelectionFactory(new OrientationSelectionFactory(horizontal, SysdynResource.URIs.Horizontal, true)); + horizontal.addSelectionListener(new OrientationSelectionListener(context, SysdynResource.URIs.Horizontal)); + + vertical = new Button(group, support, SWT.RADIO); + vertical.setText("Vertical"); + vertical.setSelectionFactory(new OrientationSelectionFactory(vertical, SysdynResource.URIs.Vertical)); + vertical.addSelectionListener(new OrientationSelectionListener(context, SysdynResource.URIs.Vertical)); + } + + @Override + public void setInput(ISessionContext context, Object input) { + horizontal.setInput(context, input); + vertical.setInput(context, input); + } + + @Override + public Control getControl() { + return this.group; + } + + private class OrientationSelectionFactory extends ReadFactoryImpl { + + boolean defaultSelected; + String uri; + Button button; + + public OrientationSelectionFactory(Button button, String uri) { + this(button, uri, false); + } + + public OrientationSelectionFactory(Button button, String uri, boolean defaultSelected) { + this.uri = uri; + this.defaultSelected = defaultSelected; + this.button = button; + } + + public Object getIdentity(Object inputContents) { + return new Quad>(button, uri, defaultSelected, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, Resource valve) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + if(!graph.isInstanceOf(valve, sr.Valve)) + return Boolean.FALSE; + + Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement); + if(symbol == null) + return Boolean.FALSE; + + Resource orientation = graph.getPossibleObject(symbol, sr.ValveSymbol_orientation); + + if(orientation == null) + return defaultSelected; + + return orientation.equals(graph.getResource(uri)); + } + + } + + + private class OrientationSelectionListener extends SelectionListenerImpl { + + String uri; + + public OrientationSelectionListener(ISessionContext context, String uri) { + super(context); + this.uri = uri; + } + + @Override + public void apply(WriteGraph graph, Resource valve) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + if(!graph.isInstanceOf(valve, sr.Valve)) + return; + + Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement); + if(symbol == null) + return; + + if(graph.hasStatement(symbol, sr.ValveSymbol_orientation)) + graph.deny(symbol, sr.ValveSymbol_orientation); + graph.claim(symbol, sr.ValveSymbol_orientation, graph.getResource(uri)); + + if(graph.hasStatement(symbol, sr.ValveSymbol_textLocation)) + graph.deny(symbol, sr.ValveSymbol_textLocation); + if(sr.Vertical.equals(graph.getResource(uri))) + graph.claim(symbol, sr.ValveSymbol_textLocation, sr.Right); + + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveTextLocationGroup.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveTextLocationGroup.java new file mode 100644 index 00000000..87615966 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveTextLocationGroup.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.WidgetImpl; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.datastructures.Quad; + +public class ValveTextLocationGroup extends WidgetImpl { + + Group group; + Button top, bottom, left, right; + + public ValveTextLocationGroup(Composite parent, ISessionContext context, WidgetSupport support, int style) { + super(support); + + group = new Group(parent, SWT.NONE); + group.setText("Text location"); + GridDataFactory.fillDefaults().applyTo(group); + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(group); + + top = new Button(group, support, SWT.RADIO); + top.setText("Top"); + top.setSelectionFactory(new LocationSelectionFactory(top, SysdynResource.URIs.Top)); + top.addSelectionListener(new LocationSelectionListener(context, SysdynResource.URIs.Top)); + + bottom = new Button(group, support, SWT.RADIO); + bottom.setText("Bottom"); + bottom.setSelectionFactory(new LocationSelectionFactory(bottom, SysdynResource.URIs.Bottom, true)); + bottom.addSelectionListener(new LocationSelectionListener(context, SysdynResource.URIs.Bottom)); + + left = new Button(group, support, SWT.RADIO); + left.setText("Left"); + left.setSelectionFactory(new LocationSelectionFactory(left, SysdynResource.URIs.Left)); + left.addSelectionListener(new LocationSelectionListener(context, SysdynResource.URIs.Left)); + + right = new Button(group, support, SWT.RADIO); + right.setText("Right"); + right.setSelectionFactory(new LocationSelectionFactory(right, SysdynResource.URIs.Right)); + right.addSelectionListener(new LocationSelectionListener(context, SysdynResource.URIs.Right)); + + } + + @Override + public void setInput(ISessionContext context, Object input) { + top.setInput(context, input); + bottom.setInput(context, input); + left.setInput(context, input); + right.setInput(context, input); + } + + @Override + public Control getControl() { + return this.group; + } + + + private class LocationSelectionFactory extends ReadFactoryImpl { + + boolean defaultSelected; + String uri; + Button button; + + public LocationSelectionFactory(Button button, String uri) { + this(button, uri, false); + } + + public LocationSelectionFactory(Button button, String uri, boolean defaultSelected) { + this.uri = uri; + this.defaultSelected = defaultSelected; + this.button = button; + } + + public Object getIdentity(Object inputContents) { + return new Quad>(button, uri, defaultSelected, getClass()); + } + + @Override + public Boolean perform(ReadGraph graph, Resource valve) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + if(!graph.isInstanceOf(valve, sr.Valve)) + return Boolean.FALSE; + + Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement); + if(symbol == null) + return Boolean.FALSE; + + Resource location = graph.getPossibleObject(symbol, sr.ValveSymbol_textLocation); + + if(location == null) + return defaultSelected; + + return location.equals(graph.getResource(uri)); + } + + } + + + private class LocationSelectionListener extends SelectionListenerImpl { + + String uri; + + public LocationSelectionListener(ISessionContext context, String uri) { + super(context); + this.uri = uri; + } + + @Override + public void apply(WriteGraph graph, Resource valve) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + if(!graph.isInstanceOf(valve, sr.Valve)) + return; + + Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement); + if(symbol == null) + return; + + if(graph.hasStatement(symbol, sr.ValveSymbol_textLocation)) + graph.deny(symbol, sr.ValveSymbol_textLocation); + graph.claim(symbol, sr.ValveSymbol_textLocation, graph.getResource(uri)); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/AvailableEnumerations.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/AvailableEnumerations.java new file mode 100644 index 00000000..76a46f00 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/AvailableEnumerations.java @@ -0,0 +1,53 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.ResourceArray; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; + +public class AvailableEnumerations extends ViewpointContributorImpl { + + @Override + public Collection getContribution(ReadGraph graph, ResourceArray input) + throws DatabaseException { + Resource[] selection = input.resources; + if(selection.length < 1) + return Collections.emptyList(); + Layer0 l0 = Layer0.getInstance(graph); + Resource configuration = null; + + // Variables need to be from the same configuration + for(Resource r : selection) { + Resource conf = graph.getPossibleObject(r, l0.PartOf); + if(configuration == null || conf.equals(configuration)) + configuration = conf; + else + return Collections.emptyList(); + } + + ArrayList> result = new ArrayList>(); + SysdynResource sr = SysdynResource.getInstance(graph); + if(configuration == null) + return result; + for(Resource r : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) { + result.add(new EnumerationNode(r)); + } + return result; + } + + @Override + public String getViewpointId() { + return "Available enumerations"; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ComboBoxModifier.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ComboBoxModifier.java new file mode 100644 index 00000000..d45b1a2a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ComboBoxModifier.java @@ -0,0 +1,136 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.common.modifiers.EnumeratedValue; +import org.simantics.browsing.ui.common.modifiers.Enumeration; +import org.simantics.browsing.ui.content.Labeler.CustomModifier; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.utils.ObjectUtils; + +public abstract class ComboBoxModifier implements CustomModifier { + + private final Enumeration enumeration; + private final EnumeratedValue value; + private final List values; + private final Session session; + private Combo combo; + int select; + + public ComboBoxModifier(Session session, Enumeration enumeration, T value) { + this(session, enumeration, enumeration.find(value)); + } + + public ComboBoxModifier(Session session, Enumeration enumeration, + EnumeratedValue value) { + if (session == null) + throw new NullPointerException("null session"); + if (enumeration == null) + throw new NullPointerException("null enumeration"); + if (enumeration.size() == 0) + throw new IllegalArgumentException(""); + + this.enumeration = enumeration; + this.value = value; + this.session = session; + + select = 0; + boolean found = false; + + this.values = new ArrayList(); + for (EnumeratedValue v : enumeration.values()) { + values.add(v.getName()); + + if(v == value) + found = true; + + if(found == false) + select++; + } + } + + @Override + public Object createControl(Object parentControl, Object controlItem, + int columnIndex, NodeContext context) { + + combo = new Combo((Composite) parentControl, SWT.DROP_DOWN + | SWT.BORDER | SWT.READ_ONLY); + + for (String item : values) { + combo.add(item); + } + + combo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + String index = ((Combo) e.getSource()).getText(); + modify(index); + } + }); + + combo.select(select); + + return combo; + + } + + @Override + public String getValue() { + return enumeration.values().get(0).getName(); + } + + @Override + public final String isValid(String label) { + if (enumeration.findByName(label) == null) + return "Value '" + label + "' is not among the enumerated values " + enumeration.values(); + return null; + } + + @Override + public void modify(String label) { + + int index = values.indexOf(label); + if (index == -1) + throw new IllegalArgumentException("Cannot modify enumeration with value '" + label + "', not among the enumerated values " + values); + + EnumeratedValue oldEnumValue = value; + EnumeratedValue newEnumValue = enumeration.values().get(index); + + final T oldObject = oldEnumValue != null ? oldEnumValue.getObject() : null; + final T newObject = newEnumValue != null ? newEnumValue.getObject() : null; + + if (ObjectUtils.objectEquals(oldObject, newObject)) + return; + + try { + session.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + modifyWithObject(graph, oldObject, newObject); + } + }); + } catch (DatabaseException e) { + handleException(e); + } + + combo.dispose(); + } + + protected abstract void modifyWithObject(WriteGraph graph, T oldEnumObject, T enumObject) throws DatabaseException; + + protected void handleException(DatabaseException e) { + throw new RuntimeException(e); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationLabeler.java new file mode 100644 index 00000000..4fa7ef9e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationLabeler.java @@ -0,0 +1,41 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.HashMap; +import java.util.Map; + +import org.simantics.browsing.ui.graph.impl.contributor.labeler.ColumnLabelerContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; + +public class ConflictingEnumerationLabeler extends ColumnLabelerContributorImpl{ + + @Override + public Map getLabel(ReadGraph graph, ConflictingEnumerationNode input) + throws DatabaseException { + HashMap map = new HashMap(); + + boolean first = true; + StringBuilder names = new StringBuilder(); + for(Resource r : (Resource[])input.data) { + if(!first) + names.append(", "); + first = false; + + String name = "empty"; + if(r != null) + name = NameUtils.getSafeName(graph, r); + names.append(name); + } + map.put(ColumnKeys.ENUMERATION, names.toString()); + + map.put(ColumnKeys.INDEXES, "Conflicting enumerations"); + + return map; + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationNode.java new file mode 100644 index 00000000..b93f849c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationNode.java @@ -0,0 +1,11 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import org.simantics.browsing.ui.common.node.AbstractNode; + +public class ConflictingEnumerationNode extends AbstractNode { + + public ConflictingEnumerationNode(Object resources) { + super(resources); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexLabeler.java new file mode 100644 index 00000000..a740831f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexLabeler.java @@ -0,0 +1,20 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; + +public class EnumerationIndexLabeler extends LabelerContributor{ + + @Override + public String getLabel(ReadGraph graph, EnumerationIndexNode index) throws DatabaseException { + Resource r = index.data; + if(r == null) return "Null resource"; + String name = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasName); + return name == null ? "No name" : name; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexNode.java new file mode 100644 index 00000000..ff7b7021 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexNode.java @@ -0,0 +1,93 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.IDoubleClickableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.VariableNameValidator; +import org.simantics.ui.SimanticsUI; + +public class EnumerationIndexNode extends AbstractNode implements IModifiableNode, IDoubleClickableNode { + + public EnumerationIndexNode(Resource resource) { + super(resource); + } + + @Override + public Modifier getModifier(String columnId) { + Modifier modifier = new Modifier() { + + @Override + public String getValue() { + Read request = + new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + String name = graph.getPossibleRelatedValue(data, Layer0.getInstance(graph).HasName); + return name != null ? name : ""; + } + + }; + try { + return SimanticsUI.getSession().syncRequest(request); + } catch (DatabaseException e) { + e.printStackTrace(); + return ""; + } + } + + @Override + public String isValid(String label) { + if(!new VariableNameValidator().isValidModelica(label, true)) + return "Not valid"; + return null; + } + + @Override + public void modify(final String label) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + graph.claimLiteral(data, Layer0.getInstance(graph).HasName, label); + } + }); + } + + }; + + return modifier; + + + + + } + + @Override + public boolean handleDoubleClick() { + return true; + } + + public void setShowInChartsSelected(final boolean selected) { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + graph.claimLiteral(data, sr.EnumerationIndex_showEnumerationIndexInCharts, selected); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexes.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexes.java new file mode 100644 index 00000000..a4758fc2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexes.java @@ -0,0 +1,40 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; + +public class EnumerationIndexes extends ViewpointContributorImpl { + + @Override + public Collection getContribution(ReadGraph graph, Resource input) + throws DatabaseException { + if(input == null) + return null; + SysdynResource sr = SysdynResource.getInstance(graph); + if(!graph.isInstanceOf(input, sr.Enumeration)) + return null; + Resource enumerationIndexList = graph.getPossibleObject(input, sr.Enumeration_enumerationIndexList); + if(enumerationIndexList == null) + return null; + ArrayList> result = new ArrayList>(); + for(Resource r : ListUtils.toList(graph, enumerationIndexList)) { + result.add(new EnumerationIndexNode(r)); + } + return result; + } + + @Override + public String getViewpointId() { + return "Enumeration indexes"; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationLabeler.java new file mode 100644 index 00000000..f274331a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationLabeler.java @@ -0,0 +1,52 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.simantics.browsing.ui.graph.impl.contributor.labeler.ColumnLabelerContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; + +public class EnumerationLabeler extends ColumnLabelerContributorImpl{ + + @Override + public Map getLabel(ReadGraph graph, EnumerationNode input) + throws DatabaseException { + + String name = NameUtils.getSafeName(graph, input.data); + HashMap map = new HashMap(); + map.put(ColumnKeys.ENUMERATION, name); + + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource enumerationIndexes = graph.getPossibleObject(input.data, sr.Enumeration_enumerationIndexList); + Iterator indexes = ListUtils.toList(graph, enumerationIndexes).iterator(); + StringBuilder sb = new StringBuilder(); + sb.append("["); + while(indexes.hasNext()) { + Resource i = indexes.next(); + sb.append(NameUtils.getSafeName(graph, i)); + if(indexes.hasNext()) + sb.append(", "); + } + sb.append("]"); + + Boolean relaceable = graph.getPossibleRelatedValue(input.data, sr.Enumeration_isReplaceable); + if(Boolean.TRUE.equals(relaceable)) { + sb.append(" Replaceable"); + } + + map.put(ColumnKeys.INDEXES, sb.toString()); + + return map; + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationNode.java new file mode 100644 index 00000000..2d960058 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationNode.java @@ -0,0 +1,12 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.db.Resource; + +public class EnumerationNode extends AbstractNode { + + public EnumerationNode(Resource resource) { + super(resource); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/NameAndArrayRangeModifyListener.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/NameAndArrayRangeModifyListener.java new file mode 100644 index 00000000..90b4319c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/NameAndArrayRangeModifyListener.java @@ -0,0 +1,147 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.LinkedHashMap; +import java.util.StringTokenizer; + +import org.eclipse.swt.widgets.Combo; +import org.simantics.Simantics; +import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.VirtualGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.ArrayExpressionCombo; +import org.simantics.sysdyn.ui.properties.widgets.ExpressionWidget; +import org.simantics.sysdyn.ui.utils.VariableNameValidator; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Modification listener ONLY for ArrayExpressionCombos in EquationTabs. + * @author Teemu Lempinen + * + */ +public class NameAndArrayRangeModifyListener extends ComboModifyListenerImpl implements Widget { + + Resource lastExpression; + ExpressionWidget expressionWidget; + ArrayExpressionCombo arrayExpressionCombo; + Object lastInput; + + public NameAndArrayRangeModifyListener(WidgetSupport support, ExpressionWidget expressionWidget, ArrayExpressionCombo arrayExpressionCombo) { + support.register(this); + this.expressionWidget = expressionWidget; + this.arrayExpressionCombo = arrayExpressionCombo; + } + + @Override + public void setInput(ISessionContext context, Object input) { + super.setInput(context, input); + this.lastInput = input; + } + + @Override + public void modifyText(TrackedModifyEvent e) { + Combo combo = (Combo)e.getWidget(); + LinkedHashMap data = (LinkedHashMap) combo.getData(); + + Resource activeExpression = null; + try { + final Object input = lastInput; + activeExpression = Simantics.getSession().syncRequest(new Read() { + @Override + public Resource perform(ReadGraph graph) + throws DatabaseException { + Resource variable = ISelectionUtils.filterSingleSelection(input, Resource.class); + return graph.getPossibleObject(variable, SysdynResource.getInstance(graph).IndependentVariable_activeExpression); + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + + Resource expression = (Resource) data.get(combo.getText()); + if(expression != null) { + lastExpression = expression; + arrayExpressionCombo.setLastSelectedIndex(combo.getSelectionIndex()); + } else { + for(Object key : data.keySet()) { + int index = arrayExpressionCombo.getLastSelectedIndex() < 0 ? 0 : arrayExpressionCombo.getLastSelectedIndex(); + if((Integer)combo.getData((String)key) == index) { + lastExpression = (Resource) data.get(key); + break; + } + } + } + + // If expression has changed (i.e. user actually selects a different item in the combo), save the previous + if(lastExpression != null && !lastExpression.equals(activeExpression)) { + expressionWidget.save(); + } + + super.modifyText(e); + } + + @Override + public void applyText(WriteGraph graph, final Resource variable, String text) + throws DatabaseException { + StringTokenizer st = new StringTokenizer(text, "[]"); + final String newName = st.nextToken(); + String range = null; + if(st.hasMoreTokens()) { + range = st.nextToken(); + } + String originalName = graph.getRelatedValue(variable, Layer0.getInstance(graph).HasName); + if(!originalName.equals(newName)) { + Resource configuration = graph.getPossibleObject(variable, Layer0.getInstance(graph).PartOf); + new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, newName); + graph.claimLiteral(variable, Layer0.getInstance(graph).HasName, newName); + } + + SysdynResource sr = SysdynResource.getInstance(graph); + + if(range != null && lastExpression != null) { + String oldRange = graph.getPossibleRelatedValue(lastExpression, sr.Expression_arrayRange); + if(oldRange == null || !range.equals(oldRange)) { + graph.claimLiteral(lastExpression, sr.Expression_arrayRange, "[" + range + "]"); + } + } else if (range == null && lastExpression != null && graph.hasStatement(lastExpression, sr.Expression_arrayRange)) { + graph.deny(lastExpression, sr.Expression_arrayRange); + } + + Resource activeExpression = graph.getPossibleObject(variable, sr.IndependentVariable_activeExpression); + + if(lastExpression != null && !lastExpression.equals(activeExpression)) { + VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); + final Session session = graph.getSession(); + session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + VirtualGraph runtime = graph.getService(VirtualGraph.class); + session.asyncRequest(new WriteRequest(runtime) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression)) + graph.deny(variable, sr.IndependentVariable_activeExpression); + graph.claim(variable, sr.IndependentVariable_activeExpression, lastExpression); + } + }); + } + }); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/RedeclarationNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/RedeclarationNode.java new file mode 100644 index 00000000..6c2b6781 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/RedeclarationNode.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.ArrayList; + +import org.simantics.browsing.ui.common.modifiers.EnumeratedValue; +import org.simantics.browsing.ui.common.modifiers.Enumeration; +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; +import org.simantics.ui.SimanticsUI; + +public class RedeclarationNode extends AbstractNode implements IModifiableNode { + + private Resource module; + + public RedeclarationNode(ReadGraph graph, final Resource module, Resource enumeration) { + super(enumeration); + this.module = module; + } + + /** + * + * @param graph + * @return + */ + public Resource getReplacingEnumeration(ReadGraph graph) { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource result = null; + try { + Resource redeclaration = getRedeclaration(graph); + if(redeclaration != null) { + result = graph.getSingleObject(redeclaration, sr.Redeclaration_replacingEnumeration); + } + } catch(DatabaseException e) { + e.printStackTrace(); + } + + return result; + } + + + public Resource getModule() { + return module; + } + + public void setModule(Resource module) { + this.module = module; + } + + public Resource getRedeclaration(ReadGraph graph) { + try { + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource redeclaration : graph.syncRequest(new ObjectsWithType(module, sr.Module_redeclaration, sr.Redeclaration))) { + Resource replacedEnumeration = graph.getPossibleObject(redeclaration, sr.Redeclaration_replacedEnumeration); + if(replacedEnumeration != null && replacedEnumeration.equals(getReplacedEnumeration())) { + return redeclaration; + } + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + return null; + } + + public void setRedeclaration(WriteGraph graph, Resource redeclaration) { + try { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource oldRedeclaration = getRedeclaration(graph); + if(oldRedeclaration != null || redeclaration == null) { + graph.deny(module, sr.Module_redeclaration, oldRedeclaration); + } + + if(redeclaration != null) + graph.claim(module, sr.Module_redeclaration, redeclaration); + + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + public Resource getReplacedEnumeration() { + return this.data; + } + + @Override + public Modifier getModifier(String columnId) { + + if(!ColumnKeys.REPLACED_WITH.equals(columnId)) + return null; + + ComboBoxModifier cbm = null; + + try { + cbm = SimanticsUI.getSession().syncRequest(new Read>() { + + @Override + public ComboBoxModifier perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + ArrayList> values = new ArrayList>(); + + + Resource configuration = graph.getSingleObject(module, l0.PartOf); + + for(Resource enumeration : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) { + String name = NameUtils.getSafeName(graph, enumeration); + values.add(new EnumeratedValue(name, enumeration)); + } + + if(values.size() == 0) + return null; + + values.add(0, new EnumeratedValue("", null)); + Enumeration enumeration = new Enumeration(values); + + ComboBoxModifier cbm = new ComboBoxModifier(graph.getSession(), enumeration, getReplacingEnumeration(graph)) { + + @Override + protected void modifyWithObject(WriteGraph graph, Resource oldEnumObject, + Resource enumObject) throws DatabaseException { + + if(enumObject == null) { + setRedeclaration(graph, null); + } else if(!enumObject.equals(oldEnumObject)) { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource redeclaration = GraphUtils.create2(graph, + sr.Redeclaration, + sr.Redeclaration_replacedEnumeration, getReplacedEnumeration(), + sr.Redeclaration_replacingEnumeration, enumObject); + setRedeclaration(graph, redeclaration); + } + + } + }; + + return cbm; + + } + }); + } catch (DatabaseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return cbm; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerations.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerations.java new file mode 100644 index 00000000..7f8a1fa2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerations.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; + +public class ReplaceableEnumerations extends ViewpointContributorImpl { + + @Override + public Collection getContribution(ReadGraph graph, Resource input) + throws DatabaseException { + ArrayList result = new ArrayList(); + if(input == null) + return result; + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + + Resource moduleType = graph.getPossibleObject(input, l0.InstanceOf); + if(moduleType == null) + return result; + Resource configuration = graph.getPossibleObject(moduleType, sr2.IsDefinedBy); + if(configuration == null) + return result; + + for(Resource r : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) { + if(Boolean.TRUE.equals(graph.getRelatedValue(r, sr.Enumeration_isReplaceable))) + result.add(new RedeclarationNode(graph, input, r)); + } + + return result; + } + + @Override + public String getViewpointId() { + return "Replaceable enumerations"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerationsLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerationsLabeler.java new file mode 100644 index 00000000..68a44dba --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerationsLabeler.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.HashMap; +import java.util.Map; + +import org.simantics.browsing.ui.graph.impl.contributor.labeler.ColumnLabelerContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; + +public class ReplaceableEnumerationsLabeler extends ColumnLabelerContributorImpl{ + + @Override + public Map getLabel(ReadGraph graph, RedeclarationNode input) + throws DatabaseException { + HashMap map = new HashMap(); + + String name = NameUtils.getSafeName(graph, input.data); + map.put(ColumnKeys.ENUMERATION, name); + + Resource replacingEnumeration = input.getReplacingEnumeration(graph); + String replacingEnumerationName = ""; + if(replacingEnumeration != null) + replacingEnumerationName = NameUtils.getSafeName(graph, replacingEnumeration); + + map.put(ColumnKeys.REPLACED_WITH, replacingEnumerationName); + return map; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableIndexesWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableIndexesWidget.java new file mode 100644 index 00000000..0dd0a49a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableIndexesWidget.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.ui.ISelectionUtils; + +public class ReplaceableIndexesWidget implements Widget { + + Resource variable = null; + boolean selected = false; + org.simantics.browsing.ui.swt.widgets.Button isReplaceableButton; + + public ReplaceableIndexesWidget(Composite parent, WidgetSupport support, int style) { + support.register(this); + isReplaceableButton = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK); + isReplaceableButton.setText("Can be replaced by parent module"); + } + + @Override + public void setInput(ISessionContext context, Object input) { + if(input instanceof ISelection) { + ISelection selection = (ISelection)input; + if(selection instanceof IStructuredSelection) { + Resource resource = ISelectionUtils.filterSingleSelection(selection, Resource.class); + if(resource != null) { + variable = resource; + } + } + } + + if(variable == null) return; + + try { + context.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + final Boolean replaceable = graph.getPossibleRelatedValue(variable, sr.Enumeration_isReplaceable); + if(replaceable != null) + selected = replaceable; + final Button button = getWidget(); + button.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(button.isDisposed()) return; + + if(replaceable) + button.setSelection(true); + else + button.setSelection(false); + } + }); + + + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + isReplaceableButton.addSelectionListener(new SelectionListenerImpl(context) { + + @Override + public void apply(WriteGraph graph, Resource input) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Boolean replaceable = graph.getPossibleRelatedValue(input, sr.Enumeration_isReplaceable); + if(Boolean.TRUE.equals(replaceable)) { + graph.claimLiteral(input, sr.Enumeration_isReplaceable, false); + selected = false; + } else { + graph.claimLiteral(input, sr.Enumeration_isReplaceable, true); + selected = true; + } + } + }); + } + + public Button getWidget() { + return isReplaceableButton.getWidget(); + } + + public boolean getSelection() { + return selected; + } + + public void addSelectionListener(SelectionListener listener) { + isReplaceableButton.addSelectionListener(listener); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ShowInChartsCheckBox.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ShowInChartsCheckBox.java new file mode 100644 index 00000000..da412f47 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ShowInChartsCheckBox.java @@ -0,0 +1,21 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import org.simantics.browsing.ui.CheckedState; +import org.simantics.browsing.ui.graph.contributor.labeler.CheckedStateContributor; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; + +public class ShowInChartsCheckBox extends CheckedStateContributor { + + @Override + public CheckedState getState(ReadGraph graph, EnumerationIndexNode input) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Boolean selected = graph.getPossibleRelatedValue(input.data, sr.EnumerationIndex_showEnumerationIndexInCharts, Bindings.BOOLEAN); + return selected ? CheckedState.CHECKED : CheckedState.NOT_CHECKED; + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerations.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerations.java new file mode 100644 index 00000000..29402910 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerations.java @@ -0,0 +1,115 @@ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.ResourceArray; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; + +public class UsedEnumerations extends ViewpointContributorImpl { + + @Override + public Collection getContribution(ReadGraph graph, ResourceArray input) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource[] selection = input.resources; + if(selection.length < 1) + return Collections.emptyList(); + + /* Collect enumerations for all variables + * var1 + * - enum1 + * - enum2 + * var2 + * - enum1 + * - enum2 + * - enum3 + */ + ArrayList> variableEnumerations = new ArrayList>(); + for(Resource variable : selection) { + Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList); + if(arrayIndexes != null) { + variableEnumerations.add(ListUtils.toList(graph, arrayIndexes)); + } else { + variableEnumerations.add(new ArrayList()); + } + } + + + /* Construct a list of enumerations + * FirstEnumeration + * - var1.first + * - var2.first + * - var3.first + * SecondEnumeration + * - var1.second + * - ... + */ + ArrayList> enumerations = new ArrayList>(); + + int index = 0; + while(true) { + + // Break loop if enumerations for all variables have been recorded + boolean b = true; + for(List varEnums : variableEnumerations) { + if(index < varEnums.size()) { + b = false; + break; + } + } + + if(b) break; + + for(List current : variableEnumerations) { + if(index == enumerations.size()) + enumerations.add(index, new ArrayList()); + Resource enumeration = index < current.size()? current.get(index) : null; + enumerations.get(index).add(enumeration); + } + + index++; + } + + // Build nodes + ArrayList> result = new ArrayList>(); + + if(enumerations.size() == 1 && (enumerations.get(0).size() == 0 || (enumerations.get(0).size() == 1 && enumerations.get(0).get(0) == null))) + return result; + + for(List enumeration : enumerations) { + boolean same = true; + for(int i = 0; i < enumeration.size() - 1; i++) { + if(enumeration.get(i) == null || enumeration.get(i + 1) == null || + !enumeration.get(i).equals(enumeration.get(i + 1))) { + same = false; + break; + } + } + + if(!same) { + result.add(new ConflictingEnumerationNode(enumeration.toArray(new Resource[enumeration.size()]))); + } else { + result.add(new EnumerationNode(enumeration.get(0))); + } + } + + + + return result; + } + + @Override + public String getViewpointId() { + return "Used enumerations"; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerationsManyVariables.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerationsManyVariables.java new file mode 100644 index 00000000..28defab2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerationsManyVariables.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.arrays; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; + +public class UsedEnumerationsManyVariables extends ViewpointContributorImpl> { + + @Override + public Collection getContribution(ReadGraph graph, List input) + throws DatabaseException { + + ArrayList> result = new ArrayList>(); + + return result; + } + + @Override + public String getViewpointId() { + return "Available enumerations"; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/AuxiliaryExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/AuxiliaryExpression.java new file mode 100644 index 00000000..48a5e7d1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/AuxiliaryExpression.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +public class AuxiliaryExpression extends BasicExpression { + + public AuxiliaryExpression(ExpressionWidgetInput input) { + super(input); + try { + this.expressionType = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return SysdynResource.getInstance(graph).NormalExpression; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void createExpressionFields(Composite parent, Map data, Table allowedVariables) { + // Create the single field + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent); + String equation = data.get("equation") != null ? (String)data.get("equation") : ""; + + Label l = new Label(parent, SWT.NONE); + l.setText("="); + + expression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input); + expression.setExpression(equation); + GridDataFactory.fillDefaults().grab(true, true).applyTo(expression); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java new file mode 100644 index 00000000..b5226951 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.ExpressionUtils; +import org.simantics.ui.SimanticsUI; + +/** + * Basic expression that is used with parameter, auxiliary and constant + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class BasicExpression implements IExpression { + + protected ExpressionField expression; + protected Resource expressionType; + protected ExpressionWidgetInput input; + + public BasicExpression(ExpressionWidgetInput input) { + this.input = input; + } + + @Override + public void createExpressionFields(Composite parent, Map data, Table allowedVariables) { + // Create the single field + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent); + String equation = data.get("equation") != null ? (String)data.get("equation") : ""; + + Label l = new Label(parent, SWT.NONE); + l.setText("="); + + expression = new ExpressionField(parent, SWT.BORDER, null, false, input); + expression.setExpression(equation); + GridDataFactory.fillDefaults().grab(true, true).applyTo(expression); + + } + + @Override + public void focus() { + this.expression.focus(); + + } + + @Override + public List getExpressionFields() { + return Arrays.asList(this.expression); + } + + @Override + public void readData(final Resource expression, Map data) { + String equation = null; + if (expression != null && data.get("equation") == null) { + try { + equation = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if (expression != null) { + String equation = graph.getPossibleRelatedValue(expression, sr.Expression_equation); + if(equation != null) + return equation; + } + + return ""; + + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + data.put("equation", equation); + } + } + + @Override + public void replaceSelection(String var) { + if(expression != null) { + IDocument doc = expression.getDocument(); + try { + Point selection = expression.getSelection(); + doc.replace(selection.x, selection.y, var); + expression.setSelection(selection.x + var.length()); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + } + + @Override + public void save(final Resource expression, Map data) { + final String currentText = this.expression.getExpression(); + final String oldEquation = (String)data.get("equation"); + + if(oldEquation == null || + (currentText != null && expressionType != null)) { + data.put("equation", currentText); + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph g) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + + // If nothing has changed, do nothing + if (oldEquation != null + && expression != null + && g.isInstanceOf(expression, expressionType) + && currentText.equals(oldEquation)) { + return; + } + + // Force change to parameter, if the equation is a parameter + if(ExpressionUtils.isParameter(currentText)) { + if(!expressionType.equals(sr.ConstantExpression)) + expressionType = sr.ParameterExpression; + } else { + expressionType = sr.NormalExpression; + } + + // If the current expression type is different than the target expression type, create a new expression + if(!g.isInstanceOf(expression, expressionType)) { + + final Resource newExpression = GraphUtils.create2(g, expressionType, + sr.Expression_equation, currentText); + String arrayRange = g.getPossibleRelatedValue(expression, sr.Expression_arrayRange, Bindings.STRING); + if(arrayRange != null) + g.claimLiteral(newExpression, sr.Expression_arrayRange, arrayRange); + + final Resource variable = g.getPossibleObject(expression, l0.PartOf); + if(variable == null) + return; + Resource ownerList = g.getPossibleObject(variable, sr.Variable_expressionList); + if(ownerList == null) + return; + + ListUtils.replace(g, ownerList, expression, newExpression); + + g.deny(expression, l0.PartOf); + + g.claim(newExpression, l0.PartOf, variable); + + + VirtualGraphSupport support = g.getService(VirtualGraphSupport.class); + g.syncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(variable != null) { + if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression)) + graph.deny(variable, sr.IndependentVariable_activeExpression); + graph.claim(variable, sr.IndependentVariable_activeExpression, newExpression); + } + } + } + ); + } else { + // Claim value for the expression + g.claimLiteral(expression, sr.Expression_equation, currentText); + } + } + + }); + } + } + + @Override + public void updateData(Map data) { + if(this.expression != null && this.expression.getExpression() != null) + data.put("equation", this.expression.getExpression()); + } + + @Override + public void addKeyListener(KeyListener listener) { + this.expression.getSourceViewer().getTextWidget().addKeyListener(listener); + + } + + @Override + public void addModifyListener(ModifyListener listener) { + this.expression.getSourceViewer().getTextWidget().addModifyListener(listener); + + } + + @Override + public void addFocusListener(FocusListener listener) { + this.expression.getSourceViewer().getTextWidget().addFocusListener(listener); + } + + @Override + public void addVerifyKeyListener(VerifyKeyListener listener) { + this.expression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ColorManager.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ColorManager.java new file mode 100644 index 00000000..a25d2155 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ColorManager.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import gnu.trove.THashMap; + +import org.eclipse.jface.text.source.ISharedTextColors; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +public class ColorManager implements ISharedTextColors { + + THashMap map = new THashMap(); + + @Override + public void dispose() { + for(Color c : map.values()) + c.dispose(); + map.clear(); + } + + @Override + public Color getColor(RGB rgb) { + Color color = map.get(rgb); + if (color == null) { + color = new Color(Display.getCurrent(), rgb); + map.put(rgb, color); + } + return color; + + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/CompletionProcessor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/CompletionProcessor.java new file mode 100644 index 00000000..af2ea930 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/CompletionProcessor.java @@ -0,0 +1,273 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.ArrayList; +import java.util.Collections; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.CompletionProposal; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.properties.widgets.ShortcutTabWidget; +import org.simantics.sysdyn.ui.utils.ExpressionUtils; +import org.simantics.sysdyn.utils.Function; +import org.simantics.ui.SimanticsUI; + + +/** + * IContentAssistProcessor to determine which options (the functions and + * variables available) are shown for ContentAssistant; this assist of + * text field allows long variable names to be selected from a popup menu. + * @author Tuomas Miettinen + * + */ +public class CompletionProcessor implements IContentAssistProcessor { + + private final Table allowedVariables; + private ArrayList functions; + private ArrayList variables = null; + private ArrayList timeAndSelfVariables = null; + private final ExpressionWidgetInput input; + + private LocalResourceManager resourceManager; + + private final char[] allowedCharacters = { + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','å','ä','ö', + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Å','Ä','Ö', + '1','2','3','4','5','6','7','8','9','0','.','(',')'}; + + private final String allowedConnectedCharactersRegExp = "[\\Q({[:;,<=>+-*/^\\E]"; + + public CompletionProcessor(Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) { + this.allowedVariables = allowedVariables; + this.input = input; + this.functions = new ArrayList(); + + if (allowFunctions) { + if (input != null && CompletionProcessor.this.input.variable != null) { + // Get the respective model + Resource model = null; + try { + model = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return Variables.getModel(graph, CompletionProcessor.this.input.variable); + } + }); + + //User defined functions + functions.addAll(Function.getUserDefinedFunctions(model)); + // Shared functions + functions.addAll(Function.getSharedFunctions(model)); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + // Collect built in functions and sort all functions. + functions.addAll(Function.getAllBuiltInFunctions()); + Collections.sort(functions); + } + } + + /** + * Collect and sort all variables. + */ + private void findVariables() { + if (variables == null) { + variables = new ArrayList(); + timeAndSelfVariables = new ArrayList(); + if(allowedVariables != null && !allowedVariables.isDisposed()) { + TableItem[] connectedVariables = allowedVariables.getItems(); + for(TableItem ti : connectedVariables) { + // The status of the variable is determined using the color of its table item :( + if (ExpressionUtils.variableTimeAndSelfColor(resourceManager).equals(ti.getForeground())) { + this.timeAndSelfVariables.add(ti.getText()); + } else { + this.variables.add(ti.getText()); + } + + } + } + Collections.sort(variables); + Collections.sort(timeAndSelfVariables); + } + } + + /** + * Create CompletionProposals of the variables and add them to array. + * @param array result array of CompletionProposals + * @param token current token + * @param offset an offset within the document for which completions should be computed + */ + private void addVariables(ArrayList array, String token, int offset) { + Image imageVariable = resourceManager.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/variable.png"))); + Image imageVariableGray = resourceManager.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/variableGray.png"))); + + for (String variable : variables) { + if (token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) { + array.add(new CompletionProposal(variable, + offset - token.length(), + token.length(), + variable.length(), + imageVariable, + variable, + null, + null)); + } + } + for (String variable : timeAndSelfVariables) { + if (token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase())) { + array.add(new CompletionProposal(variable, + offset - token.length(), + token.length(), + variable.length(), + imageVariableGray, + variable, + null, + null)); + } + } + } + + /** + * Create CompletionProposals of the functions and add them to array. + * @param array result array of CompletionProposals + * @param token current token + * @param offset an offset within the document for which completions should be computed + */ + private void addFunctions(ArrayList array, String token, int offset) { + // Parameters don't have functions + if (functions == null) + return; + + // Create CompletionProposals out of Functions + for (Function function : functions) { + if (token.length() == 0 || function.getName().toUpperCase().startsWith(token.toUpperCase())) { + Image image = ShortcutTabWidget.getImage(resourceManager, function); + String parameterList = Function.inputListToString(function.getInputList()); + array.add(new CompletionProposal( + function.getName() + "(" + parameterList + ")", + offset - token.length(), + token.length(), + function.getName().length() + 1, + image, + function.getName() + "(" + parameterList + ")", + null, + function.getDescriptionHTML())); + } + } + } + + /** + * Collect all matching proposals + * @param token current token + * @param offset an offset within the document for which completions should be computed + * @return Array of matching proposals + */ + private ICompletionProposal[] collectProposals(String token, int offset) { + ArrayList resultArray = new ArrayList(); + + // Find variables and functions and create CompletionProposals out of them. + findVariables(); + addVariables(resultArray, token, offset); + addFunctions(resultArray, token, offset); + + ICompletionProposal[] result = new ICompletionProposal[resultArray.size()]; + for (int i = 0; i < result.length; ++i) { + result[i] = resultArray.get(i); + } + return result; + } + + @Override + public ICompletionProposal[] computeCompletionProposals( + ITextViewer viewer, int offset) { + String equation = viewer.getDocument().get(); + Control control = viewer.getTextWidget(); + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), control); + + if (equation.length() == 0 + || offset == 0 + || Character.isWhitespace(equation.charAt(offset - 1))) { + return collectProposals("", offset); + } + + equation = equation.substring(0, offset); + + // Split into tokens on whitespace characters + String[] tokens = equation.split("[\\s]"); + if (tokens.length == 0) { + return collectProposals("", offset); + } + String token = tokens[tokens.length - 1]; + + // If a '+', '-', etc. character is in the end, return all. + if (allowedConnectedCharactersRegExp.indexOf(token.charAt(token.length() - 1)) != -1) { + return collectProposals("", offset); + } + + // Split the last token on '+', '-', etc. characters + String tokensOfLastToken[] = token.split(allowedConnectedCharactersRegExp); + if (tokensOfLastToken.length == 0) { + return collectProposals("", offset); + } + token = tokensOfLastToken[tokensOfLastToken.length - 1]; + //System.out.println(token + "\noffset = " + offset); + + return collectProposals(token, offset); + } + + @Override + public IContextInformation[] computeContextInformation( + ITextViewer viewer, int offset) { + return null; + } + + @Override + public char[] getCompletionProposalAutoActivationCharacters() { + return allowedCharacters; + } + + @Override + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + @Override + public String getErrorMessage() { + return "Error in CompletionProcessor"; + } + + @Override + public IContextInformationValidator getContextInformationValidator() { + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ConstantExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ConstantExpression.java new file mode 100644 index 00000000..28a502d2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ConstantExpression.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +public class ConstantExpression extends BasicExpression { + + public ConstantExpression(ExpressionWidgetInput input) { + super(input); + try { + this.expressionType = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return SysdynResource.getInstance(graph).ConstantExpression; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @Override + public void createExpressionFields(Composite parent, Map data, Table allowedVariables) { + // Create the single field + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent); + String equation = data.get("equation") != null ? (String)data.get("equation") : ""; + + Label l = new Label(parent, SWT.NONE); + l.setText("="); + //System.out.println("ConstantExpression"); + expression = new ExpressionField(parent, SWT.BORDER, null, false, input); + expression.setExpression(equation); + GridDataFactory.fillDefaults().grab(true, true).applyTo(expression); + + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/DelayExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/DelayExpression.java new file mode 100644 index 00000000..3c1c1b1a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/DelayExpression.java @@ -0,0 +1,326 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Spinner; +import org.eclipse.swt.widgets.Table; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.VirtualGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +/** + * IExpression for displaying fields of DelayExpression + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class DelayExpression implements IExpression { + + private ExpressionField equation, delayTime, initialValue; + private ExpressionField lastSelectedText; + private Spinner order; + private final ExpressionWidgetInput input; + private Resource expression; + + /** + * Creates a new DelayExpression + * @param expression + */ + public DelayExpression(ExpressionWidgetInput input) { + this.input = input; + this.expression = input.expression; + } + + /** + * Displays the fields for delayExpression + */ + @Override + public void createExpressionFields(Composite parent, final Map data, Table allowedVariables) { + // Get possible existing data + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent); + String eq = data.get("equation") != null ? (String)data.get("equation") : ""; + String dt = data.get("delayTime") != null ? (String)data.get("delayTime") : ""; + String iv = data.get("initialValue") != null ? (String)data.get("initialValue") : ""; + int o = data.get("order") != null ? (Integer)data.get("order") : 3; + + Label l = new Label(parent, SWT.NONE); + l.setText("expression"); + + // Equation that is delayed + equation = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input); + equation.setExpression(eq); + GridDataFactory.fillDefaults().grab(true, true).applyTo(equation); + equation.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + lastSelectedText = equation; + } + }); + + l = new Label(parent, SWT.NONE); + l.setText("delay time"); + + // How much the equation is delayed + delayTime = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input); + delayTime.setExpression(dt); + GridDataFactory.fillDefaults().grab(true, true).applyTo(delayTime); + + delayTime.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + lastSelectedText = delayTime; + } + }); + + l = new Label(parent, SWT.NONE); + l.setText("initial value"); + + // What is the initial value of the delay (empty == same as equation) + initialValue = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input); + initialValue.setExpression(iv); + GridDataFactory.fillDefaults().grab(true, true).applyTo(initialValue); + + initialValue.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + lastSelectedText = initialValue; + } + }); + + + l = new Label(parent, SWT.NONE); + l.setText("order"); + + // The order of the delay (default == 3) + order = new Spinner(parent, SWT.BORDER); + order.setMinimum(1); + order.setSelection(o); + order.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + save(expression, data); + } + }); + GridDataFactory.fillDefaults().applyTo(order); + + lastSelectedText = equation; + } + + @Override + public void focus() { + lastSelectedText.setFocus(); + } + + @Override + public List getExpressionFields() { + return Arrays.asList(equation, delayTime, initialValue); + } + + @Override + public void readData(final Resource expression, Map data) { + class Auxiliary { + String equation, delayTime, initialValue; + Integer order; + } + + Auxiliary results = null; + + try { + results = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Auxiliary perform(ReadGraph graph) throws DatabaseException { + Auxiliary results = new Auxiliary(); + SysdynResource sr = SysdynResource.getInstance(graph); + if (expression != null && graph.isInstanceOf(expression, sr.DelayExpression)) { + results.equation = graph.getPossibleRelatedValue(expression, sr.DelayExpression_expression); + results.delayTime = graph.getPossibleRelatedValue(expression, sr.DelayExpression_delayTime); + results.initialValue = graph.getPossibleRelatedValue(expression, sr.DelayExpression_initialValue); + results.order = graph.getPossibleRelatedValue(expression, sr.DelayExpression_order); + } else { + results.equation = ""; + results.delayTime = ""; + results.order = 1; + } + return results; + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + if(results.equation != null) + data.put("equation", results.equation); + if(results.delayTime != null) + data.put("delayTime", results.delayTime); + if(results.initialValue != null) + data.put("initialValue", results.initialValue); + if(results.order != null) + data.put("order", results.order); + } + + @Override + public void replaceSelection(String var) { + if(lastSelectedText != null) { + IDocument doc = lastSelectedText.getDocument(); + try { + Point selection = lastSelectedText.getSelection(); + doc.replace(selection.x, selection.y, var); + lastSelectedText.setSelection(selection.x + var.length()); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + } + + @Override + public void save(Resource expr, Map data) { + this.expression = expr; + final String currentEquation = this.equation.getExpression(); + final String currentDelayTime = this.delayTime.getExpression(); + final String currentInitialValue = this.initialValue.getExpression(); + final Integer currentOrder = this.order.getSelection(); + + String oldEquation = (String)data.get("equation"); + String oldDelayTime = (String)data.get("delayTime"); + String oldInitialValue = (String)data.get("initialValue"); + Integer oldOrder = (Integer)data.get("order"); + + if((oldEquation == null || oldDelayTime == null || oldOrder == null || oldInitialValue == null) || + !oldEquation.equals(currentEquation) || !oldDelayTime.equals(currentDelayTime) || + !oldOrder.equals(currentOrder) || !oldInitialValue.equals(currentInitialValue)) { + // old value was null or value has changed -> Do save + + data.putAll(data); + data.put("equation", currentEquation); + data.put("delayTime", currentDelayTime); + data.put("initialValue", currentInitialValue); + data.put("order", currentOrder); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph g) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + + if(!g.isInstanceOf(expression, sr.DelayExpression)) { + // Create a new DelayExpression, if the old expression was something else + final Resource newExpression = GraphUtils.create2(g, sr.DelayExpression); + String arrayRange = g.getPossibleRelatedValue(expression, sr.Expression_arrayRange, Bindings.STRING); + if(arrayRange != null) + g.claimLiteral(newExpression, sr.Expression_arrayRange, arrayRange); + + final Resource variable = g.getPossibleObject(expression, l0.PartOf); + Resource ownerList = g.getPossibleObject(variable, sr.Variable_expressionList); + ListUtils.replace(g, ownerList, expression, newExpression); + g.deny(expression, l0.PartOf); + g.claim(newExpression, l0.PartOf, variable); + + VirtualGraph runtime = g.getService(VirtualGraph.class); + g.syncRequest(new WriteRequest(runtime) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression)) + graph.deny(variable, sr.IndependentVariable_activeExpression); + graph.claim(variable, sr.IndependentVariable_activeExpression, newExpression); + } + } + ); + expression = newExpression; + } + + // Claim values + g.claimLiteral(expression, sr.DelayExpression_expression, currentEquation); + g.claimLiteral(expression, sr.DelayExpression_delayTime, currentDelayTime); + g.claimLiteral(expression, sr.DelayExpression_initialValue, currentInitialValue); + g.claimLiteral(expression, sr.DelayExpression_order, currentOrder); + } + }); + } + + } + + @Override + public void updateData(Map data) { + if(this.equation != null && this.equation.getExpression() != null) + data.put("equation", this.equation.getExpression()); + if(this.delayTime != null && this.delayTime.getExpression() != null) + data.put("delayTime", this.delayTime.getExpression()); + if(this.initialValue != null && this.initialValue.getExpression() != null) + data.put("initialValue", this.initialValue.getExpression()); + if(this.order != null) + data.put("order", this.order.getSelection()); + } + + @Override + public void addKeyListener(KeyListener listener) { + this.equation.getSourceViewer().getTextWidget().addKeyListener(listener); + this.delayTime.getSourceViewer().getTextWidget().addKeyListener(listener); + this.initialValue.getSourceViewer().getTextWidget().addKeyListener(listener); + } + + @Override + public void addModifyListener(ModifyListener listener) { + this.equation.getSourceViewer().getTextWidget().addModifyListener(listener); + this.delayTime.getSourceViewer().getTextWidget().addModifyListener(listener); + this.initialValue.getSourceViewer().getTextWidget().addModifyListener(listener); + } + + @Override + public void addFocusListener(FocusListener listener) { + this.equation.getSourceViewer().getTextWidget().addFocusListener(listener); + this.delayTime.getSourceViewer().getTextWidget().addFocusListener(listener); + this.initialValue.getSourceViewer().getTextWidget().addFocusListener(listener); + } + + @Override + public void addVerifyKeyListener(VerifyKeyListener listener) { + this.equation.getSourceViewer().getTextWidget().addVerifyKeyListener(listener); + this.delayTime.getSourceViewer().getTextWidget().addVerifyKeyListener(listener); + this.initialValue.getSourceViewer().getTextWidget().addVerifyKeyListener(listener); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/EmptyExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/EmptyExpression.java new file mode 100644 index 00000000..f36fac96 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/EmptyExpression.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.List; +import java.util.Map; + +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.simantics.db.Resource; + +public class EmptyExpression implements IExpression { + + @Override + public void createExpressionFields(Composite parent, Map data, Table allowedVariables) { + // TODO Auto-generated method stub + + } + + @Override + public void focus() { + // TODO Auto-generated method stub + + } + + @Override + public List getExpressionFields() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void readData(Resource variable, Map data) { + // TODO Auto-generated method stub + + } + + @Override + public void replaceSelection(String var) { + // TODO Auto-generated method stub + + } + + @Override + public void save(Resource variable, Map data) { + // TODO Auto-generated method stub + + } + + @Override + public void updateData(Map data) { + // TODO Auto-generated method stub + + } + + @Override + public void addKeyListener(KeyListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void addModifyListener(ModifyListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void addFocusListener(FocusListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void addVerifyKeyListener(VerifyKeyListener listener) { + // TODO Auto-generated method stub + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionComposite.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionComposite.java new file mode 100644 index 00000000..6459daba --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionComposite.java @@ -0,0 +1,27 @@ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import org.eclipse.swt.widgets.Composite; +import org.simantics.sysdyn.ui.properties.widgets.ExpressionWidget; + +/** + * A composite class for access to save equation in expressionWidget. + * @author Tuomas Miettinen + * + */ +public class ExpressionComposite extends Composite { + + private ExpressionWidget expressionWidget; + + public ExpressionComposite(Composite parent, int style) { + super(parent, style); + + } + + public void saveExpression() { + expressionWidget.save(); + } + + public void setExpressionWidget(ExpressionWidget expressionWidget) { + this.expressionWidget = expressionWidget; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionField.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionField.java new file mode 100644 index 00000000..5b5b3aff --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionField.java @@ -0,0 +1,300 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.List; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.PaintManager; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.jface.text.source.AnnotationPainter; +import org.eclipse.jface.text.source.DefaultCharacterPairMatcher; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.MatchingCharacterPainter; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess; +import org.simantics.sysdyn.ui.utils.SyntaxError; + +/** + * Field for displaying a part of an expression. Expression field uses SourceViewer + * to display annotations and other visual elements just like any other + * source viewer in eclipse. + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ExpressionField extends Composite { + + protected SourceViewer _sourceViewer; + protected IDocument _document; + protected AnnotationModel _annotationModel; + + public static final String MISSING_LINK = "MissingLink"; + public static final String NO_SUCH_VARIABLE = "NoSuchVariable"; + public static final String SYNTAX_ERROR = "SyntaxError"; + public static final String SYNTAX_WARNING = "SyntaxWarning"; + + String oldExpression; + + IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess(); + + ExpressionFieldConfiguration expressionFieldConfiguration; + + private final LocalResourceManager resourceManager; + private final RGB warningRGB = new RGB(255,215,0); + private final RGB errorRGB = new RGB(255,0,0); + + /** + * Create a new expression field + * @param parent + * @param style + */ + public ExpressionField(Composite parent, int style, Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) { + super(parent, style); + + // Create a ResourceManager to dispose images when the widget is disposed. + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), this); + + GridLayoutFactory.fillDefaults().applyTo(this); + + int styles = SWT.V_SCROLL + | SWT.MULTI + | SWT.FULL_SELECTION + | SWT.WRAP; + + _document = new Document(); + _document.set(""); + + _annotationModel = new AnnotationModel(); + _annotationModel.connect(_document); + + _sourceViewer = new SourceViewer(this, + + null, + null, + true, + styles); + + // Configuration for color management + expressionFieldConfiguration = new ExpressionFieldConfiguration( + new LocalResourceManager(JFaceResources.getResources(), _sourceViewer.getControl()), + allowedVariables, allowFunctions, input); + _sourceViewer.configure(expressionFieldConfiguration); + AnnotationPainter painter = new AnnotationPainter(_sourceViewer, annotationAccess); + _sourceViewer.addPainter(painter); + + // Annotation types + Color warningColor = resourceManager.createColor(warningRGB); + Color errorColor = resourceManager.createColor(errorRGB); + painter.addAnnotationType(MISSING_LINK); + painter.setAnnotationTypeColor(MISSING_LINK, warningColor); + painter.addAnnotationType(NO_SUCH_VARIABLE); + painter.setAnnotationTypeColor(NO_SUCH_VARIABLE, errorColor); + painter.addAnnotationType(SYNTAX_ERROR); + painter.setAnnotationTypeColor(SYNTAX_ERROR, errorColor); + painter.addAnnotationType(SYNTAX_WARNING); + painter.setAnnotationTypeColor(SYNTAX_WARNING, warningColor); + + _sourceViewer.setDocument(_document, _annotationModel); + + GridDataFactory.fillDefaults().grab(true, true).applyTo(_sourceViewer.getControl()); + + // Parenthesis matching + PaintManager paintManager = new PaintManager(_sourceViewer); + MatchingCharacterPainter matchingCharacterPainter = new MatchingCharacterPainter(_sourceViewer, + new DefaultCharacterPairMatcher( new char[] {'(', ')', '{', '}', '[', ']'} )); + matchingCharacterPainter.setColor(resourceManager.createColor(new RGB(160, 160, 160))); + paintManager.addPainter(matchingCharacterPainter); + + + // Listener for canceling editing. ESC -> revert back to original text + _sourceViewer.getTextWidget().addKeyListener(new KeyListener() { + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + // Check if the expression field has an active completion assistant + if (!isAssistSessionActive()) { + if(e.keyCode == SWT.ESC && getExpression() != null) { + ((StyledText)e.widget).setText(oldExpression); + ((StyledText)e.widget).setSelection(getExpression().length()); + } + } + } + }); + + /* Focus listener saving and restoring selections + * When focus is lost, current selection is saved, but the selection is removed. + * When focus is gained back, the selection is restored + */ + _sourceViewer.getTextWidget().addFocusListener(new FocusListener() { + + Point selection = null; + @Override + public void focusLost(FocusEvent e) { + selection = ((StyledText)e.widget).getSelection(); + ((StyledText)e.widget).setSelection(0); + } + + @Override + public void focusGained(FocusEvent e) { + if(selection != null) + ((StyledText)e.widget).setSelection(selection); + } + }); + + _sourceViewer.appendVerifyKeyListener(new VerifyKeyListener() { + @Override + public void verifyKey(VerifyEvent event) { + // Check for Ctrl+Spacebar + if (event.stateMask == SWT.CTRL && event.character == ' ') { + // Check if source viewer is able to perform operation + if (_sourceViewer.canDoOperation(SourceViewer.CONTENTASSIST_PROPOSALS)) { + // Perform operation + _sourceViewer.doOperation(SourceViewer.CONTENTASSIST_PROPOSALS); + } + // Veto this key press to avoid further processing + event.doit = false; + } + } + + }); + + } + + /** + * Returns the {@link SourceViewer} of this ExpressionField + * @return Returns the {@link SourceViewer} of this ExpressionField + */ + public SourceViewer getSourceViewer() { + return this._sourceViewer; + } + + public boolean isAssistSessionActive() { + return expressionFieldConfiguration.isAssistSessionActive(); + } + + /** + * Sets missing link annotations to given positions + * @param positions Positions for missing link annotations + */ + public void setMissingLinkAnnotations(List positions){ + for(Position p : positions) { + Annotation annotation = new Annotation(false); + annotation.setType(MISSING_LINK); + annotation.setText("No link to this variable"); + _annotationModel.addAnnotation(annotation, p); + } + } + + /** + * Sets no such variable annotations to given positions + * @param positions Positions for no such variable annotations + */ + public void setNoSuchVariableAnnotations(List positions){ + for(Position p : positions) { + Annotation annotation = new Annotation(false); + annotation.setType(NO_SUCH_VARIABLE); + annotation.setText("No such variable in model"); + _annotationModel.addAnnotation(annotation, p); + } + } + + + /** + * Sets a syntax error annoattion to the expression field + * @param syntaxError + */ + public void setSyntaxError(SyntaxError syntaxError) { + Annotation annotation = new Annotation(false); + annotation.setType(syntaxError.getType()); + annotation.setText(syntaxError.getMessage()); + Position p = new Position(syntaxError.getStart(_document), syntaxError.getOffset(_document)); + _annotationModel.addAnnotation(annotation, p); + } + + /** + * Resets all annotations + */ + public void resetAnnotations() { + _annotationModel.removeAllAnnotations(); + } + + /** + * Sets an expression to this expression field + * @param expression + */ + public void setExpression(String expression) { + _document.set(expression); + this.oldExpression = expression; + } + + /** + * Returns the expression of this expression field + * @return + */ + public String getExpression() { + return this._document.get(); + } + + /** + * Returns the current selection + * @return current selection + */ + public Point getSelection() { + return _sourceViewer.getSelectedRange(); + } + + /** + * Set selection for this expression field. The length of the selection is 0 + * @param selection Selection location + */ + public void setSelection(int selection) { + this._sourceViewer.setSelectedRange(selection, 0); + } + + public IDocument getDocument() { + return _document; + } + + /** + * Focus to this expression field + */ + public void focus() { + this._sourceViewer.getTextWidget().forceFocus(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionFieldConfiguration.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionFieldConfiguration.java new file mode 100644 index 00000000..205d41db --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionFieldConfiguration.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import org.eclipse.jface.internal.text.html.HTMLTextPresenter; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.DefaultTextHover; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.TextAttribute; +import org.eclipse.jface.text.contentassist.ContentAssistEvent; +import org.eclipse.jface.text.contentassist.ContentAssistant; +import org.eclipse.jface.text.contentassist.ICompletionListener; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; +import org.eclipse.jface.text.rules.DefaultDamagerRepairer; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.ITokenScanner; +import org.eclipse.jface.text.rules.IWordDetector; +import org.eclipse.jface.text.rules.MultiLineRule; +import org.eclipse.jface.text.rules.RuleBasedScanner; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WordRule; +import org.eclipse.jface.text.source.DefaultAnnotationHover; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.simantics.sysdyn.ui.modelica.ModelicaSourceViewerConfiguration; + +@SuppressWarnings("restriction") +public class ExpressionFieldConfiguration extends SourceViewerConfiguration { + + private final long WAIT_BEFORE_STATUS_CHANGE = 100; + + Table allowedVariables; + boolean allowFunctions; + boolean assistSessionActive; + CompletionProcessor completionProcessor; + ResourceManager resourceManager; + + private final ExpressionWidgetInput input; + + public ExpressionFieldConfiguration(ResourceManager resourceManager, Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) { + super(); + this.resourceManager = resourceManager; + this.allowedVariables = allowedVariables; + this.allowFunctions = allowFunctions; + this.assistSessionActive = false; + this.completionProcessor = null; + this.input = input; + } + + public boolean isAssistSessionActive() { + return assistSessionActive; + } + + @Override + public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) { + return new String[] { + IDocument.DEFAULT_CONTENT_TYPE + }; + } + + @Override + public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { + PresentationReconciler reconciler = new PresentationReconciler(); + + DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getTokenScanner()); + + reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); + reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); + + return reconciler; + } + + + ITokenScanner getTokenScanner() { + RuleBasedScanner scanner = new RuleBasedScanner(); + + final Token reserved = new Token( + new TextAttribute( + resourceManager.createColor(new RGB(127, 0, 85)), + null, + SWT.BOLD + )); + final Token defaultToken = new Token(new TextAttribute(resourceManager.createColor(new RGB(0, 0, 0)))); + + final Token comment = new Token(new TextAttribute(resourceManager.createColor(new RGB(63, 127, 95)))); + + WordRule reservedWord = new WordRule(new IWordDetector() { + @Override + public boolean isWordStart(char c) { + return Character.isLetter(c); + } + + @Override + public boolean isWordPart(char c) { + return Character.isLetter(c); + } + }, defaultToken); + + + for(String s : ModelicaSourceViewerConfiguration.keywords) { + reservedWord.addWord(s, reserved); + } + + IRule[] rules = new IRule[] { + reservedWord, + new MultiLineRule("/*", "*/", comment), + new MultiLineRule("\"", "\"", comment) + }; + scanner.setRules(rules); + + return scanner; + } + + @Override + public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { + return new DefaultTextHover(sourceViewer); + } + + @Override + public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) { + return new DefaultAnnotationHover(); + } + + @Override + public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { + ContentAssistant assistant = new ContentAssistant(); + completionProcessor = new CompletionProcessor(allowedVariables, allowFunctions, input); + assistant.setContentAssistProcessor(completionProcessor, IDocument.DEFAULT_CONTENT_TYPE); + assistant.enableAutoActivation(true); + assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer)); + assistant.enableAutoInsert(true); + assistant.setAutoActivationDelay(0); + assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY); + assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE); + assistant.addCompletionListener(new CompletionListener()); + return assistant; + } + + @Override + public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) { + return new IInformationControlCreator() { + @Override + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent,new HTMLTextPresenter(false)); + } + }; + } + + private class CompletionListener implements ICompletionListener { + + @Override + public void assistSessionStarted(ContentAssistEvent event) { + if (event.processor.equals(completionProcessor)) { + assistSessionActive = true; + } + } + + @Override + public void assistSessionEnded(ContentAssistEvent event) { + if (event.processor.equals(completionProcessor)) { + Thread waitBeforeStateChange = new Thread() { + @Override + public void run() { + try { + sleep(WAIT_BEFORE_STATUS_CHANGE); + assistSessionActive = false; + } catch (InterruptedException e) { + assistSessionActive = false; + } + } + }; + waitBeforeStateChange.start(); + } + } + + @Override + public void selectionChanged(ICompletionProposal proposal, + boolean smartToggle) { + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionWidgetInput.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionWidgetInput.java new file mode 100644 index 00000000..9f6481cc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionWidgetInput.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import org.simantics.db.Resource; +import org.simantics.db.layer0.variable.Variable; + +/** + * Inputs for expression widgets contain both Variable and the expression resource + * @author Teemu Lempinen + * + */ +public class ExpressionWidgetInput { + public Variable variable; + public Resource expression; + + public ExpressionWidgetInput(Variable variable, Resource expression) { + this.variable = variable; + this.expression = expression; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/IExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/IExpression.java new file mode 100644 index 00000000..c2c6eff0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/IExpression.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.List; +import java.util.Map; + +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.simantics.db.Resource; + +public interface IExpression { + + public void createExpressionFields(Composite parent, Map data, Table allowedVaribles); + + public void readData(final Resource expression, Map data); + + public void save(final Resource expression, Map data); + + public void focus(); + + public void replaceSelection(String var); + + public void updateData(Map data); + + public List getExpressionFields(); + + public void addModifyListener(ModifyListener listener); + + public void addKeyListener(KeyListener listener); + + public void addVerifyKeyListener(VerifyKeyListener listener); + + public void addFocusListener(FocusListener listener); +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupChartPanel.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupChartPanel.java new file mode 100644 index 00000000..44db3f03 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupChartPanel.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.awt.Point; +import java.awt.event.MouseEvent; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.jfree.chart.ChartPanel; +import org.jfree.chart.ChartRenderingInfo; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.entity.ChartEntity; +import org.jfree.chart.entity.PlotEntity; +import org.jfree.chart.entity.XYItemEntity; +import org.jfree.chart.plot.XYPlot; +import org.jfree.data.general.SeriesChangeListener; +import org.jfree.data.xy.XYDataset; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; + +@SuppressWarnings("serial") +public class LookupChartPanel extends ChartPanel { + + private XYItemEntity dragPrevEntity; + private boolean drawing; + private XYSeries series; + private JFreeChart chart; + private SeriesChangeListener changeListener; + + public LookupChartPanel(JFreeChart chart) { + super(chart); + this.chart = chart; + XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset(); + series = collection.getSeries(0); + } + + public void mouseDragged(MouseEvent e) + { + if(dragPrevEntity != null) { + + int item = dragPrevEntity.getItem(); + XYPlot plot = (XYPlot)chart.getPlot(); + ValueAxis rangeAxis = plot.getRangeAxis(); + ValueAxis domainAxis = plot.getDomainAxis(); + Point2D location = getLocationOnChart(getMouseLocation(e)); + Number prevX = item == 0 ? null : series.getX(item - 1); + Number nextX = item == series.getItemCount() - 1 ? null : series.getX(item + 1); + + + if(series.indexOf(location.getX()) >= 0 && series.indexOf(location.getX()) != item) + return; + else if (prevX != null && location.getX() < prevX.doubleValue()) + location.setLocation(series.getX(item).doubleValue(), location.getY()); + else if (nextX != null && location.getX() > nextX.doubleValue()) + location.setLocation(series.getX(item).doubleValue(), location.getY()); + else if (location.getX() > domainAxis.getUpperBound()) + location.setLocation(domainAxis.getUpperBound(), location.getY()); + else if (location.getX() < domainAxis.getLowerBound()) + location.setLocation(domainAxis.getLowerBound(), location.getY()); + + if (location.getY() > rangeAxis.getUpperBound()) + location.setLocation(location.getX(), rangeAxis.getUpperBound()); + else if (location.getY() < rangeAxis.getLowerBound()) + location.setLocation(location.getX(), rangeAxis.getLowerBound()); + + removeItemFromSeries(dragPrevEntity.getItem()); + addLocationToSeries(location); + } else { + ChartEntity currEntity = this.getEntityForPoint(e.getX(),e.getY()); + if(!drawing && currEntity instanceof XYItemEntity) { + dragPrevEntity = ((XYItemEntity)currEntity); + } else if (currEntity instanceof PlotEntity){ + drawing = true; + Point2D locationOnChart = getLocationOnChart(getMouseLocation(e)); + int item = series.indexOf(locationOnChart.getX()); + if (item >= 0) { + Point2D location = new Point2D.Double(series.getX(item).doubleValue(), series.getY(item).doubleValue()); + Point2D javaLocation = getLocationOnJava2D(location); + removeItemFromSeries(item); + addLocationToSeries(getLocationOnChart(new Point2D.Double(javaLocation.getX(), e.getY()))); + } + } + } + + } + + public void mouseReleased(MouseEvent e) { + if(isDragging()) { + dragPrevEntity = null; + if(changeListener != null) + changeListener.seriesChanged(null); + } + drawing = false; + + } + + public void mouseClicked(MouseEvent e) + { + if(e.getButton() == MouseEvent.BUTTON1) { + addLocationToSeries(getLocationOnChart(getMouseLocation(e))); + } else if (e.getButton() == MouseEvent.BUTTON3) { + ChartEntity entity = this.getEntityForPoint(e.getX(),e.getY()); + if(entity instanceof XYItemEntity) { + XYItemEntity xyentity = ((XYItemEntity)entity); + removeItemFromSeries(xyentity.getItem()); + } + } + } + + private Point2D getLocationOnChart(Point2D coordinates) { + XYPlot plot = (XYPlot)chart.getPlot(); + ChartRenderingInfo info = getChartRenderingInfo(); + Rectangle2D dataArea = info.getPlotInfo().getDataArea(); + double chartX = plot.getDomainAxis().java2DToValue(coordinates.getX(), dataArea, + plot.getDomainAxisEdge()); + double chartY = plot.getRangeAxis().java2DToValue(coordinates.getY(), dataArea, + plot.getRangeAxisEdge()); + return new Point2D.Double(chartX, chartY); + } + + private Point2D getLocationOnJava2D(Point2D location) { + XYPlot plot = (XYPlot)chart.getPlot(); + ChartRenderingInfo info = getChartRenderingInfo(); + Rectangle2D dataArea = info.getPlotInfo().getDataArea(); + double javaX = plot.getDomainAxis().valueToJava2D(location.getX(), dataArea, + plot.getDomainAxisEdge()); + double javaY = plot.getRangeAxis().valueToJava2D(location.getY(), dataArea, + plot.getRangeAxisEdge()); + return new Point2D.Double(javaX, javaY); + } + + public void addLocationToSeries(Point2D location) { + if(series.indexOf(location.getX()) < 0) { + series.add(location.getX(), location.getY()); + } + } + + public void removeItemFromSeries(int item){ + series.remove(item); + } + + public void resetChart(XYDataset dataset) { + XYPlot plot = (XYPlot)chart.getPlot(); + plot.setDataset(dataset); + XYSeriesCollection collection = (XYSeriesCollection) plot.getDataset(); + series = collection.getSeries(0); + } + + private Point2D getMouseLocation(MouseEvent e) { + int mouseX = e.getX(); + int mouseY = e.getY(); + Point2D p = translateScreenToJava2D( + new Point(mouseX, mouseY)); + return p; + } + + public void addSeriesChangeListener(SeriesChangeListener listener) { + this.changeListener = listener; + this.series.addChangeListener(changeListener); + } + + public boolean isDragging() { + return dragPrevEntity != null; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupExpression.java new file mode 100644 index 00000000..cf0f2304 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupExpression.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.List; +import java.util.Map; + +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.simantics.db.Resource; + +public class LookupExpression implements IExpression { + + @Override + public void focus() { + // TODO Auto-generated method stub + + } + + @Override + public List getExpressionFields() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void readData(final Resource variable, Map data) { + // TODO Auto-generated method stub + + } + + @Override + public void replaceSelection(String var) { + // TODO Auto-generated method stub + + } + + @Override + public void save(final Resource variable, Map data) { + // TODO Auto-generated method stub + + } + + @Override + public void updateData(Map data) { + // TODO Auto-generated method stub + + } + + @Override + public void createExpressionFields(Composite parent, Map data, Table allowedVariables) { + // TODO Auto-generated method stub + + } + + @Override + public void addKeyListener(KeyListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void addModifyListener(ModifyListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void addFocusListener(FocusListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void addVerifyKeyListener(VerifyKeyListener listener) { + // TODO Auto-generated method stub + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupInputOutputTable.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupInputOutputTable.java new file mode 100644 index 00000000..e6eb4775 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupInputOutputTable.java @@ -0,0 +1,279 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; + +public class LookupInputOutputTable extends Composite { + + public static final String INPUT = "Input"; + public static final String OUTPUT = "Output"; + public static final String[] PROPS = { INPUT, OUTPUT }; + + private Table table; + private TableViewer tableViewer; + private List tableRows; + + public LookupInputOutputTable(Composite parent, int style) { + super(parent, style); + + GridLayoutFactory.fillDefaults().applyTo(this); + GridDataFactory.fillDefaults().grab(true, true).applyTo(this); + table = new Table(this, SWT.BORDER|SWT.SINGLE|SWT.FULL_SELECTION); + GridDataFactory.fillDefaults().grab(true, true).applyTo(table); + table.setHeaderVisible (true); + table.setLinesVisible(true); + table.getVerticalBar().setVisible(true); + TableColumn column1 = new TableColumn (table, SWT.LEFT); + column1.setText (INPUT); + column1.setWidth (85); + + TableColumn column2 = new TableColumn (table, SWT.LEFT); + column2.setText (OUTPUT); + column2.setWidth (85); + + // Create the viewer and connect it to the view + tableViewer = new TableViewer (table); + + tableViewer.setContentProvider (new ArrayContentProvider()); + tableViewer.setLabelProvider (new InputOutputLabelProvider()); + tableViewer.setCellModifier(new InputOutputCellModifier()); + + tableRows = new ArrayList(); + tableViewer.setInput(tableRows); + + CellEditor[] editors = new CellEditor[2]; + editors[0] = new TextCellEditor(table); + editors[1] = new TextCellEditor(table); + tableViewer.setCellEditors(editors); + tableViewer.setColumnProperties(PROPS); + + } + + private class InputOutputLabelProvider extends LabelProvider implements ITableLabelProvider { + public Image getColumnImage (Object element, int columnIndex) { + return null; + } + public String getColumnText (Object element, int columnIndex) { + if(element instanceof InputOutput) { + InputOutput io = (InputOutput)element; + switch (columnIndex) { + case 0: return (String)io.getInput(String.class); + case 1: return (String)io.getOutput(String.class); + } + } + return ""; + } + } + + public void addLocation(Point2D location) { + tableRows.add(new InputOutput(location.getX(), location.getY())); + tableViewer.getTable().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + refresh(); + } + }); + + } + + public void removeItem(int index) { + tableRows.remove(index); + tableViewer.getTable().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + refresh(); + } + }); + } + + public void clearTable() { + this.tableRows.clear(); + tableViewer.getTable().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + refresh(); + } + }); + } + + + public class InputOutput { + private double input, output; + + public InputOutput(double input, double output) { + this.input = input; + this.output = output; + } + + /** + * + * @param clazz String.class or Double.class + * @return input as string or double or null if asked for something else + */ + @SuppressWarnings("rawtypes") + public Object getInput(Class clazz) { + if(clazz == String.class) { + return "" + input; + } else if (clazz == Double.class) { + return input; + } + return null; + } + + public Double setInput(String input) { + try { + this.input = Double.parseDouble(input); + return this.input; + } catch (NumberFormatException e) { + return null; + } + } + + public void setInput(double input) { + this.input = input; + } + + /** + * + * @param clazz String.class or Double.class + * @return output as string or double or null if asked for something else + */ + @SuppressWarnings("rawtypes") + public Object getOutput(Class clazz) { + if(clazz == String.class) { + return "" + output; + } else if (clazz == Double.class) { + return output; + } + return null; + } + + public void setOutput(String output) { + try { + this.output = Double.parseDouble(output); + } catch (NumberFormatException e) { + + } + } + + public void setOutput(double output) { + this.output = output; + } + + } + + public class InputOutputComparator extends ViewerComparator implements Comparator{ + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + if ((e1 instanceof InputOutput) && + (e2 instanceof InputOutput)) { + return compare((InputOutput)e1, (InputOutput)e2); + } else { + return 0; + } + } + + @Override + public int compare(InputOutput e1, InputOutput e2) { + InputOutput io1 = (InputOutput)e1; + InputOutput io2 = (InputOutput)e2; + Double d1 = (Double)io1.getInput((Double.class)); + Double d2 = (Double)io2.getInput((Double.class)); + return d1.compareTo(d2); + } + } + + public TableViewer getTableViewer() { + return this.tableViewer; + } + + public void refresh() { + if(!tableViewer.getTable().isDisposed()) { + tableViewer.setComparator(new InputOutputComparator()); + tableViewer.refresh(); + } + } + + class InputOutputCellModifier implements ICellModifier { + + public InputOutputCellModifier() {} + + public boolean canModify(Object element, String property) { + return true; + } + + public Object getValue(Object element, String property) { + InputOutput io = (InputOutput)element; + if (LookupInputOutputTable.INPUT.equals(property)) + return (String)io.getInput(String.class); + else if (LookupInputOutputTable.OUTPUT.equals(property)) + return (String)io.getOutput(String.class); + else + return null; + } + + public void modify(Object element, String property, Object value) { + if (element instanceof Item) element = ((Item) element).getData(); + + InputOutput io = (InputOutput)element; + + if (LookupInputOutputTable.INPUT.equals(property)) { + io.setInput((String)value); + } else if (LookupInputOutputTable.OUTPUT.equals(property)) { + io.setOutput((String)value); + } + tableModified(); + refresh(); + } + } + + private void tableModified() { + tableViewer.getTable().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + for (Listener listener : getListeners(SWT.Modify)) { + Event e = new Event(); + listener.handleEvent(e); + } + } + }); + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java new file mode 100644 index 00000000..cfaf2a6d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + + +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteResultRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.request.Read; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynGameExperiment; +import org.simantics.sysdyn.ui.utils.ExpressionUtils; +import org.simantics.ui.SimanticsUI; + +public class ParameterExpression extends BasicExpression { + + Variable variable; + + public ParameterExpression(ExpressionWidgetInput input) { + super(input); + try { + this.expressionType = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return SysdynResource.getInstance(graph).ParameterExpression; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + this.variable = input.variable; + } + + + @Override + public void createExpressionFields(Composite parent, Map data, Table allowedVariables) { + // Create the single field + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent); + String equation = data.get("equation") != null ? (String)data.get("equation") : ""; + + Label l = new Label(parent, SWT.NONE); + l.setText("="); + + expression = new ExpressionField(parent, SWT.BORDER, null, false, input); + expression.setExpression(equation); + GridDataFactory.fillDefaults().grab(true, true).applyTo(expression); + + } + + @Override + public void readData(final Resource expression, Map data) { + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynGameExperiment)) { + super.readData(expression, data); + } else { + Double value; + ExperimentState state = ((SysdynGameExperiment)experiment).getSysdynExperimentState(); + if(ExperimentState.RUNNING.equals(state) || ExperimentState.STOPPED.equals(state)) { + try { + value = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Double perform(ReadGraph graph) throws DatabaseException { + try { + Variable valuesVariable = variable.browsePossible(graph, "#value#"); + double[] res = valuesVariable.getValue(graph); + if(res != null && res.length == 1) + return res[0]; + else + return null; + } catch (DatabaseException e) { + throw new DatabaseException(e.getMessage()); + } + } + }); + if(value != null) + data.put("equation", value.toString()); + } catch (DatabaseException e) {} + } + super.readData(expression, data); + + } + } + + @Override + public void save(final Resource expression, Map data) { + + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment != null && experiment instanceof SysdynGameExperiment) { + final String currentText = this.expression.getExpression(); + final String oldEquation = (String)data.get("equation"); + if(oldEquation == null || + (currentText != null && oldEquation != null && !currentText.equals(oldEquation) && expressionType != null)) { + if(ExpressionUtils.isParameter(currentText)) { + Boolean savedIntoFMU = false; + + ExperimentState state = ((SysdynGameExperiment)experiment).getSysdynExperimentState(); + // Set value to control only if the simulation is running or stopped, not before initialization + if(ExperimentState.RUNNING.equals(state) || ExperimentState.STOPPED.equals(state)) { + try { + savedIntoFMU = SimanticsUI.getSession().syncRequest(new WriteResultRequest() { + + @Override + public Boolean perform(WriteGraph graph) + throws DatabaseException { + try { + Variable valuesVariable = variable.browsePossible(graph, "#value#"); + if(valuesVariable == null) + return false; + valuesVariable.setValue(graph, new double[] {Double.parseDouble(currentText)}); + return true; + } catch (Exception e) { + return false; + } + } + + }); + } catch (DatabaseException e) {} + } + + if(savedIntoFMU) { + data.put("equation", currentText); + return; + } + } + } + } + + // If setting a parameter value was not succesful, use the normal save-method + super.save(expression, data); + } + + public ParameterExpression() { + super(null); + try { + this.expressionType = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return SysdynResource.getInstance(graph).ParameterExpression; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java new file mode 100644 index 00000000..53e51b91 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java @@ -0,0 +1,345 @@ +/******************************************************************************* + * Copyright (c) 2007, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Table; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.Stock; +import org.simantics.sysdyn.representation.Valve; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; + +public class StockExpression implements IExpression { + + private final ExpressionWidgetInput input; + private ExpressionField integralExpression, initialExpression; + private ExpressionField lastSelectedText; + + public StockExpression(ExpressionWidgetInput input) { + this.input = input; + } + + @Override + public void createExpressionFields(Composite parent, Map data, Table allowedVariables) { + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent); + String initialEquation = data.get("initialEquation") != null ? (String)data.get("initialEquation") : ""; + String integralEquation = data.get("integral") != null ? (String)data.get("integral") : getDefaultIntegral(input.expression); + + + Label label = new Label(parent, SWT.NONE); + label.setText("Integral"); + + Composite integralComposite = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(integralComposite); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(integralComposite); + + integralExpression = new ExpressionField(integralComposite, SWT.BORDER, allowedVariables, true, input); + integralExpression.setExpression(integralEquation); + GridDataFactory.fillDefaults().grab(true, true).applyTo(integralExpression); + integralExpression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + lastSelectedText = integralExpression; + } + }); + + Button defaultButton = new Button(integralComposite, SWT.PUSH); + defaultButton.setText("Use default"); + defaultButton.addListener(SWT.Selection, new Listener() { + + @Override + public void handleEvent(Event event) { + switch (event.type) { + case SWT.Selection: + StockExpression.this.integralExpression.setExpression(getDefaultIntegral(input.expression)); + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) + throws DatabaseException { + // Delete the possible integral expression from the database to note + // that we are in the "default" mode. + SysdynResource sr = SysdynResource.getInstance(graph); + graph.deny(input.expression, sr.StockExpression_useCustomIntegral); + graph.claimLiteral(input.expression, sr.StockExpression_integralEquation, getDefaultIntegral(graph, input.expression)); + } + }); + break; + } + } + + }); + + label = new Label(parent, SWT.NONE); + label.setText("Initial\nValue"); + + initialExpression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input); + initialExpression.setExpression(initialEquation); + GridDataFactory.fillDefaults().grab(true, true).applyTo(initialExpression); + initialExpression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + lastSelectedText = initialExpression; + } + }); + + lastSelectedText = initialExpression; + } + + @Override + public void focus() { + this.lastSelectedText.focus(); + } + + @Override + public List getExpressionFields() { + return Arrays.asList(this.integralExpression, this.initialExpression); + } + + @Override + public void readData(final Resource expression, Map data) { + Pair equations = null; + if (expression != null && data.get("initialEquation") == null) { + try { + equations = SimanticsUI.getSession().syncRequest(new Read>() { + + @Override + public Pair perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if (graph.isInstanceOf(expression, sr.StockExpression)) { + String initialEquation = graph.getPossibleRelatedValue(expression, sr.StockExpression_initialEquation); + String integralEquation = graph.getPossibleRelatedValue(expression, sr.StockExpression_integralEquation); + initialEquation = (initialEquation != null) ? initialEquation : ""; + return new Pair(integralEquation, initialEquation); + } else { + return new Pair(null, ""); + } + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + data.put("initialEquation", equations.second); + } + + if (equations.first == null) { + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + graph.claimLiteral(input.expression, sr.StockExpression_integralEquation, getDefaultIntegral(graph, input.expression)); + } + + }); + } catch (DatabaseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + data.put("integral", getDefaultIntegral(expression)); + } else { + data.put("integral", equations.first); + } + + } + + @Override + public void replaceSelection(String var) { + if(lastSelectedText != null) { + IDocument doc = lastSelectedText.getDocument(); + try { + Point selection = lastSelectedText.getSelection(); + doc.replace(selection.x, selection.y, var); + lastSelectedText.setSelection(selection.x + var.length()); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + } + + @Override + public void save(final Resource expression, final Map data) { + final String currentInitial = this.initialExpression.getExpression(); + final String currentIntegral = this.integralExpression.getExpression(); + if (currentIntegral == null) { + this.integralExpression.setExpression(getDefaultIntegral(expression)); + } + if(!currentInitial.equals(data.get("initialEquation")) + || currentIntegral == null + || !currentIntegral.equals(data.get("integral"))) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph g) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + + if(!g.isInstanceOf(expression, sr.StockExpression)) { + Resource variable = g.getPossibleObject(expression, l0.PartOf); + Resource expressionList = g.getPossibleObject(variable, sr.Variable_expressionList); + Resource temp = g.newResource(); + ListUtils.replace(g, expressionList, expression, temp); + + for(Resource predicate : g.getPredicates(expression)) { + g.deny(expression, predicate); + } + g.claim(expression, l0.InstanceOf, null, sr.StockExpression); + + ListUtils.replace(g, expressionList, temp, expression); + + RemoverUtil.remove(g, temp); + + g.claim(expression, l0.PartOf, variable); + } + g.claimLiteral(expression, sr.StockExpression_initialEquation, currentInitial); + + if (!currentIntegral.equals(data.get("integral"))) { + // If the value is not same as default, enable the custom tag + g.claim(expression, sr.StockExpression_useCustomIntegral, expression); + } + g.claimLiteral(expression, sr.StockExpression_integralEquation, currentIntegral); + } + + }); + } + this.initialExpression.setExpression(currentInitial); + this.integralExpression.setExpression(currentIntegral); + } + + @Override + public void updateData(Map data) { + if(this.initialExpression != null && this.initialExpression.getExpression() != null) + data.put("initialEquation", this.initialExpression.getExpression()); + if(this.integralExpression != null && this.integralExpression.getExpression() != null) + data.put("integral", this.integralExpression.getExpression()); + } + + + private static String getDefaultIntegral(ReadGraph graph, Resource expression) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + // find the variable + Resource variable = graph.getPossibleObject(expression, l0.PartOf); + if(variable == null) + return ""; + + SysdynModelManager sdm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel model = sdm.getModel(graph, graph.getSingleObject(variable, l0.PartOf)); + model.update(graph); + + Stock stock = (Stock)model.getElement(variable); + + String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange); + if(range == null) + range = ""; + + StringBuilder builder = new StringBuilder(); + builder.append(""); + for(Valve in : stock.getIncomingValves()) { + builder.append(" + " + in.getName() + range); + } + for(Valve out : stock.getOutgoingValves()) { + builder.append(" - " + out.getName() + range); + } + if (builder.indexOf(" + ") == 0) + builder.delete(0, 3); + + return builder.toString().trim(); + } + + + private static String getDefaultIntegral(final Resource expression) { + + String integral = ""; + if(expression == null) + return integral; + try { + integral = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + return getDefaultIntegral(graph, expression); + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return integral; + } + + @Override + public void addKeyListener(KeyListener listener) { + this.initialExpression.getSourceViewer().getTextWidget().addKeyListener(listener); + this.integralExpression.getSourceViewer().getTextWidget().addKeyListener(listener); + + } + + @Override + public void addModifyListener(ModifyListener listener) { + this.initialExpression.getSourceViewer().getTextWidget().addModifyListener(listener); + this.integralExpression.getSourceViewer().getTextWidget().addModifyListener(listener); + + } + + @Override + public void addFocusListener(FocusListener listener) { + this.initialExpression.getSourceViewer().getTextWidget().addFocusListener(listener); + this.integralExpression.getSourceViewer().getTextWidget().addFocusListener(listener); + } + + @Override + public void addVerifyKeyListener(VerifyKeyListener listener) { + this.initialExpression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener); + this.integralExpression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java new file mode 100644 index 00000000..32b0bfed --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java @@ -0,0 +1,456 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.expressions; + +import java.awt.BasicStroke; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.geom.Point2D; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.swing.Timer; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.swt.SWT; +import org.eclipse.swt.awt.SWT_AWT; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.data.xy.XYDataset; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.VirtualGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.tableParser.ParseException; +import org.simantics.sysdyn.tableParser.TableParser; +import org.simantics.sysdyn.tableParser.Token; +import org.simantics.sysdyn.ui.utils.SyntaxError; +import org.simantics.sysdyn.utils.SheetUtils; +import org.simantics.ui.SimanticsUI; + +public class WithLookupExpression implements IExpression { + + private ExpressionField expression; + private ExpressionField lookup; + private ExpressionField lastSelectedText = expression; + private Timer updateChartTimer; + + private ChartPanel smallPanel; + private Frame smallFrame; + + private final ExpressionWidgetInput input; + private Resource expr; + + public WithLookupExpression(ExpressionWidgetInput input) { + this.input = input; + this.expr = input.expression; + } + + @Override + public void createExpressionFields(Composite parent, final Map data, Table allowedVariables) { + GridLayoutFactory.fillDefaults().numColumns(3).applyTo(parent); + + updateChartTimer = new Timer(1000, new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + updateChart(); + } + }); + updateChartTimer.setRepeats(false); + + String equation = data.get("equation") != null ? (String)data.get("equation") : ""; + String lookupTable = data.get("lookup") != null ? (String)data.get("lookup") : ""; + + Label l = new Label(parent, SWT.NONE); + l.setText("With\nLookup"); + + expression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true ,input); + expression.setExpression(equation); + GridDataFactory.fillDefaults().grab(true, true).applyTo(expression); + + expression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + lastSelectedText = expression; + } + }); + + Composite chartContainer = new Composite(parent, SWT.NONE); + createChart(chartContainer, data); + + + l = new Label(parent, SWT.NONE); + l.setText("Lookup\ntable"); + + lookup = new ExpressionField(parent, SWT.BORDER, null, false, input); + lookup.setExpression(lookupTable); + GridDataFactory.fillDefaults().grab(true, true).applyTo(lookup); + + lookup.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + lastSelectedText = lookup; + save(expr, data); + } + }); + + lookup.getSourceViewer().getTextWidget().addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + if(!updateChartTimer.isRunning()) + updateChartTimer.start(); + else + updateChartTimer.restart(); + } + }); + + + SimanticsUI.getSession().asyncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + String result = ""; + if (expr != null && graph.isInstanceOf(expr, sr.WithLookupExpression)) { + result = graph.getPossibleRelatedValue(expr, sr.WithLookupExpression_lookup); + } + return result; + } + }, new Listener() { + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public void execute(final String result) { + if(lookup != null) + lookup.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + lookup.setExpression(result); + updateChart(); + } + }); + } + + @Override + public boolean isDisposed() { + if(lookup != null && !lookup.isDisposed()) { + return false; + } + return true; + } + }); + + updateChart(); + } + + @Override + public void focus() { + if(this.lastSelectedText != null) this.lastSelectedText.focus(); + } + + @Override + public List getExpressionFields() { + return Arrays.asList(this.expression, this.lookup); + } + + @Override + public void readData(final Resource expression, Map data) { + + class Auxiliary { + String equation, lookup; + } + + Auxiliary results = null; + + if (data.get("equation") == null) { + try { + results = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Auxiliary perform(ReadGraph graph) throws DatabaseException { + Auxiliary results = new Auxiliary(); + SysdynResource sr = SysdynResource.getInstance(graph); + if (expression != null && graph.isInstanceOf(expression, sr.WithLookupExpression)) { + results.equation = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_expression); + results.lookup = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_lookup); + } else { + results.equation = ""; + results.lookup = ""; + } + return results; + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + data.put("equation", results.equation == null ? "" : results.equation); + data.put("lookup", results.lookup == null ? "" : results.lookup); + } + + } + + @Override + public void replaceSelection(String var) { + if(lastSelectedText != null) { + IDocument doc = lastSelectedText.getDocument(); + try { + Point selection = lastSelectedText.getSelection(); + doc.replace(selection.x, selection.y, var); + lastSelectedText.setSelection(selection.x + var.length()); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + } + + @Override + public void save(final Resource expression, Map data) { + final String currentExpression = this.expression.getExpression(); + final String currentLookupTable = lookup.getExpression(); + String oldExpression = (String)data.get("equation"); + String oldLookupTable = (String)data.get("lookup"); + + if(oldExpression == null || oldLookupTable == null || + (currentExpression != null && currentLookupTable != null + && (!currentExpression.equals(oldExpression) || + !currentLookupTable.equals(oldLookupTable)))) { + data.putAll(data); + data.put("equation", currentExpression); + data.put("lookup", currentLookupTable); + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph g) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + Layer0 l0 = Layer0.getInstance(g); + + if(!g.isInstanceOf(expr, sr.WithLookupExpression)) { + + + final Resource newExpression = GraphUtils.create2(g, sr.WithLookupExpression, + sr.WithLookupExpression_minX, 0.0, + sr.WithLookupExpression_maxX, 10.0, + sr.WithLookupExpression_minY, 0.0, + sr.WithLookupExpression_maxY, 10.0); + String arrayRange = g.getPossibleRelatedValue(expression, sr.Expression_arrayRange, Bindings.STRING); + if(arrayRange != null) + g.claimLiteral(newExpression, sr.Expression_arrayRange, arrayRange); + + final Resource variable = g.getSingleObject(expression, l0.PartOf); + Resource expressions = g.getPossibleObject(variable, sr.Variable_expressionList); + Resource node = ListUtils.getNode(g, expressions, expression); + g.deny(node, l0.List_Element); + g.claim(node, l0.List_Element, newExpression); + + g.deny(expression, l0.PartOf); + g.claim(newExpression, l0.PartOf, variable); + + VirtualGraph runtime = g.getService(VirtualGraph.class); + g.syncRequest(new WriteRequest(runtime) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression)) + graph.deny(variable, sr.IndependentVariable_activeExpression); + graph.claim(variable, sr.IndependentVariable_activeExpression, newExpression); + } + } + ); + expr = newExpression; + + } + g.claimLiteral(expr, sr.WithLookupExpression_expression, currentExpression); + g.claimLiteral(expr, sr.WithLookupExpression_lookup, currentLookupTable); + } + }); + } + + } + + @Override + public void updateData(Map data) { + if(this.expression != null && this.expression.getExpression() != null) + data.put("equation", this.expression.getExpression()); + if(this.lookup != null && this.lookup.getExpression() != null) + data.put("lookup", this.lookup.getExpression()); + } + + @Override + public void addKeyListener(KeyListener listener) { + this.expression.getSourceViewer().getTextWidget().addKeyListener(listener); + this.lookup.getSourceViewer().getTextWidget().addKeyListener(listener); + } + + @Override + public void addVerifyKeyListener(VerifyKeyListener listener) { + this.expression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener); + this.lookup.getSourceViewer().getTextWidget().addVerifyKeyListener(listener); + } + + @Override + public void addModifyListener(ModifyListener listener) { + this.expression.getSourceViewer().getTextWidget().addModifyListener(listener); + this.lookup.getSourceViewer().getTextWidget().addModifyListener(listener); + } + + @Override + public void addFocusListener(FocusListener listener) { + this.expression.getSourceViewer().getTextWidget().addFocusListener(listener); + this.lookup.getSourceViewer().getTextWidget().addFocusListener(listener); + } + + private void createChart(Composite composite, final Map data) { + GridLayoutFactory.fillDefaults().applyTo(composite); + GridDataFactory.fillDefaults().span(1, 2).hint(150, SWT.DEFAULT).applyTo(composite); + final Composite chartComposite = new Composite(composite, + SWT.NO_BACKGROUND | SWT.EMBEDDED); + GridDataFactory.fillDefaults().grab(true, true).applyTo(chartComposite); + smallFrame = SWT_AWT.new_Frame(chartComposite); + + XYDataset dataset = new XYSeriesCollection(new XYSeries("Lookup Table")); + JFreeChart chart = createChart(dataset); + smallPanel = new ChartPanel(chart); + smallFrame.add(smallPanel); + + } + + private static JFreeChart createChart(XYDataset dataset) { + JFreeChart chart = ChartFactory.createXYLineChart( + null, + null, + null, + dataset, + PlotOrientation.VERTICAL, + true, + true, + false + ); + chart.removeLegend(); + chart.getXYPlot().getDomainAxis().setTickLabelsVisible(true); + chart.getXYPlot().getDomainAxis().setAxisLineVisible(false); + chart.getXYPlot().getDomainAxis().setTickMarksVisible(true); + chart.getXYPlot().getRangeAxis().setTickLabelsVisible(true); + chart.getXYPlot().getRangeAxis().setAxisLineVisible(false); + chart.getXYPlot().getRangeAxis().setTickMarksVisible(true); + chart.getXYPlot().getRenderer().setSeriesStroke(0, new BasicStroke(3.0f)); + return chart; + } + + private void updateChart() { + ArrayList dataPoints = new ArrayList(); + TableParser parser = new TableParser(new StringReader("")); + parser.ReInit(new StringReader(lookup.getExpression())); + try { + parser.table(); + ArrayList xTokens = parser.getXTokens(); + ArrayList yTokens = parser.getYTokens(); + for(int i = 0; i < xTokens.size(); i++) { + dataPoints.add(new Point2D.Double( + Double.parseDouble(xTokens.get(i).image), + Double.parseDouble(yTokens.get(i).image))); + } + } catch (ParseException e1) { + if(lookup.getExpression().matches("[a-zA-Z0-9]*\\([a-zA-Z0-9:]*\\)")) { + // Might be a sheet reference + try { + final String name = lookup.getExpression().substring(0, lookup.getExpression().indexOf("(")); + final String range = lookup.getExpression().substring(lookup.getExpression().indexOf("(") + 1, lookup.getExpression().indexOf(")")); + String possibleTable = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Variable variable = input.variable; + Resource model = Variables.getModel(graph, variable); + return SheetUtils.getStringRepresentation(graph, model, name, range); + } + + }); + + + try { + if(possibleTable == null) { + ParseException e = new ParseException(e1.getMessage()); + e.currentToken = e1.currentToken; + throw e; + } + + parser.ReInit(new StringReader(possibleTable)); + parser.table(); + ArrayList xTokens = parser.getXTokens(); + ArrayList yTokens = parser.getYTokens(); + for(int i = 0; i < xTokens.size(); i++) { + dataPoints.add(new Point2D.Double( + Double.parseDouble(xTokens.get(i).image), + Double.parseDouble(yTokens.get(i).image))); + } + } catch (ParseException e2) { + this.lookup.setSyntaxError(new SyntaxError(e2.currentToken, "Syntax Error")); + System.out.println("MESSAGE: " + e2.getMessage()); + return; + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + } + + XYSeries series = new XYSeries("Lookup Table"); + for(Point2D point : dataPoints) { + series.add(point.getX(), point.getY()); + } + XYSeriesCollection dataset = new XYSeriesCollection(series); + smallPanel.getChart().getXYPlot().setDataset(dataset); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileImager.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileImager.java new file mode 100644 index 00000000..9af9a0d0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileImager.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.externalFiles; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.simantics.browsing.ui.swt.ImagerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; + +public class ExternalFileImager extends ImagerContributor { + + @Override + public ImageDescriptor getDescriptor(ReadGraph graph, ExternalFileNode input) + throws DatabaseException { + return null; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileLabeler.java new file mode 100644 index 00000000..ee94d5ad --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileLabeler.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.externalFiles; + +import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; + +public class ExternalFileLabeler extends LabelerContributorImpl{ + + @Override + public String getLabel(ReadGraph graph, ExternalFileNode input) + throws DatabaseException { + return NameUtils.getSafeName(graph, input.data); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileNode.java new file mode 100644 index 00000000..1150817a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileNode.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.externalFiles; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.request.Write; +import org.simantics.layer0.Layer0; +import org.simantics.ui.SimanticsUI; + +public class ExternalFileNode extends AbstractNode implements IModifiableNode, IDeletableNode { + + public ExternalFileNode(Resource data) { + super(data); + } + + @Override + public Modifier getModifier(String columnId) { + try { + final Resource hasName = Layer0.getInstance(SimanticsUI.getSession()).HasName; + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data, hasName) { + @Override + public String isValid(String label) { + if (label.isEmpty()) + return "Empty label not allowed"; + if (label.contains(" ")) + return "Spaces are not allowed"; + return null; + } + + @Override + protected Write getWriteRequest(final String label) { + return new WriteRequest() { + @Override + public void perform(WriteGraph g) throws DatabaseException { + g.claimLiteral(data, hasName, label); + } + }; + } + }; + return modifier; + } catch (DatabaseException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void delete() throws DeleteException { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + RemoverUtil.remove(graph, data); + } + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFiles.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFiles.java new file mode 100644 index 00000000..59ad535e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFiles.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.externalFiles; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; + +public class ExternalFiles extends ViewpointContributorImpl { + + @Override + public Collection getContribution(ReadGraph graph, Resource input) + throws DatabaseException { + + if(input == null) + return null; + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + ArrayList result = new ArrayList(); + for(Resource r : graph.syncRequest(new ObjectsWithType(input, l0.ConsistsOf, sr.ExternalFunctionFile))) { + result.add(new ExternalFileNode(r)); + } + + return result; + } + + @Override + public String getViewpointId() { + return "External Files"; + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ComboStringPropertyModifier.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ComboStringPropertyModifier.java new file mode 100644 index 00000000..a029acd3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ComboStringPropertyModifier.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Combo; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.utils.ReflectionUtils; +import org.simantics.utils.ui.ISelectionUtils; + +abstract public class ComboStringPropertyModifier implements TextModifyListener, Widget { + + private ISessionContext context; + private Object lastInput = null; + + final private Class clazz; + + public ComboStringPropertyModifier() { + clazz = ReflectionUtils.getSingleParameterType(getClass()); + } + + @Override + public void setInput(ISessionContext context, Object input) { + this.context = context; + lastInput = input; + } + + @Override + public void modifyText(TrackedModifyEvent e) { + Combo text = (Combo)e.getWidget(); + final String textValue = text.getText(); + final Object input = lastInput; + + try { + context.getSession().syncRequest(new WriteRequest() { + + @SuppressWarnings("unchecked") + @Override + public void perform(WriteGraph graph) throws DatabaseException { + + T single = (T) ISelectionUtils.filterSingleSelection((ISelection)input, clazz); + applyText(graph, single, textValue); + + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + } + + abstract public void applyText(WriteGraph graph, T input, String text) throws DatabaseException; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyFactory.java new file mode 100644 index 00000000..1cc23fe2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyFactory.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.utils.datastructures.Triple; + +public class DoublePropertyFactory extends ReadFactoryImpl { + + final private String propertyURI; + + public DoublePropertyFactory(String propertyURI) { + this.propertyURI = propertyURI; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple((Resource)inputContents, propertyURI, getClass()); + } + + @Override + public String perform(ReadGraph graph, Resource issue) throws DatabaseException { + + Double value = graph.getPossibleRelatedValue(issue, graph.getResource(propertyURI)); + if (value != null) + return value.toString(); + else + return ""; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyModifier.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyModifier.java new file mode 100644 index 00000000..58dc654e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyModifier.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; + +public class DoublePropertyModifier extends TextModifyListenerImpl { + + final private String propertyURI; + + public DoublePropertyModifier(ISessionContext context, String propertyURI) { + this.propertyURI = propertyURI; + } + + @Override + public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException { + if (text == null || text.equals("")) { + if(graph.hasStatement(input, graph.getResource(propertyURI))) + graph.deny(input, graph.getResource(propertyURI)); + } else { + graph.claimLiteral(input, graph.getResource(propertyURI), Double.parseDouble(text), Bindings.DOUBLE); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionLibraryNameInputValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionLibraryNameInputValidator.java new file mode 100644 index 00000000..18c1a414 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionLibraryNameInputValidator.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.eclipse.jface.dialogs.IInputValidator; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.ui.utils.FunctionLibraryNameValidator; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Name validator container for user defined function libraries. + * @author Tuomas Miettinen + * + */ +public class FunctionLibraryNameInputValidator implements IInputValidator, Widget { + + private Resource lastInput = null; + + public FunctionLibraryNameInputValidator(WidgetSupport support) { + support.register(this); + } + + /** + * Checks that the syntax of the given name is valid and there + * are no other components that have the same name in the configuration. + */ + @Override + public String isValid(final String newText) { + if (!new FunctionLibraryNameValidator().isValid(lastInput, newText)) + return "Not valid"; + else + return null; + } + + @Override + public void setInput(ISessionContext context, Object input) { + lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionNameInputValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionNameInputValidator.java new file mode 100644 index 00000000..a5cce2b3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionNameInputValidator.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.eclipse.jface.dialogs.IInputValidator; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.ui.utils.FunctionNameValidator; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Name validator container for user defined functions. + * @author Tuomas Miettinen + * + */ +public class FunctionNameInputValidator implements IInputValidator, Widget { + + private Resource lastInput = null; + + public FunctionNameInputValidator(WidgetSupport support) { + support.register(this); + } + + /** + * Checks that the syntax of the given name is valid and there + * are no other components that have the same name in the configuration. + */ + @Override + public String isValid(final String newText) { + if (!new FunctionNameValidator().isValid(lastInput, newText)) + return "Not valid"; + else + return null; + } + + @Override + public void setInput(ISessionContext context, Object input) { + lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyFactory.java new file mode 100644 index 00000000..d3629566 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyFactory.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.utils.datastructures.Triple; + +public class IntegerPropertyFactory extends ReadFactoryImpl { + + final private String propertyURI; + + public IntegerPropertyFactory(String propertyURI) { + this.propertyURI = propertyURI; + } + + @Override + public Object getIdentity(Object inputContents) { + return new Triple((Resource)inputContents, propertyURI, getClass()); + } + + @Override + public String perform(ReadGraph graph, Resource issue) throws DatabaseException { + + Integer value = graph.getPossibleRelatedValue(issue, graph.getResource(propertyURI)); + if (value != null) + return value.toString(); + else + return ""; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyModifier.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyModifier.java new file mode 100644 index 00000000..fb612405 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyModifier.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; + +public class IntegerPropertyModifier extends TextModifyListenerImpl { + + final private String propertyURI; + + public IntegerPropertyModifier(ISessionContext context, String propertyURI) { + this.propertyURI = propertyURI; + } + + @Override + public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException { + if (text == null || text.equals("")) { + if(graph.hasStatement(input, graph.getResource(propertyURI))) + graph.deny(input, graph.getResource(propertyURI)); + } else { + graph.claimLiteral(input, graph.getResource(propertyURI), Integer.parseInt(text), Bindings.INTEGER); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModelNameInputValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModelNameInputValidator.java new file mode 100644 index 00000000..625e9559 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModelNameInputValidator.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.eclipse.jface.dialogs.IInputValidator; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.ui.utils.ModelNameValidator; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Name validator container for model. + * @author Tuomas Miettinen + * + */ +public class ModelNameInputValidator implements IInputValidator, Widget { + + private Resource lastInput = null; + + public ModelNameInputValidator(WidgetSupport support) { + support.register(this); + } + + /** + * Checks that the syntax of the given name is valid and there + * are no other components that have the same name in the configuration. + */ + @Override + public String isValid(final String newText) { + if (!new ModelNameValidator().isValid(lastInput, newText)) + return "Not valid"; + else + return null; + } + + @Override + public void setInput(ISessionContext context, Object input) { + lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModuleTypeNameInputValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModuleTypeNameInputValidator.java new file mode 100644 index 00000000..1340525a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModuleTypeNameInputValidator.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.eclipse.jface.dialogs.IInputValidator; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.ui.utils.ModuleTypeNameValidator; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Name validator container for module types. + * @author Tuomas Miettinen + * + */ +public class ModuleTypeNameInputValidator implements IInputValidator, Widget { + + private Resource lastInput = null; + + public ModuleTypeNameInputValidator(WidgetSupport support) { + support.register(this); + } + + /** + * Checks that the syntax of the given name is valid and there + * are no other components that have the same name in the configuration. + */ + @Override + public String isValid(final String newText) { + if (!new ModuleTypeNameValidator().isValid(lastInput, newText)) + return "Not valid"; + else + return null; + } + + @Override + public void setInput(ISessionContext context, Object input) { + lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNameInputValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNameInputValidator.java new file mode 100644 index 00000000..3a6af0ce --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNameInputValidator.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.eclipse.jface.dialogs.IInputValidator; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.Resource; +import org.simantics.db.management.ISessionContext; +import org.simantics.sysdyn.ui.utils.VariableNameValidator; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Name validator container for module types. + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class VariableNameInputValidator implements IInputValidator, Widget { + + private Resource lastInput = null; + + public VariableNameInputValidator(WidgetSupport support) { + support.register(this); + } + + /** + * Checks that the syntax of the given name is valid and there + * are no other components that have the same name in the configuration. + */ + @Override + public String isValid(final String newText) { + if (!new VariableNameValidator().isValid(lastInput, newText, true)) + return "Not valid"; + else + return null; + } + + @Override + public void setInput(ISessionContext context, Object input) { + lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNamePropertyModifier.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNamePropertyModifier.java new file mode 100644 index 00000000..297b12b5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNamePropertyModifier.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.factories; + +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.ui.utils.VariableNameValidator; + +public class VariableNamePropertyModifier extends TextModifyListenerImpl { + + final private String propertyURI; + + public VariableNamePropertyModifier(ISessionContext context, String propertyURI) { + this.propertyURI = propertyURI; + } + + /** + * Overrides the original applyText. Renames variables also in equations in the same configuration. + */ + @Override + public void applyText(WriteGraph graph, Resource variable, String text) throws DatabaseException { + + // TODO: separate possible array indexes + + // TODO: add enumerations to the variable + Layer0 L0 = Layer0.getInstance(graph); + String originalName = graph.getRelatedValue(variable, L0.HasName); + Resource configuration = graph.getPossibleObject(variable, L0.PartOf); + new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, text); + graph.claimLiteral(variable, graph.getResource(propertyURI), text, Bindings.STRING); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/FunctionCodeWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/FunctionCodeWidget.java new file mode 100644 index 00000000..696f4815 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/FunctionCodeWidget.java @@ -0,0 +1,334 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.functions; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.StringReader; +import java.util.ArrayList; + +import javax.swing.Timer; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.custom.VerifyKeyListener; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Listener; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.modelParser.ModelParser; +import org.simantics.sysdyn.modelParser.ModelParser.Parameter; +import org.simantics.sysdyn.modelParser.ParseException; +import org.simantics.sysdyn.modelParser.Token; +import org.simantics.sysdyn.modelParser.TokenMgrError; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField; +import org.simantics.sysdyn.ui.utils.SyntaxError; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +public class FunctionCodeWidget implements Widget { + + private ExpressionField modelicaCode; + private Resource function; + + private Timer updateChartTimer; + private static int VALIDATION_DELAY_TIME = 500; + + private ArrayList inputs; + private ArrayList outputs; + + public FunctionCodeWidget(Composite parent, WidgetSupport support, int style) { + support.register(this); + modelicaCode = new ExpressionField(parent, SWT.BORDER, null, false, null); + GridDataFactory.fillDefaults().grab(true, true).applyTo(modelicaCode); + + + // Support shift+enter for line change + modelicaCode.getSourceViewer().getTextWidget().addVerifyKeyListener(new VerifyKeyListener() { + + @Override + public void verifyKey(VerifyEvent event) { + if(event.keyCode == SWT.CR || event.keyCode == SWT.KEYPAD_CR) { + if((event.stateMask & SWT.SHIFT) == 0) { + event.doit = false; + Listener[] listeners = modelicaCode.getSourceViewer().getTextWidget().getListeners(SWT.FocusOut); + for(Listener l : listeners) { + modelicaCode.getSourceViewer().getTextWidget().removeListener(SWT.FocusOut, l); + } + ((StyledText)event.widget).getParent().forceFocus(); + save(); + for(Listener l : listeners) { + modelicaCode.getSourceViewer().getTextWidget().addListener(SWT.FocusOut, l); + } + + } + } + } + }); + + + modelicaCode.getSourceViewer().getTextWidget().addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + validateFieldsTimed(); + } + }); + + modelicaCode.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + save(); + } + }); + + + updateChartTimer = new Timer(VALIDATION_DELAY_TIME, new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if(modelicaCode == null || modelicaCode.isDisposed()) + return; + modelicaCode.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + validate(); + } + }); + } + }); + updateChartTimer.setRepeats(false); + } + + @Override + public void setInput(ISessionContext context, Object input) { + function = AdaptionUtils.adaptToSingle(input, Resource.class); + + try { + String code = context.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + String code = graph.getPossibleRelatedValue( + function, SysdynResource.getInstance(graph).SysdynModelicaFunction_modelicaFunctionCode); + if (code == null) { + code = graph.getPossibleRelatedValue( + function, SysdynResource.getInstance(graph).SysdynModelicaFunction_modelicaFunctionInterface); + if (code == null) { + code = new String(""); + } + } + return code; + } + + }); + if(code != null) { + modelicaCode.setExpression(code); + validate(); + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + + public void validateFieldsTimed() { + validateFieldsTimed(VALIDATION_DELAY_TIME); + } + + public void validateFieldsTimed(int delay) { + updateChartTimer.setDelay(delay); + if(!updateChartTimer.isRunning()) + updateChartTimer.start(); + else + updateChartTimer.restart(); + } + + public void validate() { + modelicaCode.resetAnnotations(); + String code = modelicaCode.getExpression(); + StringReader sr = new StringReader(code); + ModelParser modelParser = new ModelParser(sr); + + try { + modelParser.parse_composition(); + + inputs = modelParser.getInputs(); + outputs = modelParser.getOutputs(); + + } catch (ParseException e1) { + Token token = e1.currentToken; + modelicaCode.setSyntaxError(new SyntaxError(token.image, "Syntax error", token.beginLine, token.beginColumn, token.endLine, token.endColumn)); + } catch (TokenMgrError err) { + String message = err.getMessage(); + String line = message.substring(0, message.indexOf(",")); + line = line.substring(line.lastIndexOf(" ") + 1); + String column = message.substring(message.indexOf(",") + 1, message.indexOf(".")); + column = column.substring(column.lastIndexOf(" ") + 1); + try { + Integer endLine = Integer.parseInt(line); + Integer endColumn = Integer.parseInt(column); + Token token = modelParser.token; + modelicaCode.setSyntaxError(new SyntaxError(token.image, "Syntax error", token.endLine, token.endColumn, endLine, endColumn)); + } catch (NumberFormatException e) { + + } + + } + } + + private void save() { + final String code = modelicaCode.getExpression(); + + // Update input and output lists. + validate(); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + // Remove the existing input list + removeInputList(graph); + // Create the new input list + createInputList(graph); + + // Remove the existing output list + removeOutputList(graph); + // Create the new output list + createOutputList(graph); + + // Update the function code + graph.claimLiteral( + function, + sr.SysdynModelicaFunction_modelicaFunctionCode, + code); + } + + private void removeInputList(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource oldInputList = graph.getPossibleObject(function, sr.SysdynModelicaFunction_inputs); + if (oldInputList != null) { + // Find all the inputs + for (Resource input : ListUtils.toList(graph, oldInputList)) { + // Check if we have a variable length input + if (graph.isInstanceOf(input, sr.SysdynModelicaFunction_VariableLengthInput)) { + // The variable length inputs are found here + Resource variableLengthInputLabels = graph.getPossibleObject(input, sr.SysdynModelicaFunction_VariableLengthInput_shownLabels); + if (variableLengthInputLabels != null) { + // Find labels (strings) + for (Resource label : ListUtils.toList(graph, variableLengthInputLabels)) { + //Remove string + RemoverUtil.remove(graph, label); + } + // Remove list + RemoverUtil.remove(graph, variableLengthInputLabels); + } + } + // Remove the input + RemoverUtil.remove(graph, input); + } + // Remove the list + RemoverUtil.remove(graph, oldInputList); + } + } + + private void createInputList(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + ArrayList inputResources = new ArrayList(); + // Create inputs + if (inputs != null) { + for (Parameter input : inputs) { + Resource r = GraphUtils.create2(graph, sr.SysdynModelicaFunction_Input, + l0.HasName, input.name, + sr.Variable_type, input.type, + sr.SysdynModelicaFunction_optional, input.optional ? l0.True : l0.False); + if (input.description != null) { + // Description is optional + graph.claimLiteral(r, sr.SysdynModelicaFunction_definition, input.description); + } + inputResources.add(r); + } + graph.claim( + function, + sr.SysdynModelicaFunction_inputs, + ListUtils.create(graph, inputResources)); + } + } + + private void removeOutputList(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource oldOutputList = graph.getPossibleObject(function, sr.SysdynModelicaFunction_outputs); + if (oldOutputList != null) { + // Find all the outputs + for (Resource output : ListUtils.toList(graph, oldOutputList)) { + // Remove the output + RemoverUtil.remove(graph, output); + } + // Remove the list + RemoverUtil.remove(graph, oldOutputList); + } + } + + private void createOutputList(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + ArrayList outputResources = new ArrayList(); + // Create outputs + if (outputs != null) { + for (Parameter output : outputs) { + Resource r = GraphUtils.create2(graph, sr.SysdynModelicaFunction_Output, + l0.HasName, output.name, + sr.Variable_type, output.type); + if (output.description != null) { + // Description is optional + graph.claimLiteral(r, sr.SysdynModelicaFunction_definition, output.description); + } + outputResources.add(r); + } + graph.claim( + function, + sr.SysdynModelicaFunction_outputs, + ListUtils.create(graph, outputResources)); + } + + } + + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SelectedSharedFunctionLibraries.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SelectedSharedFunctionLibraries.java new file mode 100644 index 00000000..255555b9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SelectedSharedFunctionLibraries.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.functions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode; + +public class SelectedSharedFunctionLibraries extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, Resource input) + throws DatabaseException { + ArrayList> result = new ArrayList>(); + + + for(Resource sharedLibrary : graph.syncRequest(new ObjectsWithType( + input, + Layer0.getInstance(graph).IsLinkedTo, + SysdynResource.getInstance(graph).SharedFunctionOntology))) + { + result.add(new SharedFunctionLibraryNode(sharedLibrary)); + } + + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SharedFunctionLibraries.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SharedFunctionLibraries.java new file mode 100644 index 00000000..70dbb6f7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SharedFunctionLibraries.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.functions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode; + +public class SharedFunctionLibraries extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, Resource input) + throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + ArrayList> result = new ArrayList>(); + + // Find shared ontologies. graph.getPossibleResource("http://SharedOntologies") does not update if it was null for the first time. + Resource sharedOntologies = null; + Resource root = input; + while(graph.getPossibleObject(root, l0.PartOf) != null) + root = graph.getPossibleObject(root, l0.PartOf); + + for(Resource r : graph.getObjects(root, l0.ConsistsOf)) { + if("SharedOntologies".equals(NameUtils.getSafeName(graph, r))) { + sharedOntologies = r; + break; + } + } + + if(sharedOntologies == null) { + return result; + } + + // Find all shared function ontologies. + // (Don't know why ObjectsWithType works only the first time, then gives nothing) + ArrayList sharedFunctionLibraries = new ArrayList(); + for(Resource r : graph.getObjects(sharedOntologies, l0.ConsistsOf)) { + if(graph.isInstanceOf(r, sr.SharedFunctionOntology)) + sharedFunctionLibraries.add(r); + } + + // Find all shared function ontologies that have already been selected + Collection selectedSharedFunctionLibraries = graph.syncRequest(new ObjectsWithType( + input, l0.IsLinkedTo, sr.SharedFunctionOntology)); + + // Remove all selected ontologies from the shared function ontologies + sharedFunctionLibraries.removeAll(selectedSharedFunctionLibraries); + + for(Resource ontology : sharedFunctionLibraries) { + result.add(new SharedFunctionLibraryNode(ontology)); + } + + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableChildRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableChildRule.java new file mode 100644 index 00000000..45b29241 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableChildRule.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.historyDataset; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.manager.HistoryDatasetUtils; +import org.simantics.sysdyn.ui.properties.HistoryDataTab; + +/** + * Variable child rule for GE in {@link HistoryDataTab} + * @author Teemu Lempinen + * + */ +public class VariableChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) throws DatabaseException { + ArrayList result = new ArrayList(); + if(!(parent instanceof Resource)) + return result; + result.addAll(HistoryDatasetUtils.getVariableNamesInRange(graph, (Resource)parent)); + return result; + + + } + + @Override + public Collection getParents(ReadGraph graph, Object child) throws DatabaseException { + return new ArrayList(); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableLabelRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableLabelRule.java new file mode 100644 index 00000000..0cb9459b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableLabelRule.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.historyDataset; + +import java.util.Collections; +import java.util.Map; + +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.labels.LabelRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.properties.HistoryDataTab; + +/** + * Variable label rule for GE in {@link HistoryDataTab} + * @author Teemu Lempinen + * + */ +public class VariableLabelRule implements LabelRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(String.class); + } + + @Override + public Map getLabel(ReadGraph graph, Object content) throws DatabaseException { + return Collections.singletonMap(ColumnKeys.SINGLE, (content instanceof String ? (String)content : "No content")); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleInputEditingSupport.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleInputEditingSupport.java new file mode 100644 index 00000000..42a751a1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleInputEditingSupport.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import java.util.HashMap; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ComboBoxCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.SWT; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +public class ModuleInputEditingSupport extends EditingSupport { + private CellEditor editor; + private int column; + private HashMap optionResources; + private String[] options; + private TableViewer tableViewer; + + public ModuleInputEditingSupport(TableViewer viewer, int column) { + super(viewer); + this.tableViewer = (TableViewer)viewer; + this.column = column; + } + + @Override + protected boolean canEdit(Object element) { + switch (this.column) { + case 0: return false; + default: return true; + } + } + + + @Override + protected CellEditor getCellEditor(Object element) { + // Create the correct editor based on the column index + switch (column) { + case 0: + editor = new TextCellEditor(this.tableViewer.getTable()); + case 1: + ReferenceRow row = (ReferenceRow)element; + final Resource module = row.getModule(); + final Resource inputVariable = row.getVariable(); + + optionResources = new HashMap(); + try { + optionResources = SimanticsUI.getSession().syncRequest(new Read>() { + + @Override + public HashMap perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + HashMap result = new HashMap(); + for(Resource dependency : graph.syncRequest(new ObjectsWithType(module, sr.Variable_isHeadOf, sr.Dependency))) { + if(graph.getPossibleObject(dependency, sr.Dependency_refersTo) == null || + graph.getPossibleObject(dependency, sr.Dependency_refersTo).equals(inputVariable)) { + Resource output = graph.getSingleObject(dependency, sr.Variable_HasTail); + + if(graph.isInstanceOf(output, sr.Shadow)) { + output = graph.getPossibleObject(output, sr.Shadow_original); + } + + if(output != null) + result.put((String)graph.getRelatedValue(output, l0.HasName), dependency); + } + } + return result; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + options = optionResources.keySet().toArray(new String[optionResources.keySet().size() + 1]); + options[optionResources.keySet().size()] = ""; + ComboBoxCellEditor ceditor = new ComboBoxCellEditor(this.tableViewer.getTable(), options, SWT.READ_ONLY); + ceditor.setActivationStyle(1); + editor = ceditor; + break; + default: + editor = null; + } + + return editor; + } + + @Override + protected Object getValue(Object element) { + ReferenceRow referenceRow = (ReferenceRow) element; + + switch (this.column) { + case 0: + return referenceRow.getName(); + case 1: + String refersToName = referenceRow.getValue(); + if (refersToName == null) return options.length - 1; + for(int i = 0; i < options.length ; i++) { + if(refersToName.equals(options[i])) return i; + } + return options[options.length - 1]; + default: + break; + } + return null; + } + + @Override + protected void setValue(Object element, Object value) { + ReferenceRow referenceRow = (ReferenceRow) element; + String valueString = String.valueOf(value); + switch (this.column) { + case 0: + break; + case 1: + referenceRow.setRefersTo(optionResources.get(options[Integer.parseInt(valueString)])); + break; + default: + break; + } + + getViewer().update(element, null); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleOutputEditingSupport.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleOutputEditingSupport.java new file mode 100644 index 00000000..4b64f3bc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleOutputEditingSupport.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import java.util.HashMap; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ComboBoxCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.SWT; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +public class ModuleOutputEditingSupport extends EditingSupport { + private CellEditor editor; + private int column; + private HashMap optionResources; + private String[] options; + private TableViewer tableViewer; + + public ModuleOutputEditingSupport(TableViewer viewer, int column) { + super(viewer); + this.tableViewer = (TableViewer)viewer; + this.column = column; + } + + @Override + protected boolean canEdit(Object element) { + switch (this.column) { + case 0: return false; + default: return true; + } + } + + + @Override + protected CellEditor getCellEditor(Object element) { + // Create the correct editor based on the column index + switch (column) { + case 0: + editor = new TextCellEditor(this.tableViewer.getTable()); + case 1: + ReferenceRow row = (ReferenceRow)element; + final Resource module = row.getModule(); + final Resource outputVariable = row.getVariable(); + + optionResources = new HashMap(); + try { + optionResources = SimanticsUI.getSession().syncRequest(new Read>() { + + @Override + public HashMap perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + HashMap result = new HashMap(); + for(Resource dependency : graph.syncRequest(new ObjectsWithType(module, sr.Variable_isTailOf, sr.Dependency))) { + if(graph.getPossibleObject(dependency, sr.Dependency_refersTo) == null + || !graph.hasStatement(graph.getPossibleObject(dependency, sr.Dependency_refersTo), l0.HasName) + || graph.getPossibleObject(dependency, sr.Dependency_refersTo).equals(outputVariable)) { + Resource input = graph.getSingleObject(dependency, sr.Variable_HasHead); + result.put((String)graph.getRelatedValue(input, l0.HasName), dependency); + } + } + return result; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + options = optionResources.keySet().toArray(new String[optionResources.keySet().size() + 1]); + options[optionResources.keySet().size()] = ""; + ComboBoxCellEditor ceditor = new ComboBoxCellEditor(this.tableViewer.getTable(), options, SWT.READ_ONLY); + ceditor.setActivationStyle(1); + editor = ceditor; + break; + default: + editor = null; + } + + return editor; + } + + @Override + protected Object getValue(Object element) { + ReferenceRow referenceRow = (ReferenceRow) element; + + switch (this.column) { + case 0: + return referenceRow.getName(); + case 1: + String refersToName = referenceRow.getValue(); + if (refersToName == null) return options.length - 1; + for(int i = 0; i < options.length ; i++) { + if(refersToName.equals(options[i])) return i; + } + return options[options.length - 1]; + default: + break; + } + return null; + } + + @Override + protected void setValue(Object element, Object value) { + ReferenceRow referenceRow = (ReferenceRow) element; + String valueString = String.valueOf(value); + switch (this.column) { + case 0: + break; + case 1: + referenceRow.setRefersTo(optionResources.get(options[Integer.parseInt(valueString)])); + break; + default: + break; + } + + getViewer().update(element, null); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleParameterOverrideUtils.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleParameterOverrideUtils.java new file mode 100644 index 00000000..06a9e2bb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleParameterOverrideUtils.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.IndependentVariable; + +/** + * Utilities for module parameter override functionalities + * + * @author Teemu Lempinen + * + */ +public class ModuleParameterOverrideUtils { + + /** + * Get the parameter expression of a variable or null, if it does not contain a parameter expression, + * or there are many parameter expressions + * @param graph ReadGraph + * @param variable IndependentVariable + * @return parameter expression or null + * @throws DatabaseException + */ + public static String getParameterExpression(IndependentVariable variable) throws DatabaseException { + String result = null; + try { + result = variable.getExpressions().get(0).getExpression(); + if(result.contains("/* Actual value read from init file */")) + result = result.substring(0, result.indexOf("/* Actual value read from init file */")); + } catch (NullPointerException e) { + } + return result; + } + + /** + * Get the expression, or the overriding expression, of a parameter + * @param graph ReadGraph + * @param parent Parent resource + * @param variable IndependentVariable + * @return Overriding expression, or the default parameter expression, or null + * @throws DatabaseException + */ + public static String getParameterExpressionOrOverride(ReadGraph graph, Resource parent, IndependentVariable variable) + throws DatabaseException { + String result = null; + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + + // Get possible override + for(Resource r : graph.syncRequest(new ObjectsWithType(parent, L0.ConsistsOf, sr.Module_ParameterOverride))) { + Resource overridden = graph.getPossibleObject(r, sr.Module_ParameterOverride_overriddenParameter); + if(variable.getName().equals(NameUtils.getSafeName(graph, overridden))) { + result = graph.getPossibleRelatedValue(r, sr.Module_ParameterOverride_overrideExpression); + } + } + + if(result == null) { + // Parameter is not overridden, find the actual expression + result = getParameterExpression(variable); + } + return result; + } + + /** + * Find out if a variable has a single parameter expression + * @param graph ReadGraph + * @param variable Variable + * @return does the variable have a single parameter expression + * @throws DatabaseException + */ + public static boolean hasParameterExpression(ReadGraph graph, Resource variable) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + boolean result = false; + Resource expressionsResource = graph.getPossibleObject(variable, sr.Variable_expressionList); + if(expressionsResource != null) { + List expressions = ListUtils.toList(graph, expressionsResource); + if(expressions.size() == 1 && graph.isInstanceOf(expressions.get(0), sr.ParameterExpression)) { + result = true; + } + } + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterChildRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterChildRule.java new file mode 100644 index 00000000..5d88453e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterChildRule.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Stock; +import org.simantics.sysdyn.representation.Variability; + +public class ParameterChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) throws DatabaseException { + ArrayList result = new ArrayList(); + if(!(parent instanceof Resource)) + return result; + + Layer0 L0 = Layer0.getInstance(graph); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource moduleInstance = (Resource) parent; + + Resource type = graph.getSingleObject(moduleInstance, L0.InstanceOf); + Resource configuration = graph.getSingleObject(type, STR.IsDefinedBy); + SysdynModelManager sdm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel model = sdm.getModel(graph, configuration); + + Resource varConfRes = graph.getSingleObject(moduleInstance, L0.PartOf); + Configuration varConf = sdm.getModel(graph, varConfRes).getConfiguration(); + + for(Resource variable : graph.syncRequest(new ObjectsWithType(configuration, L0.ConsistsOf, sr.IndependentVariable))) { + IElement element = model.getElement(variable); + if(element instanceof IndependentVariable && !(element instanceof Stock)) + if(!Variability.CONTINUOUS.equals(Variability.getVariability((IndependentVariable)element, false, varConf))) + result.add(new ParameterNode(moduleInstance, varConf, variable, (IndependentVariable)element)); + } + + return result; + + + } + + @Override + public Collection getParents(ReadGraph graph, Object child) throws DatabaseException { + return new ArrayList(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelDecorationRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelDecorationRule.java new file mode 100644 index 00000000..993d6138 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelDecorationRule.java @@ -0,0 +1,57 @@ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import org.eclipse.jface.resource.ColorDescriptor; +import org.eclipse.swt.graphics.RGB; +import org.simantics.browsing.ui.content.LabelDecorator; +import org.simantics.browsing.ui.model.labeldecorators.LabelDecorationRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; + +public class ParameterLabelDecorationRule implements LabelDecorationRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Object.class); + } + + @Override + public LabelDecorator getLabelDecorator(ReadGraph graph, Object content) throws DatabaseException { + if(content instanceof ParameterNode) { + ParameterNode node = (ParameterNode) content; + String notOverriding = ModuleParameterOverrideUtils.getParameterExpression(node.getIndependentVariable()); + String overriding = ModuleParameterOverrideUtils.getParameterExpressionOrOverride(graph, node.getParent(), node.getIndependentVariable()); + + if(notOverriding == null) + return null; + + final boolean original = notOverriding.equals(overriding); + + return new LabelDecorator.Stub() { + @Override + public String decorateLabel(String label, String column, int itemIndex) { + if(ColumnKeys.VALUE.equals(column)) { + return original ? label : label + " [Overridden]"; + } else { + return label; + } + } + + @SuppressWarnings("unchecked") + @Override + public Color decorateForeground(Color color, String column, int itemIndex) { + Color result = null; + if(ColumnKeys.VALUE.equals(column)) { + if(original) + result = (Color) ColorDescriptor.createFrom(new RGB(125,125,125)); + else + result = (Color) ColorDescriptor.createFrom(new RGB(0,0,0)); + } + return result; + } + }; + } + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelRule.java new file mode 100644 index 00000000..0640bc34 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelRule.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import java.util.HashMap; +import java.util.Map; + +import org.simantics.browsing.ui.model.labels.LabelRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; + +public class ParameterLabelRule implements LabelRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Object.class); + } + + @Override + public Map getLabel(ReadGraph graph, Object content) throws DatabaseException { + Map result = new HashMap(); + + if(content instanceof ParameterNode) { + ParameterNode node = (ParameterNode) content; + String parameterExpression = ModuleParameterOverrideUtils.getParameterExpressionOrOverride(graph, node.getParent(), node.getIndependentVariable()); + String name = node.getIndependentVariable().getName(); + + result.put(ColumnKeys.MODULE_PARAMETER, name); + result.put(ColumnKeys.VALUE, parameterExpression); + } + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterModifierRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterModifierRule.java new file mode 100644 index 00000000..a964c5b6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterModifierRule.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.model.modifiers.ModifierRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.Variability; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; +import org.simantics.ui.SimanticsUI; + +public class ParameterModifierRule implements ModifierRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Object.class); + } + + @Override + public Modifier getModifier(ReadGraph graph, Object content, String columnKey) throws DatabaseException { + if(content instanceof ParameterNode && ColumnKeys.VALUE.equals(columnKey)) { + final ParameterNode node = (ParameterNode) content; + return new Modifier() { + + @Override + public String getValue() { + Read request = + new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + String parameterExpression = ModuleParameterOverrideUtils.getParameterExpressionOrOverride( + graph, + node.getParent(), + node.getIndependentVariable()); + + return parameterExpression != null ? parameterExpression : ""; + } + + }; + try { + return SimanticsUI.getSession().syncRequest(request); + } catch (DatabaseException e) { + e.printStackTrace(); + return ""; + } + } + + @Override + public String isValid(String label) { + if(label.isEmpty()) + return null; + + if(Variability.CONTINUOUS.equals(Variability.getVariability(node.getIndependentVariable(), label, false, node.getParentConfiguration()))) + return "Not valid"; + else + return null; + } + + @Override + public void modify(final String label) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + + // Remove possible old override + for(Resource r : graph.syncRequest(new ObjectsWithType(node.getParent(), L0.ConsistsOf, sr.Module_ParameterOverride))) { + if(node.getVariableResource().equals(graph.getPossibleObject(r, sr.Module_ParameterOverride_overriddenParameter))) { + RemoverUtil.remove(graph, r); + break; + } + } + + // Write the new override, if there is one + if(label != null && !label.isEmpty()) { + GraphUtils.create2(graph, sr.Module_ParameterOverride, + sr.Module_ParameterOverride_overriddenParameter, node.getVariableResource(), + sr.Module_ParameterOverride_overrideExpression, label, + L0.PartOf, node.getParent() + ); + } + } + }); + } + + }; + } else { + return null; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterNode.java new file mode 100644 index 00000000..49e3586c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterNode.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import org.simantics.db.Resource; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IndependentVariable; + +public class ParameterNode { + + private Resource moduleInstance; + private Resource variableResource; + private IndependentVariable independentVariable; + private Configuration parentConfiguration; + + public ParameterNode(Resource parent, Configuration parentConfiguration, Resource variableResource, IndependentVariable independentVariable) { + this.moduleInstance = parent; + this.variableResource = variableResource; + this.independentVariable = independentVariable; + this.parentConfiguration = parentConfiguration; + } + + public Resource getParent() { + return moduleInstance; + } + + public Resource getVariableResource() { + return variableResource; + } + + public IndependentVariable getIndependentVariable() { + return independentVariable; + } + + public Configuration getParentConfiguration() { + return parentConfiguration; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorter.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorter.java new file mode 100644 index 00000000..802e193d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorter.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import java.util.Map; + +import org.simantics.browsing.ui.NodeContext; +import org.simantics.browsing.ui.model.browsecontexts.BrowseContext; +import org.simantics.browsing.ui.model.sorters.AbstractSorter; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys; +import org.simantics.utils.strings.AlphanumComparator; + +/** + * Sorter for sorting module parameters into alphabetic order. + * + * @author Teemu Lempinen + * + */ +public class ParameterSorter extends AbstractSorter { + + public static ParameterSorter INSTANCE = new ParameterSorter(); + + @Override + public String getSortingCriterion(ReadGraph graph, BrowseContext context, + NodeContext node) throws DatabaseException { + Map labels = context.getLabel(graph, node); + String label = labels.get(ColumnKeys.MODULE_PARAMETER); + return label; + } + + @Override + public int compare(String a, String b) { + return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(a, b); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorterRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorterRule.java new file mode 100644 index 00000000..20db86bd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorterRule.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import org.simantics.browsing.ui.model.sorters.Sorter; +import org.simantics.browsing.ui.model.sorters.SorterRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; + +/** + * SorterRule for sorting module parameters into alphabetic order. + * @author Teemu Lempinen + * + */ +public class ParameterSorterRule implements SorterRule { + + @Override + public boolean isCompatible(Class contentType) { + return true; + } + + @Override + public Sorter getSorter(ReadGraph graph, Object content) + throws DatabaseException { + return ParameterSorter.INSTANCE; + } +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRow.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRow.java new file mode 100644 index 00000000..e6685123 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRow.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; + +public class ReferenceRow { + + Resource variable, module, dependency; + String name; + + public ReferenceRow(Resource module, Resource dependency, Resource variable) { + this.module = module; + this.variable = variable; + this.dependency = dependency; + } + + + public Resource getModule() { + return this.module; + } + + public Resource getVariable() { + return this.variable; + } + + public Resource getDependency() { + return this.dependency; + } + + public String getName() { + String name = null; + try { + name = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + return (String)graph.getRelatedValue(getVariable(), Layer0.getInstance(graph).HasName); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return name; + } + + public String getValue() { + if(dependency == null) return ""; + + String value = null; + try { + value = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Resource valueResource = graph.getPossibleObject(dependency, sr.Variable_HasTail); + if(!graph.isInstanceOf(valueResource, sr.Variable)) + valueResource = graph.getPossibleObject(dependency, sr.Variable_HasHead); + + if(graph.isInstanceOf(valueResource, sr.Shadow)) + valueResource = graph.getPossibleObject(valueResource, sr.Shadow_original); + + if(valueResource == null || !graph.isInstanceOf(valueResource, sr.Variable)) + return ""; + + return (String)graph.getRelatedValue(valueResource, l0.HasName, Bindings.STRING); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return value; + } + + public void setRefersTo(final Resource dependency) { + if(dependency != null && dependency.equals(this.dependency)) return; + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + if(getDependency() != null && graph.hasStatement(getDependency(), sr.Dependency_refersTo)) + graph.deny(getDependency(), sr.Dependency_refersTo); + if(dependency != null && graph.hasStatement(dependency, sr.Dependency_refersTo)) + graph.deny(dependency, sr.Dependency_refersTo); + setDependency(null); + if(dependency != null) { + setDependency(dependency); + graph.claim(getDependency(), SysdynResource.getInstance(graph).Dependency_refersTo, getVariable()); + } + } + }); + } + + private void setDependency(Resource dependency) { + this.dependency = dependency; + } +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRowLabelProvider.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRowLabelProvider.java new file mode 100644 index 00000000..763e8411 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRowLabelProvider.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +public class ReferenceRowLabelProvider extends LabelProvider implements ITableLabelProvider { + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + ReferenceRow referenceRow = (ReferenceRow) element; + switch (columnIndex) { + case 0: + return referenceRow.getName(); + case 1: + return referenceRow.getValue(); + default: + throw new RuntimeException("Should not happen"); + } + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceTable.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceTable.java new file mode 100644 index 00000000..aeb5dafd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceTable.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import java.util.ArrayList; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ISelectionUtils; + +public class ReferenceTable implements Widget{ + + private TableViewer tableViewer; + private RowProvider rowProvider; + + public static final String FIRSTCOLUMN = "Inputs"; + public static final String SECONDCOLUMN = "Outputs"; + + public ReferenceTable(Composite parent, WidgetSupport support, int style) { + support.register(this); + + Composite base = new Composite(parent, style); + GridLayoutFactory.fillDefaults().applyTo(base); + GridDataFactory.fillDefaults().grab(true, true).applyTo(base); + + Table table = new Table(base, SWT.BORDER|SWT.SINGLE|SWT.FULL_SELECTION); + GridDataFactory.fillDefaults().grab(true, true).applyTo(table); + table.setHeaderVisible (true); + table.setLinesVisible(true); + table.getVerticalBar().setVisible(true); + + tableViewer = new TableViewer (table); + tableViewer.setComparator(new ReferenceRowComparator()); + } + + public TableViewer getTableViewer() { + return this.tableViewer; + } + + public void setRowProvider(RowProvider rowProvider) { + this.rowProvider = rowProvider; + } + + public void setContentProvider(IContentProvider provider) { + tableViewer.setContentProvider(provider); + } + + public void setLabelProvider(IBaseLabelProvider labelProvider) { + tableViewer.setLabelProvider(labelProvider); + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource module = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class); + if(this.rowProvider != null) { + try { + SimanticsUI.getSession().syncRequest(new Read>() { + + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + return rowProvider.getRows(graph, module); + } + } , new Listener>() { + + @Override + public boolean isDisposed() { + if(tableViewer != null && tableViewer.getTable() != null) + return getTableViewer().getTable().isDisposed(); + else + return true; + } + + @Override + public void execute(final ArrayList result) { + if(!isDisposed()) + getTableViewer().getTable().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + if(!isDisposed()) + getTableViewer().setInput(result); + } + }); + } + + @Override + public void exception(Throwable t) { + } + } + ); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + } + + private class ReferenceRowComparator extends ViewerComparator { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + ReferenceRow rr1 = (ReferenceRow)e1; + ReferenceRow rr2 = (ReferenceRow)e2; + return rr1.getName().compareTo(rr2.getName()); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/RowProvider.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/RowProvider.java new file mode 100644 index 00000000..9b424d26 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/RowProvider.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.modules; + +import java.util.ArrayList; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; + +public abstract class RowProvider { + public abstract ArrayList getRows(ReadGraph graph, Resource module) throws DatabaseException; +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/DistributionPropertyWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/DistributionPropertyWidget.java new file mode 100644 index 00000000..93a62b2d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/DistributionPropertyWidget.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +import java.util.HashMap; + +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +public class DistributionPropertyWidget extends Composite implements Widget { + + private IDistributionProperties distributionProperties = null; + private WidgetSupportImpl distributionSupport = new WidgetSupportImpl(); + private HashMap cache = new HashMap(); + private Resource oldInput; + + public DistributionPropertyWidget(Composite parent, ISessionContext context, WidgetSupport support, int style) { + super(parent, style); + GridLayoutFactory.fillDefaults().applyTo(this); + support.register(this); + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class); + if(resource == null) + return; + + IDistributionProperties newProperties = null; + Resource distribution = null; + try { + distribution = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + Resource distribution = graph.getPossibleObject( + resource, + SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_propabilityDistribution + ); + + return distribution; + } + + }); + + newProperties = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public IDistributionProperties perform(ReadGraph graph) throws DatabaseException { + Resource distribution = graph.getPossibleObject( + resource, + SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_propabilityDistribution + ); + + return graph.adapt(distribution, IDistributionProperties.class); + } + + }); + + // Create a PropertyComposite for the selected node + if(newProperties != null) { + + if(distributionProperties != null) + distributionProperties.getCachedValues(cache); + + if(oldInput != null && !oldInput.equals(resource)) + cache.clear(); + + oldInput = resource; + + for(Control child : this.getChildren()) { + child.dispose(); + } + + newProperties.createContent(this, context, distributionSupport); + distributionProperties = newProperties; + + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + distributionProperties.applyCache(graph, cache); + + } + }); + + distributionSupport.fireInput(context, new StructuredSelection(distribution)); + } + + } catch (DatabaseException e) { + e.printStackTrace(); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IDistributionProperties.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IDistributionProperties.java new file mode 100644 index 00000000..0c628e95 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IDistributionProperties.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +import java.util.HashMap; + +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; + +public interface IDistributionProperties { + + public Composite createContent(Composite parent, ISessionContext context, WidgetSupport support); + + public void getCachedValues(HashMap cachedValues); + + public void applyCache(WriteGraph graph, HashMap cachedValues) throws DatabaseException; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IntervalProperties.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IntervalProperties.java new file mode 100644 index 00000000..9f3b7bc4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IntervalProperties.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +import java.util.HashMap; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; + +public class IntervalProperties implements IDistributionProperties { + + private Resource resource; + private TrackedText minValue; + private TrackedText maxValue; + + public IntervalProperties(Resource resource) { + this.resource = resource; + } + + @Override + public Composite createContent(Composite parent, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); + + // minValue + Label label = new Label(composite, SWT.NONE); + label.setText("Min value"); + GridDataFactory.fillDefaults().applyTo(label); + + minValue = new TrackedText(composite, support, SWT.BORDER); + minValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.Interval_minValue)); + minValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.Interval_minValue)); + minValue.setInputValidator(new DoubleValidator(false)); + minValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), minValue.getWidget()))); + GridDataFactory.fillDefaults().grab(true, false).applyTo(minValue.getWidget()); + + // maxValue + label = new Label(composite, SWT.NONE); + label.setText("Max value"); + GridDataFactory.fillDefaults().applyTo(label); + + maxValue = new TrackedText(composite, support, SWT.BORDER); + maxValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.Interval_maxValue)); + maxValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.Interval_maxValue)); + maxValue.setInputValidator(new DoubleValidator(false)); + maxValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), maxValue.getWidget()))); + GridDataFactory.fillDefaults().grab(true, false).applyTo(maxValue.getWidget()); + + return composite; + } + + + @Override + public void getCachedValues(HashMap cahcedValues) { + if(!minValue.isDisposed()) + cahcedValues.put(SensitivityDistributionKeys.MIN, minValue.getText()); + if(!maxValue.isDisposed()) + cahcedValues.put(SensitivityDistributionKeys.MAX, maxValue.getText()); + } + + + + @Override + public void applyCache(WriteGraph graph, HashMap cachedValues) throws DatabaseException { + if(resource == null) + return; + + SysdynResource SR = SysdynResource.getInstance(graph); + + String min = cachedValues.get(SensitivityDistributionKeys.MIN); + if(min != null) { + try { + Double d = Double.parseDouble(min); + graph.claimLiteral(resource, SR.Interval_minValue, d, Bindings.DOUBLE); + } catch (NumberFormatException e) {} + } + + String max = cachedValues.get(SensitivityDistributionKeys.MAX); + if(max != null) { + try { + Double d = Double.parseDouble(max); + graph.claimLiteral(resource, SR.Interval_maxValue, d, Bindings.DOUBLE); + } catch (NumberFormatException e) {} + } + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/NormalDistributionProperties.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/NormalDistributionProperties.java new file mode 100644 index 00000000..ccb5fb2a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/NormalDistributionProperties.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +import java.util.HashMap; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; + +public class NormalDistributionProperties implements IDistributionProperties { + + private TrackedText minValue; + private TrackedText maxValue; + private TrackedText mean; + private TrackedText stdDeviation; + private Resource resource; + + public NormalDistributionProperties(Resource resource) { + this.resource = resource; + } + + @Override + public Composite createContent(Composite parent, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(4).applyTo(composite); + + // mean + Label label = new Label(composite, SWT.NONE); + label.setText("Mean (\u03BC)"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + mean = new TrackedText(composite, support, SWT.BORDER); + mean.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.NormalDistribution_mean)); + mean.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.NormalDistribution_mean)); + mean.setInputValidator(new DoubleValidator(true)); + mean.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), mean.getWidget()))); + GridDataFactory.fillDefaults().grab(true, false).applyTo(mean.getWidget()); + + // minValue + label = new Label(composite, SWT.NONE); + label.setText("Min value"); + GridDataFactory.fillDefaults().indent(15, 0).align(SWT.END, SWT.CENTER).applyTo(label); + + minValue = new TrackedText(composite, support, SWT.BORDER); + minValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.NormalDistribution_minValue)); + minValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.NormalDistribution_minValue)); + minValue.setInputValidator(new DoubleValidator(true)); + minValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), minValue.getWidget()))); + GridDataFactory.fillDefaults().grab(true, false).applyTo(minValue.getWidget()); + + // stdDeviation + label = new Label(composite, SWT.NONE); + label.setText("Standard deviation (\u03C3)"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + stdDeviation = new TrackedText(composite, support, SWT.BORDER); + stdDeviation.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.NormalDistribution_stdDeviation)); + stdDeviation.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.NormalDistribution_stdDeviation)); + stdDeviation.setInputValidator(new DoubleValidator(true)); + stdDeviation.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), stdDeviation.getWidget()))); + GridDataFactory.fillDefaults().grab(true, false).applyTo(stdDeviation.getWidget()); + + // maxValue + label = new Label(composite, SWT.NONE); + label.setText("Max value"); + GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label); + + maxValue = new TrackedText(composite, support, SWT.BORDER); + maxValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.NormalDistribution_maxValue)); + maxValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.NormalDistribution_maxValue)); + maxValue.setInputValidator(new DoubleValidator(true)); + maxValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), maxValue.getWidget()))); + GridDataFactory.fillDefaults().grab(true, false).applyTo(maxValue.getWidget()); + + return composite; + } + + @Override + public void getCachedValues(HashMap cahcedValues) { + if(!minValue.isDisposed()) + cahcedValues.put(SensitivityDistributionKeys.MIN, minValue.getText()); + if(!maxValue.isDisposed()) + cahcedValues.put(SensitivityDistributionKeys.MAX, maxValue.getText()); + if(!mean.isDisposed()) + cahcedValues.put(SensitivityDistributionKeys.MEAN, mean.getText()); + if(!stdDeviation.isDisposed()) + cahcedValues.put(SensitivityDistributionKeys.STD_DEVIATION, stdDeviation.getText()); + } + + + + @Override + public void applyCache(WriteGraph graph, HashMap cachedValues) throws DatabaseException { + if(resource == null) + return; + + SysdynResource SR = SysdynResource.getInstance(graph); + + String min = cachedValues.get(SensitivityDistributionKeys.MIN); + if(min != null) { + try { + Double d = Double.parseDouble(min); + graph.claimLiteral(resource, SR.NormalDistribution_minValue, d, Bindings.DOUBLE); + } catch (NumberFormatException e) {} + } + + String max = cachedValues.get(SensitivityDistributionKeys.MAX); + if(max != null) { + try { + Double d = Double.parseDouble(max); + graph.claimLiteral(resource, SR.NormalDistribution_maxValue, d, Bindings.DOUBLE); + } catch (NumberFormatException e) {} + } + + String mean = cachedValues.get(SensitivityDistributionKeys.MEAN); + if(mean != null) { + try { + Double d = Double.parseDouble(mean); + graph.claimLiteral(resource, SR.NormalDistribution_mean, d, Bindings.DOUBLE); + } catch (NumberFormatException e) {} + } + + String stdDeviation = cachedValues.get(SensitivityDistributionKeys.STD_DEVIATION); + if(stdDeviation != null) { + try { + Double d = Double.parseDouble(stdDeviation); + graph.claimLiteral(resource, SR.NormalDistribution_stdDeviation, d, Bindings.DOUBLE); + } catch (NumberFormatException e) {} + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterChildRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterChildRule.java new file mode 100644 index 00000000..30274d60 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterChildRule.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +import java.util.Collection; +import java.util.Collections; + +import org.simantics.browsing.ui.model.children.ChildRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; + +public class ParameterChildRule implements ChildRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Collection getChildren(ReadGraph graph, Object parent) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + + Resource experiment = (Resource) parent; + Resource parameterList = graph.getPossibleObject(experiment, SR.SensitivityAnalysisExperiment_parameterList); + + if(parameterList != null) + return ListUtils.toList(graph, parameterList); + else + return Collections.emptyList(); + } + + @Override + public Collection getParents(ReadGraph graph, Object child) throws DatabaseException { + return Collections.emptyList(); + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterLabelRule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterLabelRule.java new file mode 100644 index 00000000..fd67dc8b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterLabelRule.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +import java.util.HashMap; +import java.util.Map; + +import org.simantics.browsing.ui.common.ColumnKeys; +import org.simantics.browsing.ui.model.labels.LabelRule; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; + +public class ParameterLabelRule implements LabelRule { + + @Override + public boolean isCompatible(Class contentType) { + return contentType.equals(Resource.class); + } + + @Override + public Map getLabel(ReadGraph graph, Object content) throws DatabaseException { + HashMap result = new HashMap(); + + String variable = graph.getPossibleRelatedValue((Resource)content, SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_variable); + + StringBuilder sb = new StringBuilder(); + + if(variable != null) + sb.append(variable); + else + sb.append("No variable"); + + result.put(ColumnKeys.SINGLE, sb.toString()) ; + + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterProposalProvider.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterProposalProvider.java new file mode 100644 index 00000000..84b0c212 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterProposalProvider.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +public class ParameterProposalProvider { + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityDistributionKeys.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityDistributionKeys.java new file mode 100644 index 00000000..d1019b2c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityDistributionKeys.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +public class SensitivityDistributionKeys { + + public static String MAX = "MAX"; + public static String MIN = "MIN"; + public static String STD_DEVIATION = "STD_DEVIATION"; + public static String MEAN = "MEAN"; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityRangeHandlerFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityRangeHandlerFactory.java new file mode 100644 index 00000000..aca7931c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityRangeHandlerFactory.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +import java.util.Map; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.trend.SysdynRangeHandlerFactory; + +public class SensitivityRangeHandlerFactory extends SysdynRangeHandlerFactory { + + @Override + protected Resource getRVIRelation(ReadGraph graph) { + return SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_variable; + } + + @Override + public ReadFactoryImpl> getRangeItemFactory(int index, Resource res) { + return new RangeItemFactory(index, res, false); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/UniformDistributionProperties.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/UniformDistributionProperties.java new file mode 100644 index 00000000..2b78a9db --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/UniformDistributionProperties.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +import java.util.HashMap; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.properties.DoubleValidator; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; + +public class UniformDistributionProperties implements IDistributionProperties{ + + private TrackedText minValue; + private TrackedText maxValue; + private Resource resource; + + public UniformDistributionProperties(Resource resource) { + this.resource = resource; + } + + @Override + public Composite createContent(Composite parent, ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); + + // minValue + Label label = new Label(composite, SWT.NONE); + label.setText("Min value"); + GridDataFactory.fillDefaults().applyTo(label); + + minValue = new TrackedText(composite, support, SWT.BORDER); + minValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.UniformDistribution_minValue)); + minValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.UniformDistribution_minValue)); + minValue.setInputValidator(new DoubleValidator(false)); + minValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), minValue.getWidget()))); + GridDataFactory.fillDefaults().grab(true, false).applyTo(minValue.getWidget()); + + // maxValue + label = new Label(composite, SWT.NONE); + label.setText("Max value"); + GridDataFactory.fillDefaults().applyTo(label); + + maxValue = new TrackedText(composite, support, SWT.BORDER); + maxValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.UniformDistribution_maxValue)); + maxValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.UniformDistribution_maxValue)); + maxValue.setInputValidator(new DoubleValidator(false)); + maxValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), maxValue.getWidget()))); + GridDataFactory.fillDefaults().grab(true, false).applyTo(maxValue.getWidget()); + + return composite; + } + + @Override + public void getCachedValues(HashMap cahcedValues) { + cahcedValues.put(SensitivityDistributionKeys.MIN, minValue.getText()); + cahcedValues.put(SensitivityDistributionKeys.MAX, maxValue.getText()); + } + + + + @Override + public void applyCache(WriteGraph graph, HashMap cachedValues) throws DatabaseException { + if(resource == null) + return; + + SysdynResource SR = SysdynResource.getInstance(graph); + + String min = cachedValues.get(SensitivityDistributionKeys.MIN); + if(min != null) { + try { + Double d = Double.parseDouble(min); + graph.claimLiteral(resource, SR.UniformDistribution_minValue, d, Bindings.DOUBLE); + } catch (NumberFormatException e) {} + } + + String max = cachedValues.get(SensitivityDistributionKeys.MAX); + if(max != null) { + try { + Double d = Double.parseDouble(max); + graph.claimLiteral(resource, SR.UniformDistribution_maxValue, d, Bindings.DOUBLE); + } catch (NumberFormatException e) {} + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/VariableNameModifier.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/VariableNameModifier.java new file mode 100644 index 00000000..eaac45db --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/VariableNameModifier.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.properties.widgets.sensitivity; + +import org.eclipse.jface.bindings.keys.KeyStroke; +import org.eclipse.jface.bindings.keys.ParseException; +import org.eclipse.jface.fieldassist.ContentProposalAdapter; +import org.eclipse.jface.fieldassist.IContentProposal; +import org.eclipse.jface.fieldassist.IContentProposalListener; +import org.eclipse.jface.fieldassist.IContentProposalListener2; +import org.eclipse.jface.fieldassist.TextContentAdapter; +import org.eclipse.swt.widgets.Control; +import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.jfreechart.chart.properties.VariableProposalProvider; + +public class VariableNameModifier extends TextModifyListenerImpl { + + private boolean active; + private Control control; + private String variableNameRelationUri; + private String indexUri; + + private char[] alphaNumericCharacters = { + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','å','ä','ö', + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Å','Ä','Ö', + '1','2','3','4','5','6','7','8','9','0','.'}; + + + public VariableNameModifier(Control control, WidgetSupport support, String variableNameRelationUri, String indexUri) { + this.variableNameRelationUri = variableNameRelationUri; + this.indexUri = indexUri; + + this.control = control; + this.active = true; + + KeyStroke keyStroke = null; + try { + keyStroke = KeyStroke.getInstance("Ctrl+Space"); + } catch (ParseException e1) { + e1.printStackTrace(); + } + + //SimpleContentProposalProvider scpp = new VariableProposalProvider(control, support); + VariableProposalProvider scpp = new VariableProposalProvider(control, support); + scpp.setFiltering(true); + + ContentProposalAdapter adapter = new ContentProposalAdapter( + control, new TextContentAdapter(), scpp, keyStroke, alphaNumericCharacters); + adapter.setAutoActivationDelay(0); + adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); + adapter.addContentProposalListener(new IContentProposalListener2() { + + @Override + public void proposalPopupOpened(ContentProposalAdapter adapter) { + if(VariableNameModifier.this != null) + VariableNameModifier.this.deactivate(); + } + + @Override + public void proposalPopupClosed(ContentProposalAdapter adapter) { + if(VariableNameModifier.this != null) + VariableNameModifier.this.activate(); + } + }); + + adapter.addContentProposalListener(new IContentProposalListener() { + + @Override + public void proposalAccepted(IContentProposal proposal) { + if(VariableNameModifier.this.control != null && !VariableNameModifier.this.control.isDisposed()) + VariableNameModifier.this.modifyText(new TrackedModifyEvent(VariableNameModifier.this.control, proposal.getContent())); + } + }); + + + } + + + @Override + public void applyText(WriteGraph graph, Resource resource, String text) throws DatabaseException { + if(active) { + graph.claimLiteral(resource, getVariableNameRelation(graph), text, Bindings.STRING); + graph.deny(resource, getIndexRelation(graph)); + } else { + System.out.println("NÄHÄÄ"); + } + } + + private Resource getVariableNameRelation(ReadGraph graph) throws DatabaseException { + return graph.getResource(variableNameRelationUri); + } + + private Resource getIndexRelation(ReadGraph graph) throws DatabaseException { + return graph.getResource(indexUri); + } + + public void deactivate() { + active = false; + } + + public void activate() { + active = true; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Dependencies.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Dependencies.java new file mode 100644 index 00000000..02e052d8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Dependencies.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.structure; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Spinner; +import org.simantics.db.Resource; +import org.simantics.ui.SimanticsUI; + +public class Dependencies extends StructureTabItem { + + private boolean isInverted = false; + private Button bButton, fButton; + private int levels = 3; + + private static int MAXLEVELS = 4; + private static int MINLEVELS = 1; + + public Dependencies(CTabFolder parent, int style) { + super(parent, style); + + Label line = new Label(structureComposite, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL); + GridDataFactory.fillDefaults().grab(true, false).applyTo(line); + + Composite composite = new Composite(structureComposite, SWT.NONE); + RowLayout layout = new RowLayout(); + layout.center = true; + composite.setLayout(layout); + + Label label = new Label(composite, SWT.NONE); + label.setText("Direction: "); + + bButton = new Button(composite, SWT.RADIO); + bButton.setText("Backward"); + bButton.setSelection(true); + bButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + if(bButton.getSelection()) + isInverted = false; + else + isInverted = true; + if(currentSelection != null) { + readGraph(currentSelection); + } + } + }); + + fButton = new Button(composite, SWT.RADIO); + fButton.setText("Forward"); + + label = new Label(composite, SWT.NONE); + label.setText("Steps: "); + + Spinner spinner = new Spinner(composite, SWT.BORDER); + spinner.setMaximum(MAXLEVELS); + spinner.setMinimum(MINLEVELS); + spinner.setTextLimit(1); + spinner.setSelection(levels); + + spinner.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + Spinner s = (Spinner)e.widget; + int lvls = Integer.parseInt(s.getText()); + if(lvls > MAXLEVELS) + levels = MAXLEVELS; + else if (lvls < MINLEVELS) + levels = MINLEVELS; + levels = lvls; + if(currentSelection != null) { + readGraph(currentSelection); + } + + } + }); + + this.setText("Dependencies"); + this.setControl(structureComposite); + } + + protected void readGraph(Resource resource) { + if(graphListener != null) + graphListener.dispose(); + + graphListener = new GraphListener(); + SimanticsUI.getSession().asyncRequest(new DependencyGraphRequest( + resource, levels, isInverted), graphListener); + } + + protected String getJobLabel() { + return "Loading dependencies graph"; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/DependencyGraphRequest.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/DependencyGraphRequest.java new file mode 100644 index 00000000..29075591 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/DependencyGraphRequest.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.structure; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.graphviz.Edge; +import org.simantics.graphviz.Graph; +import org.simantics.graphviz.IGraph; +import org.simantics.graphviz.Node; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; + +/** + * Builds a graph of the dependencies of a selected variable + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class DependencyGraphRequest implements Read { + + protected Resource root; + protected HashMap nodes; + protected boolean isInverted; + protected int levels; + + /** + * Builds a graph of the dependencies of a selected variable + * + * @param root Variable from which to find dependencies + * @param levels How many steps of dependencies are calculated from the variable + * @param isInverted true => variables that affect root; false => variables that are affected by root + */ + public DependencyGraphRequest(Resource root, int levels, boolean isInverted) { + this.root = root; + this.isInverted = isInverted; + this.levels = levels; + } + + @Override + public Graph perform(ReadGraph g) throws DatabaseException { + + nodes = new HashMap(); + Graph graph = new Graph(); + graph.setRankdir("LR"); + ModelingResources mr = ModelingResources.getInstance(g); + Resource element = g.getPossibleObject(root, mr.ElementToComponent); + if (element != null) { + root = element; + } + SysdynResource sr = SysdynResource.getInstance(g); + if (g.isInstanceOf(root, sr.IndependentVariable) || g.isInstanceOf(root, sr.Input)) { + setRoot(g, graph, root); + Collection resources = new ArrayList(); + resources.add(root); + for (int i = 0; i < levels && !resources.isEmpty(); i++) { + Collection newResources = new ArrayList(); + for(Resource r : resources) { + newResources.addAll(setDependencies(g, graph, r)); + } + resources = new ArrayList(newResources); + } + } + return graph; + } + + /** + * Create a root node and set appearance settings for it + * @param g ReadGraph + * @param graph Graphviz graph + * @param root Root resource + * @throws DatabaseException + */ + protected void setRoot(ReadGraph g, IGraph graph, Resource root) throws DatabaseException { + Node n; + n = new Node(graph, getName(g, root)); + setShape(g, root, n); + n.set("style", "filled"); + n.setFillColor("#d3d3d3"); + nodes.put(root, n); + } + + + /** + * Call for calculating + * @param g + * @param graph + * @param r + * @param toDependency + * @param fromDependency + * @param connectionType + * @return + * @throws DatabaseException + */ + private Collection getDependants(ReadGraph g, IGraph graph, Resource r, Resource toDependency, Resource fromDependency, Resource connectionType) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + + Collection dependencies = g.syncRequest(new ObjectsWithType(r, toDependency, connectionType)); + + Collection dependants = new ArrayList(); + Node n; + for(Resource d : dependencies) { + Resource dependant = g.getPossibleObject(d, fromDependency); + if(dependant == null) + continue; + if(g.isInstanceOf(dependant, sr.Cloud)) { + break; + } + if( !nodes.containsKey(dependant)) { + n= new Node(graph, getName(g, dependant)); + setShape(g, dependant, n); + nodes.put(dependant, n); + dependants.add(dependant); + } + + if(isInverted) { + new Edge(graph, nodes.get(r), nodes.get(dependant)); + } else { + new Edge(graph, nodes.get(dependant), nodes.get(r)); + } + } + return dependants; + } + + private Collection setDependencies(ReadGraph g, IGraph graph, Resource r) throws DatabaseException{ + SysdynResource sr = SysdynResource.getInstance(g); + + // stop here if element is a module + if (g.isInstanceOf(r, sr.Module)) + return Collections.emptyList(); + + Collection dependants; + if(isInverted) { + dependants = getDependants(g, graph, r, sr.Variable_isTailOf, sr.Variable_HasHead, sr.Dependency); + if (g.isInstanceOf(r, sr.Valve)) { + dependants.addAll(getDependants(g, graph, r, sr.Variable_isTailOf, sr.Variable_HasHead, sr.Flow)); + dependants.addAll(getDependants(g, graph, r, sr.Variable_isHeadOf, sr.Variable_HasTail, sr.Flow)); + } + } else { + dependants = getDependants(g, graph, r, sr.Variable_isHeadOf, sr.Variable_HasTail, sr.Dependency); + if (g.isInstanceOf(r, sr.Stock)) { + dependants.addAll(getDependants(g, graph, r, sr.Variable_isTailOf, sr.Variable_HasHead, sr.Flow)); + dependants.addAll(getDependants(g, graph, r, sr.Variable_isHeadOf, sr.Variable_HasTail, sr.Flow)); + } + } + + return dependants; + } + + /** + * Set shape for a node. Rectangle for stocks, ellipse for auxiliaries and rounded rectangle for modules. + * @param g ReadGraph + * @param r Resource + * @param n Node + * @throws DatabaseException + */ + protected void setShape(ReadGraph g, Resource r, Node n) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + if(g.isInstanceOf(r, sr.Stock)) + n.setShape("rectangle"); + else if(g.isInstanceOf(r, sr.Module)) { + n.setShape("rectangle"); + n.setStyle("rounded"); + } + else + n.setShape("ellipse"); + } + + protected String getName(ReadGraph g, Resource r) throws DatabaseException { + return (String)g.getRelatedValue(r, Layer0.getInstance(g).HasName); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/LoopGraphRequest.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/LoopGraphRequest.java new file mode 100644 index 00000000..6063be5c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/LoopGraphRequest.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.structure; + +import java.util.HashMap; +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.graphviz.Edge; +import org.simantics.graphviz.Graph; +import org.simantics.graphviz.IGraph; +import org.simantics.graphviz.Node; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.utils.LoopUtils; +import org.simantics.utils.datastructures.MapList; + +/** + * Builds a graph of the loops of a selected variable + * + * @author Tuomas Miettinen + * @author Teemu Lempinen + * + */ +public class LoopGraphRequest extends DependencyGraphRequest { + + MapList edges; + + /** + * Builds a graph of the dependencies of a selected variable + * + * @param root Variable from which to find dependencies + * @param levels How many steps of dependencies are calculated from the variable + * @param isInverted true => variables that affect root; false => variables that are affected by root + */ + public LoopGraphRequest(Resource root) { + super(root, 999, false); + } + + @Override + public Graph perform(ReadGraph g) throws DatabaseException { + + nodes = new HashMap(); + Graph graph = new Graph(); + graph.setRankdir("LR"); + ModelingResources mr = ModelingResources.getInstance(g); + Resource element = g.getPossibleObject(root, mr.ElementToComponent); + if (element != null) { + root = element; + } + SysdynResource sr = SysdynResource.getInstance(g); + if (g.isInstanceOf(root, sr.IndependentVariable) || g.isInstanceOf(root, sr.Input)) { + // Get ALL loops in the diagram in which the root exists. + List> loops = LoopUtils.getLoops(g, root); + setRoot(g, graph, root); + + // Add the edges to the graph. + edges = new MapList(); + for (List loop : loops) { + Resource prev = null; + for (Resource r : loop) { + // Add node if not already added. + if(!nodes.containsKey(r)) { + Node n = new Node(graph, getName(g, r)); + setShape(g, r, n); + nodes.put(r, n); + } + // Add edge if not already added. + if (prev != null) + claimEdge(g, graph, prev, r); + + prev = r; + } + // Add edge between the last and first node in the loop. + if (prev != null && loop.get(0) != null) + claimEdge(g, graph, prev, loop.get(0)); + } + } + return graph; + } + + /** + * Create and edge between _tail and _head nodes. If the edge already exists, do nothing. + * If an opposite direction edge exists, draw an arrow also to the tail of the edge. + * @param g + * @param graph Graph in which the nodes lie. + * @param tail The tail node. + * @param head The head node. + * @throws DatabaseException + */ + private void claimEdge(ReadGraph g, IGraph graph, Resource tail, Resource head) throws DatabaseException { + // If edge exists, increase the size of the arrowhead and return. + for (Edge e : edges.getValues(tail)) { + if (((Node)e.getHead()).get("label").equals(getName(g, head))) { + // Change the size of the arrowhead (fancily :-) + String arrowsize = e.get("arrowsize"); + if (arrowsize == null) + arrowsize = "1.0"; + e.setArrowsize(Math.min(2.2, Math.sqrt(Double.valueOf(arrowsize) + 0.8))); + return; + } + } + + for (Edge e : edges.getValues(head)) { // Seek for opposite edges + if (((Node)e.getHead()).get("label").equals(getName(g, tail))) { + e.setDir("both"); + return; + } + } + + // If no edge has been found, add one. + edges.add(tail, new Edge(graph, nodes.get(tail), nodes.get(head))); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Loops.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Loops.java new file mode 100644 index 00000000..798b5043 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Loops.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.structure; + +import org.eclipse.swt.custom.CTabFolder; +import org.simantics.db.Resource; +import org.simantics.ui.SimanticsUI; + +/** + * Tab for loops. + * @author Tuomas Miettinen + * + */ +public class Loops extends StructureTabItem { + + public Loops(CTabFolder parent, int style) { + super(parent, style); + this.setText("Loops"); + this.setControl(structureComposite); + } + + protected void readGraph(Resource resource) { + if(graphListener != null) + graphListener.dispose(); + + graphListener = new GraphListener(); + SimanticsUI.getSession().asyncRequest(new LoopGraphRequest( + resource), graphListener); + } + + protected String getJobLabel() { + return "Loading loops graph"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructure.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructure.java new file mode 100644 index 00000000..c3b27997 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructure.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.structure; + +import java.util.Set; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.widgets.Composite; +import org.simantics.db.Resource; +import org.simantics.db.procedure.Listener; +import org.simantics.graphviz.Graph; +import org.simantics.graphviz.ui.GraphvizComponent; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.RunnableWithObject; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Tab for displaying hierarchical model structure + * + * @author Teemu Lempinen + * + */ +public class ModuleStructure extends CTabItem { + + private GraphvizComponent component; + private GraphListener graphListener; + + + public ModuleStructure(CTabFolder parent, int style) { + super(parent, style); + + Composite moduleStructure = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(moduleStructure); + GridLayoutFactory.fillDefaults().applyTo(moduleStructure); + + component = new GraphvizComponent(moduleStructure, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(component); + + this.setText("Model Hierarchy"); + this.setControl(moduleStructure); + + } + + /** + * Draw a graph about the model of the selected resource + * @param selection + */ + public void drawSelection(ISelection selection) { + if(selection == null || selection.isEmpty()) + return; + + if(selection instanceof IStructuredSelection) { + Object[] els = ((IStructuredSelection) selection).toArray(); + if(els.length == 1) { + Set ress = ISelectionUtils.filterSetSelection(selection, Resource.class); + if(ress.isEmpty()) return; + Resource r = (ress.toArray(Resource.NONE))[0]; + if(r != null) { + // Read graph for the resource + if(graphListener != null) + graphListener.dispose(); // Dispose possible previous listener + + graphListener = new GraphListener(); + SimanticsUI.getSession().asyncRequest(new ModuleStructureGraphRequest(r), graphListener); + } + } + } + } + + /** + * Listener for updating hierarchical model graph + * @author Teemu Lempinen + * + */ + private class GraphListener implements Listener { + private boolean disposed = false; + + public void dispose() { + disposed = true; + } + + @Override + public void exception(Throwable e) { + e.printStackTrace(); + } + + @Override + public void execute(final Graph graph) { + Job job = new Job("Loading model structure graph") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + if(!isDisposed()) { + component.getDisplay().asyncExec(new RunnableWithObject(graph) { + + @Override + public void run() { + if (component.isDisposed()) return; + component.setGraph((Graph)getObject(), "dot"); + component.fit(); + } + }); + + } + return Status.OK_STATUS; + } + }; + job.schedule(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructureGraphRequest.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructureGraphRequest.java new file mode 100644 index 00000000..c32a3004 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructureGraphRequest.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.structure; + +import java.util.HashMap; +import java.util.HashSet; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.graphviz.Edge; +import org.simantics.graphviz.Graph; +import org.simantics.graphviz.Node; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; + +/** + * Builds a graph about the modular structure of the model where a selected object is located. + * + * @author Teemu Lempinen + * + */ +public class ModuleStructureGraphRequest implements Read { + + private Resource resource; + + /** + * Request a hierarchical graph about the model of resource + * @param resource + */ + public ModuleStructureGraphRequest(Resource resource) { + this.resource = resource; + } + + @Override + public Graph perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Graph g = new Graph(); + g.setRankdir("TB"); + + // Find model resource, the root of this + Resource model = resource; + while(model != null && !graph.isInstanceOf(model, sr.SysdynModel)) { + model = graph.getPossibleObject(model, l0.PartOf); + } + + // Model root was not found, return empty graph + if(model == null) + return g; + + // Find the parent module/model of the selected resource + Resource parentResource = graph.getPossibleObject(resource, l0.PartOf); + if(graph.isInstanceOf(parentResource, sr.ConfigurationDiagram)) { + parentResource = graph.getPossibleObject(parentResource, ModelingResources.getInstance(graph).DiagramToComposite); + } else if(graph.isInstanceOf(parentResource, sr.SysdynModel)) { + parentResource = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration); + } + + // Set root node + Node rootNode = new Node(g, NameUtils.getSafeLabel(graph, model)); + rootNode.setShape("rectangle"); + HashSet visited = new HashSet(); + visited.add(model); + findChildModules(g, rootNode, graph, model, parentResource, visited); + + + return g; + } + + /** + * Recursive call for finding child modules + * @param g GraphViz graph + * @param parent Parent module or model + * @param graph ReadGraph + * @param resource Module type or model + * @param parent2 + * @param visited All visited modules. Needed to check for loops in the structure. Loops are not allowed. + * @throws DatabaseException + */ + private void findChildModules(Graph g, Node parent, ReadGraph graph, Resource resource, Resource parentResource, HashSet visited) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource configuration = graph.syncRequest(new PossibleObjectWithType(resource, l0.ConsistsOf, sr.Configuration)); + + // Set the parent color different, if it is the parent of the selected resource + if(configuration.equals(parentResource)) + parent.setColor("#ff8c00"); + + HashMap modules = new HashMap(); + + // Find all module children + for(Resource m : graph.getObjects(configuration, l0.ConsistsOf)) { + Resource type = graph.getPossibleObject(m, l0.InstanceOf); + if(graph.isInheritedFrom(type, sr.Module)) { + if(!modules.containsKey(type)) + modules.put(type, 0); + modules.put(type, modules.get(type) + 1); + } + } + + // Display module children in graph + for(Resource type : modules.keySet()) { + + Node node = new Node(g, NameUtils.getSafeName(graph, type)); + node.setShape("rectangle"); + Edge edge = new Edge(g, parent, node); + edge.set("labeldistance", "1.5"); + edge.set("labelfontsize", "7"); + edge.setFontColor("#4f4f4f"); + if(modules.get(type) > 1) + edge.setHeadLabel(modules.get(type).toString()); + + if(visited.contains(type)) { + // Found a loop. Stop recursive call and display error. + edge.setFontColor("#FF0000"); + edge.setColor("#FF000"); + edge.setLabel("Error: loop"); + node.setColor("#FF0000"); + node.setFontColor("#FF0000"); + continue; + } else { + HashSet copy = new HashSet(visited); + copy.add(type); + findChildModules(g, node, graph, type, parentResource, copy); + } + + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureTabItem.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureTabItem.java new file mode 100644 index 00000000..ceadd9d4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureTabItem.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.structure; + +import java.util.Set; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.widgets.Composite; +import org.simantics.db.Resource; +import org.simantics.db.procedure.Listener; +import org.simantics.graphviz.Graph; +import org.simantics.graphviz.ui.GraphvizComponent; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Super class for certain kinds of structure tabs. + * @author Tuomas Miettinen + * + */ +public abstract class StructureTabItem extends CTabItem { + + protected GraphvizComponent component; + protected GraphListener graphListener; + protected Composite structureComposite; + protected Resource currentSelection; + + public StructureTabItem(CTabFolder parent, int style) { + super(parent, style); + + structureComposite = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(structureComposite); + GridLayoutFactory.fillDefaults().spacing(0,0).applyTo(structureComposite); + + component = new GraphvizComponent(structureComposite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(component); + } + + + public void drawSelection(ISelection selection) { + if(selection == null || selection.isEmpty()) + return; + if(selection instanceof IStructuredSelection) { + Object[] els = ((IStructuredSelection) selection).toArray(); + if(els.length == 1) { + Set ress = ISelectionUtils.filterSetSelection(selection, Resource.class); + if(ress.isEmpty()) return; + Resource r = (ress.toArray(Resource.NONE))[0]; + if(r != null && !r.equals(currentSelection)) { + currentSelection = r; + readGraph(currentSelection); + } + } + } + } + + abstract protected void readGraph(Resource resource); + + class GraphListener implements Listener { + + private boolean disposed = false; + + public void dispose() { + disposed = true; + } + + @Override + public void exception(Throwable e) { + e.printStackTrace(); + } + + @Override + public void execute(final Graph graph) { + Job job = new Job(getJobLabel()) { + + @Override + protected IStatus run(IProgressMonitor monitor) { + if(!isDisposed()) { + component.setGraph(graph, "dot"); + component.fit(); + } + return Status.OK_STATUS; + } + }; + job.schedule(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + } + + protected String getJobLabel() { + return "Loading dependencies graph"; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureView.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureView.java new file mode 100644 index 00000000..39dc59dd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureView.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.structure; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.part.ViewPart; + +/** + * View for displaying different types of structural visualizations + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class StructureView extends ViewPart { + + private CTabFolder tabFolder; + private ISelectionListener selectionListener; + private StructureTabItem dependencies; + private ModuleStructure moduleStructure; + private Loops loops; + + @Override + public void createPartControl(Composite parent) { + tabFolder = new CTabFolder(parent, SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, true).applyTo(tabFolder); + GridLayoutFactory.fillDefaults().applyTo(tabFolder); + + final ISelection currentSeletion = getSite().getWorkbenchWindow().getSelectionService().getSelection(); + + // Dependencies + dependencies = new Dependencies(tabFolder, SWT.NONE); + dependencies.drawSelection(currentSeletion); + + // Hierarchical model structure + moduleStructure = new ModuleStructure(tabFolder, SWT.NONE); + + // Loops + loops = new Loops(tabFolder, SWT.NONE); + + selectionListener = new ISelectionListener() { + + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + drawSelection(selection); + } + }; + getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(selectionListener); + + + // Listener for refreshing module structure visualization on first loading + tabFolder.addSelectionListener(new SelectionListener() { + + private boolean openedOnce = false; + + @Override + public void widgetSelected(SelectionEvent e) { + if(!openedOnce && e.item.equals(moduleStructure)) { + openedOnce = true; + moduleStructure.drawSelection(currentSeletion); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + // Listener for refreshing module structure visualization on first loading + tabFolder.addSelectionListener(new SelectionListener() { + + private boolean openedOnce = false; + + @Override + public void widgetSelected(SelectionEvent e) { + if(!openedOnce && e.item.equals(loops)) { + openedOnce = true; + loops.drawSelection(currentSeletion); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + } + + /** + * Draw structural visualizations for selected object(s) + * + * @param selection Current selection + */ + private void drawSelection(ISelection selection) { + dependencies.drawSelection(selection); + moduleStructure.drawSelection(selection); + loops.drawSelection(selection); + } + + + @Override + public void setFocus() { + if(tabFolder != null && !tabFolder.isDisposed()) { + tabFolder.setFocus(); + } + } + + + @Override + public void dispose() { + super.dispose(); + getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(selectionListener); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllParametersOfModel.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllParametersOfModel.java new file mode 100644 index 00000000..de84ecf5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllParametersOfModel.java @@ -0,0 +1,132 @@ +package org.simantics.sysdyn.ui.trend; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.properties.ChartVariable; +import org.simantics.jfreechart.chart.properties.IAllVariablesOfModel; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.strings.AlphanumComparator; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Variability; + +/** + * Request for getting all variables of a model in a String array. Includes also + * variables inside modules. + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class AllParametersOfModel implements IAllVariablesOfModel { + + protected final Resource model; + + public AllParametersOfModel(Resource model) { + this.model = model; + } + + @Override + public Read> getVariablesQuery() { + return new VariableQuery(); + } + + + private class VariableQuery implements Read> { + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SimulationResource simu = SimulationResource.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + List result = new ArrayList(); + // Find the model of this resource + Resource model = AllParametersOfModel.this.model; + while(model != null && !graph.isInstanceOf(model, sr.SysdynModel)) + model = graph.getPossibleObject(model, l0.PartOf); + + if(model == null) + return result; + + // Find the models configuration + Resource conf = graph.getSingleObject(model, simu.HasConfiguration); + + // Recursively read all configurations and add items + ReadConfiguration(graph, conf, "", result); + + // Finally sort the results + Collections.sort(result, AlphanumComparator.CASE_INSENSITIVE_COMPARATOR); + return result; + } + } + + + + /** + * Read components in a configuration and recursively all module configurations + * + * @param graph ReadGraph + * @param configuration Resource to be read + * @param path Current path from base realization + * @param items Found variables + * @throws DatabaseException + */ + private void ReadConfiguration(ReadGraph graph, Resource configuration, String path, Collection items) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + + SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession()); + SysdynModel sm = sdm.getModel(graph, configuration); + try { + sm.update(graph); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + String name; + for(Resource resource : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.IndependentVariable))) { + name = path + NameUtils.getSafeName(graph, resource); + IElement element = sm.getElement(resource); + if (element instanceof IndependentVariable) { + IndependentVariable variable = (IndependentVariable)element; + Variability variability = Variability.getVariability(variable, false, null); + if (variability == Variability.PARAMETER) { + items.add(new ChartVariable(name, name)); + } + } + } + + for(Resource module : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Module))) { + Resource instanceOf = graph.getPossibleObject(module, l0.InstanceOf); + Resource conf = graph.getPossibleObject(instanceOf, sr2.IsDefinedBy); + if(conf != null) { + String p = path + NameUtils.getSafeName(graph, module) + "."; + ReadConfiguration(graph, conf, p, items); + } + } + } + + @Override + public String getVariablesLabel(ReadGraph graph, String variableId) + throws DatabaseException { + return variableId.substring(1).replace('/', '.'); + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllVariablesOfModel.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllVariablesOfModel.java new file mode 100644 index 00000000..241b7cba --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllVariablesOfModel.java @@ -0,0 +1,120 @@ +package org.simantics.sysdyn.ui.trend; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.properties.ChartVariable; +import org.simantics.jfreechart.chart.properties.IAllVariablesOfModel; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.strings.AlphanumComparator; + +/** + * Request for getting all variables of a model in a String array. Includes also + * variables inside modules. + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class AllVariablesOfModel implements IAllVariablesOfModel{ + + private final Resource model; + + public AllVariablesOfModel(Resource model) { + this.model = model; + } + + @Override + public Read> getVariablesQuery() { + return new VariableQuery(); + } + + + @Override + public String getVariablesLabel(ReadGraph graph, String variableId) + throws DatabaseException { + return variableId.substring(1).replace('/', '.'); + } + + private class VariableQuery implements Read> { + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SimulationResource simu = SimulationResource.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + List result = new ArrayList(); + // Find the model of this resource + Resource model = AllVariablesOfModel.this.model; + while(model != null && !graph.isInstanceOf(model, sr.SysdynModel)) + model = graph.getPossibleObject(model, l0.PartOf); + + if(model == null) + return result;; + + // Find the models configuration + Resource conf = graph.getSingleObject(model, simu.HasConfiguration); + + + // Recursively read all configurations and add items + ReadConfiguration(graph, conf, "", result); + + // Add time to the variable list + result.add(new ChartVariable("time", "time")); + + // Finally sort the results + Collections.sort(result, AlphanumComparator.CASE_INSENSITIVE_COMPARATOR); + return result; + } + } + + + + /** + * Read components in a configuration and recursively all module configurations + * + * @param graph ReadGraph + * @param configuration Resource to be read + * @param path Current path from base realization + * @param items Found variables + * @throws DatabaseException + */ + private void ReadConfiguration(ReadGraph graph, Resource configuration, String path, Collection items) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + + String name; + for(Resource resource : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.IndependentVariable))) { + name = path + NameUtils.getSafeName(graph, resource); + items.add(new ChartVariable(name, name)); + } + + for(Resource resource : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Input))) { + name = path + NameUtils.getSafeName(graph, resource); + items.add(new ChartVariable(name, name)); + } + + for(Resource module : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Module))) { + Resource instanceOf = graph.getPossibleObject(module, l0.InstanceOf); + Resource conf = graph.getPossibleObject(instanceOf, sr2.IsDefinedBy); + if(conf != null) { + String p = path + NameUtils.getSafeName(graph, module) + "."; + ReadConfiguration(graph, conf, p, items); + } + } + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/CategoryDataset.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/CategoryDataset.java new file mode 100644 index 00000000..4a5f80f2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/CategoryDataset.java @@ -0,0 +1,315 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.util.ArrayList; +import java.util.List; + +import javax.swing.SwingUtilities; + +import org.jfree.chart.plot.DefaultDrawingSupplier; +import org.jfree.chart.renderer.AbstractRenderer; +import org.jfree.chart.renderer.category.BarRenderer; +import org.jfree.data.category.DefaultCategoryDataset; +import org.jfree.data.general.Dataset; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.request.PossibleActiveExperiment; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.AbstractDataset; +import org.simantics.jfreechart.chart.IRenderer; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.Functions; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.adapter.VariableRVIUtils; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.ui.SimanticsUI; + +/** + * Class representing a JFreeChart.CategoryDataset + * + * @author Teemu Lempinen + * + */ +public class CategoryDataset extends AbstractDataset implements org.simantics.jfreechart.chart.CategoryDataset{ + + private List seriesList; + private String realizationURI; + private IRenderer renderer; + private DefaultCategoryDataset dataset; + + public CategoryDataset(ReadGraph graph, Resource resource) throws DatabaseException { + super(graph, resource); + + + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + // Find the model where the chart is located + Resource model = resource; + do { + model = graph.getPossibleObject(model, l0.PartOf); + } while(model != null && !graph.isInstanceOf(model, mr.StructuralModel)); + + // Find the variable realization of the current experiment + realizationURI = null; + Resource realization = graph.syncRequest(new PossibleActiveExperiment(model)); + if (realization == null) { + Layer0X L0X = Layer0X.getInstance(graph); + realization = graph.getPossibleObject(model, L0X.HasBaseRealization); + } + if (realization != null) + realizationURI = graph.getURI(realization); + + if(realizationURI == null) + return; // No experiment -> No results + + Resource seriesList = graph.getPossibleObject(resource, jfree.Dataset_seriesList); + if(seriesList != null) + this.seriesList = ListUtils.toList(graph, seriesList); + + Resource rendererResource = graph.getPossibleObject(resource, jfree.Dataset_renderer); + renderer = graph.adapt(rendererResource, IRenderer.class); + + + } + + private DatasetListener listener; + + @Override + public Dataset getDataset() { + + if(seriesList == null || seriesList.isEmpty() || SimanticsUI.getSession() == null) + return null; + + if(dataset == null) { + dataset = new DefaultCategoryDataset(); + } + + if(listener == null || listener.isDisposed()) { + listener = new DatasetListener(); + SimanticsUI.getSession().asyncRequest(new Read>() { + + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + ArrayList series = new ArrayList(); + // Get properties for all series + if(seriesList != null) { + for(Resource r : seriesList) { + String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI); + if(rvi == null) + continue; + + try { + // Get a variable for the series + Variable v = Variables.getVariable(graph, realizationURI + rvi); + // Get values + Variable dsVariable = v.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#"); + if(dsVariable == null) + return series; + + Object object = dsVariable.getValue(graph); + + if(object == null || !(object instanceof ArrayList)) + return series; + + ArrayList datasets = new ArrayList(); + + for(Object o : (ArrayList)object) { + if(o instanceof SysdynDataSet) + datasets.add((SysdynDataSet)o); + } + + String[] filter = graph.getPossibleRelatedValue(r, jfree.variableFilter); + if(filter != null) { + ArrayList result2 = VariableRVIUtils.getDataset(datasets, filter); + if(result2 != null) { + datasets = result2; + } + } + + // Find if a specific time is set for this chart + Double chartTime = null; + if(!datasets.isEmpty()) { + Layer0 l0 = Layer0.getInstance(graph); + Resource datasetResource = graph.getPossibleObject(r, l0.PartOf); + if(datasetResource != null) { + Resource plot = graph.getPossibleObject(datasetResource, l0.PartOf); + if(plot != null) { + Resource chart = graph.getPossibleObject(plot, l0.PartOf); + if(chart != null) + chartTime = graph.getPossibleRelatedValue(chart, jfree.Chart_time); + } + } + } + + for(SysdynDataSet dataset : datasets) { + double[] va = dataset.values; + + + if(va == null || va.length == 0) + continue; + + /* + * Time + * + * 1. find time for the individual series. + * 2. find time for the whole chart + * 3. find simulation time + */ + Double time = graph.getPossibleRelatedValue(r, jfree.Series_time, Bindings.DOUBLE); + if(time == null) + time = chartTime; + if(time == null) { + // Get a variable for the experiment run + Variable run = Variables.getVariable(graph, realizationURI); + if(run == null) + return null; + Variable timeVar = run.browsePossible(graph, "#" + Functions.TIME + "#"); + if(timeVar != null) + time = timeVar.getValue(graph, Bindings.DOUBLE); + + } + + // Value + Double value = null; + if(time == null) { + value = va[va.length - 1]; + } else { + double[] ta = dataset.times; + for(int i = 0; i < ta.length; i++) { + double t = ta[i]; + if(time <= t) { + value = va[i]; + break; + } + } + + if(value == null) + value = va[va.length - 1]; + } + String label = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasLabel); // Called to refresh paints when label changes + String name = label == null || label.isEmpty() ? dataset.name : label; + if (dataset.resultIndex != null) { + name += "(" + dataset.resultIndex + ")"; + } + series.add(new TempSeries(name, dataset.result, value)); + } + } catch (MissingVariableException e) { + // Do nothing, if variable was not found. Move on to the next series + } + } + } + return series; + } + + }, listener); + } + return dataset; + } + + @Override + public AbstractRenderer getRenderer() { + return renderer.getRenderer(); + } + + private class DatasetListener implements Listener> { + private boolean disposed = false; + + public void dispose() { + disposed = true; + } + + @Override + public void execute(final ArrayList series) { + // Modify series in AWT thread to avoid synchronization problems + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + // Remove all unused series + dataset.clear(); + BarRenderer renderer = ((BarRenderer)getRenderer()); + renderer.getPlot().setDrawingSupplier(new DefaultDrawingSupplier()); + + // Add found series + for(int i = 0; i < series.size(); i++) { + TempSeries s = series.get(i); + if(renderer instanceof org.jfree.chart.renderer.category.StackedBarRenderer && s.name.contains("[")) { + String category = s.name.substring(0, s.name.indexOf('[')); + if(s.result != null) + category = category + " : " + s.result; + String series = s.name.substring(s.name.indexOf('[')); + dataset.addValue(s.value, series, category); + } else { + dataset.addValue(s.value, s.result == null ? "Current" : s.result, s.name); + } + } + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + }; + + @Override + public void dispose() { + super.dispose(); + if(listener != null) { + listener.dispose(); + listener = null; + } + } + + /** + * Auxiliary class containing all information needed to define a single series + * @author Teemu Lempinen + * + */ + private class TempSeries { + public String name; + public String result; + public Double value; + + public TempSeries(String name, String result, Double value) { + this.name = name; + this.value = value; + this.result = result; + } + + @Override + public String toString() { + return "TempSeries: " + name + ", " + value + ", " + result; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBound.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBound.java new file mode 100644 index 00000000..1dc7869e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBound.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.awt.Color; + +/** + * Container class for confidence bound properties + * @author Teemu Lempinen + * + */ +public class ConfidenceBound implements Comparable { + + private double percent; + private Color color; + + public ConfidenceBound(double percent, Color color) { + this.percent = percent; + this.color = color; + } + + public double getPercent() { + return percent; + } + + public Color getColor() { + return color; + } + + @Override + public int compareTo(ConfidenceBound other) { + return Double.compare(percent, other.getPercent()); +// return Double.compare(other.getPercent(), percent); + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBoundWidget.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBoundWidget.java new file mode 100644 index 00000000..eb89e1d7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBoundWidget.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.util.List; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.Widget; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.properties.ColorPicker; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory; +import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; +import org.simantics.utils.ui.validators.DoubleValidator; + +/** + * Widget for setting percentage and color for a confidence bound + * @author Teemu Lempinen + * + */ +public class ConfidenceBoundWidget extends Composite implements Widget { + + private WidgetSupportImpl confidenceBoundSupport; + private int index; + + public ConfidenceBoundWidget(Composite parent, ISessionContext context, WidgetSupport support, int style, int index) { + super(parent, style); + this.index = index; + + support.register(this); + + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(this); + + confidenceBoundSupport = new WidgetSupportImpl(); + TrackedText variable = new TrackedText(this, confidenceBoundSupport, SWT.BORDER); + variable.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.Charts_SensitivityDataset_ConfidenceBound_percent)); + variable.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.Charts_SensitivityDataset_ConfidenceBound_percent)); + variable.setColorProvider(new SysdynBasicColorProvider(variable.getResourceManager())); + variable.setInputValidator(new DoubleValidator() { + public String isValid(String newText) { + if(newText == null || newText.isEmpty()) + return null; + else + return super.isValid(newText); + } + + }); + GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).applyTo(variable.getWidget()); + + ColorPicker colorPicker = new ColorPicker(this, context, confidenceBoundSupport, SWT.NONE, false) { + @Override + protected Resource getColorRelation(ReadGraph graph) throws DatabaseException { + return SysdynResource.getInstance(graph).Charts_SensitivityDataset_ConfidenceBound_color; + } + }; + GridDataFactory.fillDefaults().applyTo(colorPicker); + + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class); + try { + Resource confidenceBound = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return getResource(graph, resource); + } + + }); + + if(confidenceBound != null) + confidenceBoundSupport.fireInput(context, new StructuredSelection(confidenceBound)); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + private Resource getResource(ReadGraph graph, Resource input) throws DatabaseException { + Resource dataset = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf); + SysdynResource SR = SysdynResource.getInstance(graph); + Resource confidenceBoundsList = graph.getPossibleObject(dataset, SR.Charts_SensitivityDataset_confidenceBounds); + if(confidenceBoundsList == null) + return null; + List confidenceBounds = ListUtils.toList(graph, confidenceBoundsList); + return confidenceBounds.get(index); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PieDataset.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PieDataset.java new file mode 100644 index 00000000..3eb92c57 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PieDataset.java @@ -0,0 +1,333 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.swing.SwingUtilities; + +import org.jfree.chart.renderer.AbstractRenderer; +import org.jfree.data.general.Dataset; +import org.jfree.data.general.DefaultPieDataset; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.request.PossibleActiveExperiment; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.diagram.G2DUtils; +import org.simantics.jfreechart.chart.AbstractDataset; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.Functions; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.adapter.VariableRVIUtils; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.ui.SimanticsUI; + +/** + * Class representing a PieDataset in JFreeChart ontology + * @author Teemu Lempinen + * + */ +public class PieDataset extends AbstractDataset implements org.simantics.jfreechart.chart.PieDataset{ + + private List seriesList; + private String realizationURI; + private DefaultPieDataset dataset; + + private HashMap colorMap; + private HashMap explodedMap; + + public PieDataset(ReadGraph graph, Resource resource) throws DatabaseException { + super(graph, resource); + + + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + // Find the model where the chart is located + Resource model = resource; + do { + model = graph.getPossibleObject(model, l0.PartOf); + } while(model != null && !graph.isInstanceOf(model, mr.StructuralModel)); + + // Find the variable realization of the current experiment + realizationURI = null; + Resource realization = graph.syncRequest(new PossibleActiveExperiment(model)); + if (realization == null) { + Layer0X L0X = Layer0X.getInstance(graph); + realization = graph.getPossibleObject(model, L0X.HasBaseRealization); + } + if (realization != null) + realizationURI = graph.getURI(realization); + + if(realizationURI == null) + return; // No experiment -> No results + + Resource seriesList = graph.getPossibleObject(resource, jfree.Dataset_seriesList); + if(seriesList != null) { + this.seriesList = ListUtils.toList(graph, seriesList); + } + + + } + + /** + * Map of colors for different slices in a pie chart. Name + * indicates the key of the value. + * @return Map of colors for different slices in a pie chart + */ + public HashMap getColorMap() { + return colorMap; + } + + /** + * Map of exploded statuses for slices in a pie chart. Name + * indicates the key of the slice. + * @return + */ + public HashMap getExplodedMap() { + return explodedMap; + } + + @Override + public Dataset getDataset() { + if(seriesList == null || seriesList.isEmpty() || SimanticsUI.getSession() == null) + return null; + + if(dataset == null) { + dataset = new DefaultPieDataset(); + } + + if(listener == null) { + listener = new DatasetListener(); + SimanticsUI.getSession().asyncRequest(new Read>() { + + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + ArrayList series = new ArrayList(); + // Get properties for all series + if(seriesList != null) { + + colorMap = new HashMap(); + explodedMap = new HashMap(); + + for(Resource r : seriesList) { + String label = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasLabel); + String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI); + if(rvi == null) + continue; + + try { + // Get visual properties + Resource c = graph.getPossibleObject(r, jfree.color); + Color color = c == null ? null : G2DUtils.getColor(graph, c); + Boolean exploded = graph.getPossibleRelatedValue(r, jfree.Series_exploded, Bindings.BOOLEAN); + + // Get a variable for the series + Variable v = Variables.getVariable(graph, realizationURI + rvi); + + // Get values + Variable dsVariable = v.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#"); + if(dsVariable == null) + return series; + + Object object = dsVariable.getValue(graph); + if(object == null || !(object instanceof ArrayList)) + return series; + + ArrayList datasets = new ArrayList(); + + for(Object o : (ArrayList)object) { + if(o instanceof SysdynDataSet) + datasets.add((SysdynDataSet)o); + } + + String[] filter = graph.getPossibleRelatedValue(r, jfree.variableFilter); + if(filter != null) { + ArrayList result2 = VariableRVIUtils.getDataset(datasets, filter); + if(result2 != null) { + datasets = result2; + } + } + + // Find if a specific time is set for this chart + Double chartTime = null; + if(!datasets.isEmpty()) { + Layer0 l0 = Layer0.getInstance(graph); + Resource datasetResource = graph.getPossibleObject(r, l0.PartOf); + if(datasetResource != null) { + Resource plot = graph.getPossibleObject(datasetResource, l0.PartOf); + if(plot != null) { + Resource chart = graph.getPossibleObject(plot, l0.PartOf); + if(chart != null) + chartTime = graph.getPossibleRelatedValue(chart, jfree.Chart_time); + } + } + } + + for(SysdynDataSet dataset : datasets) { + double[] va = dataset.values; + + if(va == null || va.length == 0) + continue; + + /* + * Time + * + * 1. find time for the individual series. + * 2. find time for the whole chart + * 3. find simulation time + */ + Double time = graph.getPossibleRelatedValue(r, jfree.Series_time, Bindings.DOUBLE); + if(time == null) + time = chartTime; + if(time == null) { + // Get a variable for the experiment run + Variable run = Variables.getVariable(graph, realizationURI); + if(run == null) + return null; + Variable timeVar = run.browsePossible(graph, "#" + Functions.TIME + "#"); + if(timeVar != null) + time = timeVar.getValue(graph, Bindings.DOUBLE); + } + + // Value + Double value = null; + if(time == null) { + value = va[va.length - 1]; + } else { + double[] ta = dataset.times; + for(int i = 0; i < ta.length; i++) { + double t = ta[i]; + if(time <= t) { + value = va[i]; + break; + } + } + + if(value == null) + value = va[va.length - 1]; + } + + String name = label == null || label.isEmpty() ? dataset.name : label; + if (dataset.resultIndex != null) { + name += "(" + dataset.resultIndex + ")"; + } + if(dataset.result != null) + name = name + " : " + dataset.result; + colorMap.put(name, color); + explodedMap.put(name, exploded); + series.add(new TempSeries(name, value)); + } + } catch (MissingVariableException e) { + // Do nothing, if variable was not found. Move on to the next series + } + } + } + return series; + } + + }, listener); + } + return dataset; + } + + private DatasetListener listener; + + private class DatasetListener implements Listener> { + + private boolean disposed = false; + + @Override + public void execute(final ArrayList series) { + // Modify series in AWT thread to avoid synchronization problems + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + // Remove all series + dataset.clear(); + + // Add found series + for(int i = 0; i < series.size(); i++) { + TempSeries s = series.get(i); + dataset.setValue(s.name, s.value); + } + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + + public void dispose() { + disposed = true; + } + } + + @Override + public AbstractRenderer getRenderer() { + // No renderer for pie chart + return null; + } + + @Override + public void dispose() { + super.dispose(); + if(listener != null) { + listener.dispose(); + listener = null; + } + } + + + /** + * Auxiliary class containing all information needed to define a single series + * @author Teemu Lempinen + * + */ + private class TempSeries { + public String name; + public Double value; + + public TempSeries(String name, Double value) { + this.name = name; + this.value = value; + } + + @Override + public String toString() { + return "TempSeries: " + name + ", " + value; + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PinTrend.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PinTrend.java new file mode 100644 index 00000000..a3509989 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PinTrend.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.State; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; + + +public class PinTrend extends AbstractHandler { + + public static final String COMMAND = "org.simantics.sysdyn.ui.trend.view.pin"; + public static final String STATE = "org.simantics.sysdyn.ui.trend.view.pin.state"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + Command command = service.getCommand(COMMAND); + State state = command.getState(STATE); + Boolean value = (Boolean) state.getValue(); + value = !value; + state.setValue(value); + + return null; + } + + public static Boolean getState() { + ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + Command command = service.getCommand(COMMAND); + State state = command.getState(STATE); + return (Boolean)state.getValue(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityChartAxisAndVariablesTab.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityChartAxisAndVariablesTab.java new file mode 100644 index 00000000..0bfe1d65 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityChartAxisAndVariablesTab.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.SingleSelectionInputSource; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor; +import org.simantics.jfreechart.chart.properties.xyline.AxisAndVariablesExplorerComposite; +import org.simantics.jfreechart.chart.properties.xyline.AxisPropertyComposite; +import org.simantics.jfreechart.chart.properties.xyline.SeriesPropertyComposite; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.ui.AdaptionUtils; + +public class SensitivityChartAxisAndVariablesTab extends LabelPropertyTabContributor { + + private GraphExplorerComposite explorer; + private ScrolledComposite propertyContainer; + private WidgetSupportImpl additionalSupport; + + public SensitivityChartAxisAndVariablesTab() { + additionalSupport = new WidgetSupportImpl(); + } + + @Override + public void createControls(Composite body, IWorkbenchSite site, final ISessionContext context, WidgetSupport support) { + Composite composite = new Composite(body, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(composite); + GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite); + + // (Ontology-based) GraphExplorer displaying range axis and variables mapped to those axis + explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE); + explorer.setBrowseContexts(JFreeChartResource.URIs.ChartAxisAndVariablesBrowseContext); + explorer.setInputSource(new SingleSelectionInputSource( + Resource.class)); + explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning + explorer.finish(); + + ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateSelection(context); + } + }); + GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer); + + // Scrolled composite for displaying properties of a selection in explorer + propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL); + GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(propertyContainer); + GridLayoutFactory.fillDefaults().applyTo(propertyContainer); + propertyContainer.setExpandHorizontal(true); + propertyContainer.setExpandVertical(true); + + } + + /** + * Updates the content of propertyContainer + * @param context + */ + private void updateSelection(ISessionContext context) { + ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class); + IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection(); + final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class); + if(resource == null) + return; + + // Get the type of the selected node (axis or series) + String typeUri = null; + try { + typeUri = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + if(graph.isInstanceOf(resource, jfree.Axis)) + return graph.getURI(jfree.Axis); + else if (graph.isInstanceOf(resource, jfree.Series)) + return graph.getURI(jfree.Series); + return null; + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // Create a PropertyComposite for the selected node + if(typeUri != null) { + + for(Control child : propertyContainer.getChildren()) { + child.dispose(); + } + + if(typeUri.equals(JFreeChartResource.URIs.Axis)) { + AxisPropertyComposite apc = new AxisPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE); + propertyContainer.setContent(apc); + Point size = apc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } else if(typeUri.equals(JFreeChartResource.URIs.Series)) { + SeriesPropertyComposite spc = new SensitivitySeriesPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE); + propertyContainer.setContent(spc); + Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT); + propertyContainer.setMinSize(size); + } + } + + additionalSupport.fireInput(context, selection); + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDataset.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDataset.java new file mode 100644 index 00000000..c4aba21f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDataset.java @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.swing.SwingUtilities; + +import org.jfree.chart.LegendItem; +import org.jfree.chart.renderer.AbstractRenderer; +import org.jfree.chart.renderer.xy.DeviationRenderer; +import org.jfree.data.general.Dataset; +import org.jfree.data.xy.YIntervalSeries; +import org.jfree.data.xy.YIntervalSeriesCollection; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.procedure.adapter.DisposableListener; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.diagram.G2DUtils; +import org.simantics.jfreechart.chart.IRenderer; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; + +/** + * Dataset for sensitivity analysis fan charts. + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class SensitivityDataset extends XYDataset { + + DeviationRenderer renderer; + + public SensitivityDataset(ReadGraph graph, Resource resource) throws DatabaseException { + super(graph, resource); + } + + @SuppressWarnings("unchecked") + @Override + public Dataset getDataset() { + if(dataset == null) { + dataset = new YIntervalSeriesCollection(); + } + + if(datasetListener == null || datasetListener.isDisposed()) { + datasetListener = new SensitivityDatasetListener(); + SimanticsUI.getSession().asyncRequest( + new SensitivityDatasetRequest(resource), + (DisposableListener, SensitivityDatasetProperties>>) datasetListener); + } + + if(timeListener == null || timeListener.isDisposed()) { + SimanticsUI.getSession().asyncRequest(getTimeRequest(), getTimeListener()); + } + return dataset; + } + + /** + * SensitivityDatasetRequest uses {@link XYDatasetRequest} to get values for all sensitivity analysis runs. + * + * In addition, the request finds fan chart properties from dataset resource and passes them to {@link SensitivityDatasetListener} + * @author Teemu Lempinen + * + */ + private class SensitivityDatasetRequest implements Read, SensitivityDatasetProperties>> { + + private Resource dataset; + + public SensitivityDatasetRequest(Resource dataset) { + this.dataset = dataset; + } + + @Override + public Pair, SensitivityDatasetProperties> perform(ReadGraph graph) throws DatabaseException { + + Pair, IRenderer> XYDatasetRequestResult = graph.syncRequest(new XYDatasetRequest(dataset)); + + SysdynResource SR = SysdynResource.getInstance(graph); + Boolean median = graph.getPossibleRelatedValue(dataset, SR.Charts_SensitivityDataset_median); + if (median == null) + median = false; + + Resource confidenceBoundsList = graph.getPossibleObject(dataset, SR.Charts_SensitivityDataset_confidenceBounds); + ArrayList confidenceBounds = new ArrayList(); + + if(confidenceBoundsList != null) { + List confidenceBoundResources = ListUtils.toList(graph, confidenceBoundsList); + + for(Resource cb : confidenceBoundResources) { + Double percent = graph.getPossibleRelatedValue(cb, SR.Charts_SensitivityDataset_ConfidenceBound_percent); + Resource c = graph.getPossibleObject(cb, SR.Charts_SensitivityDataset_ConfidenceBound_color); + Color color = c == null ? null : G2DUtils.getColor(graph, c); + if(percent != null && color != null) + confidenceBounds.add(new ConfidenceBound(percent, color)); + } + } + + SensitivityDatasetProperties properties = new SensitivityDatasetProperties(median, confidenceBounds); + + return new Pair, SensitivityDatasetProperties> (XYDatasetRequestResult.first, properties); + } + + } + + @Override + public AbstractRenderer getRenderer() { + if(renderer == null) + renderer = new DeviationRenderer(true, false) { + private static final long serialVersionUID = 633310754812851862L; + + /* + * Overridden getLegendElement to provide thick lines for legend. + */ + @Override + public LegendItem getLegendItem(int datasetIndex, int series) { + LegendItem item = super.getLegendItem(datasetIndex, series); + return new LegendItem(item.getLabel(), item.getDescription(), item.getToolTipText(), item.getURLText(), item.getLine(), new BasicStroke(5F), item.getLinePaint()); + } + }; + return renderer; + } + + /** + * SensitivityDatasetListener calculates confidence bounds from all sensitivity analysis run results. + * @author Teemu Lempinen + * + */ + private class SensitivityDatasetListener extends DisposableListener, SensitivityDatasetProperties>> { + + @Override + public void execute(Pair, SensitivityDatasetProperties> result) { + final ArrayList series = result.first; + final SensitivityDatasetProperties properties = result.second; + + // Modify series in AWT thread to avoid synchronization problems + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + if(dataset == null || !(dataset instanceof YIntervalSeriesCollection)) + return; + + YIntervalSeriesCollection ds = (YIntervalSeriesCollection)dataset; + + DeviationRenderer dr = (DeviationRenderer)getRenderer(); + + ArrayList confidenceBounds = properties.getConfidenceBounds(); + + + // CONFIDENCE BOUND PAINTS + for(int i = 1; i <= confidenceBounds.size(); i++) { + dr.setSeriesStroke(i, new BasicStroke(0F)); + dr.setSeriesPaint(i, confidenceBounds.get(i-1).getColor()); + dr.setSeriesFillPaint(i, confidenceBounds.get(i-1).getColor()); + } + + Color medianColor = Color.RED; + // MEDIAN PAINTS + dr.setSeriesStroke(0, new BasicStroke(2F)); + dr.setSeriesPaint(0, medianColor); + dr.setSeriesFillPaint(0, medianColor); + dr.setSeriesVisibleInLegend(0, true); + + + if(!properties.displayMedian()) { + /* + * Median is in the first index position. If it + * is not visible, make it the same color as + * the next series and hide it from legend + */ + dr.setSeriesVisibleInLegend(0, false); + dr.setSeriesPaint(0, dr.getSeriesPaint(1)); + } + + dr.setAlpha(1); + + // Remove all series + for(int i = ds.getSeriesCount() - 1; i >= 0; i-- ) { + ds.removeSeries(ds.getSeries(i)); + } + + int n = series.size(); + if(n < 1) + return; + + int length = series.get(0).values[0].length; + + + YIntervalSeries median = new YIntervalSeries("Median"); + + YIntervalSeries[] yIntervalSeries = new YIntervalSeries[confidenceBounds.size()]; + for(int i = 0; i < confidenceBounds.size(); i++) { + yIntervalSeries[i] = new YIntervalSeries(confidenceBounds.get(i).getPercent() + "%"); + } + + ArrayList sorter = new ArrayList(); + for(int i = 0; i < length; i++) { + sorter.clear(); + for(int j = 0; j < n; j++) { + if(series.get(j).values[1].length == 0) + continue; // If there are no values, move on to next dataset + sorter.add(series.get(j).values[1][i]); // values is a two-dimensional array. 0 dimension == times, 1 == values + } + Collections.sort(sorter); + + int sorterSize = sorter.size(); + int intervals = sorterSize - 1; + + // MEDIAN + double medianX = series.get(0).values[0][i]; + double medianY = sorter.get(sorterSize/2); + median.add( + medianX, + medianY, + medianY, + medianY + ); + + // CONFIDENCE BOUNDS + for(int j = 0; j < yIntervalSeries.length; j++) { + YIntervalSeries yis = yIntervalSeries[j]; + double percent = properties.getConfidenceBounds().get(j).getPercent() / 100; + if(n >= (1 / percent) * 2) { + // Estimate the confidence limits + double indexLow = (1 - percent) * intervals / 2; + int indexLowLow = (int)Math.floor(indexLow); + int indexLowHigh = (int)Math.ceil(indexLow); + double valueLowLow = sorter.get(indexLowLow); + double valueLowHigh = sorter.get(indexLowHigh); + double decimalLow = indexLow - indexLowLow; + // Linear interpolation; to decrease execution time, use interpolation of degree 0, + // but I didn't find the current approach too time consuming in a simple test. + double estimateLow = (valueLowHigh - valueLowLow) * decimalLow + valueLowLow; + + double indexHigh = (1 + percent) * intervals / 2;; + int indexHighLow = (int)Math.floor(indexHigh); + int indexHighHigh = (int)Math.ceil(indexHigh); + double valueHighLow = sorter.get(indexHighLow); + double valueHighHigh = sorter.get(indexHighHigh); + double decimalHigh = 1 - decimalLow; + double estimateHigh = (valueHighHigh - valueHighLow) * decimalHigh + valueHighLow; + yis.add( + medianX, + medianY, + estimateLow, + estimateHigh + ); + } + } + } + + // ADD MEDIAN + ds.addSeries(median); + + // ADD OTHERS + // CONFIDENCE BOUNDS + for(int j = 0; j < yIntervalSeries.length; j++) { + YIntervalSeries yis = yIntervalSeries[j]; + double percent = properties.getConfidenceBounds().get(j).getPercent(); + if(n >= (1 / percent) * 2) + ds.addSeries(yis); + } + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDatasetProperties.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDatasetProperties.java new file mode 100644 index 00000000..a216b52c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDatasetProperties.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.util.ArrayList; +import java.util.Collections; + +public class SensitivityDatasetProperties { + + private boolean median; + private ArrayList confidenceBounds; + + public SensitivityDatasetProperties(boolean median, ArrayList confidenceBounds) { + this.median = median; + this.confidenceBounds = new ArrayList(confidenceBounds); + Collections.sort(this.confidenceBounds); + } + + public boolean displayMedian() { + return median; + } + + public ArrayList getConfidenceBounds() { + return confidenceBounds; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivitySeriesPropertyComposite.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivitySeriesPropertyComposite.java new file mode 100644 index 00000000..c05d1ae4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivitySeriesPropertyComposite.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.simantics.browsing.ui.swt.widgets.Button; +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.jfreechart.chart.properties.xyline.SeriesPropertyComposite; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; + +/** + * UI for setting properties for sensitivity analysis series. Sensitivity analysis + * charts display only one variable as a "fan" chart. + * @author Teemu Lempinen + * + */ +public class SensitivitySeriesPropertyComposite extends SeriesPropertyComposite { + + public SensitivitySeriesPropertyComposite(Composite parent, ISessionContext context, WidgetSupport support, + int style) { + super(parent, context, support, style); + } + + @Override + protected void createContent(ISessionContext context, WidgetSupport support) { + GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this); + + // Variable for the series + variable(this, context, support); + + // Range + range(this, context, support); + + // Label to be displayed in chart for this series +// seriesLabel(this, context, support); + + Button validateUnits = new Button(this, support, SWT.CHECK); + validateUnits.setText("Display median"); + GridDataFactory.fillDefaults().span(2, 1).applyTo(validateUnits.getWidget()); + validateUnits.setSelectionFactory(new ReadFactoryImpl() { + + @Override + public Boolean perform(ReadGraph graph, Resource series) throws DatabaseException { + Resource dataset = graph.getPossibleObject(series, Layer0.getInstance(graph).PartOf); + Boolean result = graph.getPossibleRelatedValue(dataset, SysdynResource.getInstance(graph).Charts_SensitivityDataset_median, Bindings.BOOLEAN); + return Boolean.TRUE.equals(result); + } + }); + + validateUnits.addSelectionListener(new SelectionListenerImpl(context){ + + @Override + public void apply(WriteGraph graph, Resource series) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + Resource dataset = graph.getPossibleObject(series, Layer0.getInstance(graph).PartOf); + if(dataset == null) + return; + + Boolean result = graph.getPossibleRelatedValue(dataset, SR.Charts_SensitivityDataset_median, Bindings.BOOLEAN); + if(result == null) + result = false; + graph.claimLiteral(dataset, SR.Charts_SensitivityDataset_median, Boolean.FALSE.equals(result)); + } + + }); + + ConfidenceBoundWidget cbWidget = new ConfidenceBoundWidget(this, context, support, SWT.NONE, 0); + GridDataFactory.fillDefaults().span(2, 1).applyTo(cbWidget); + cbWidget = new ConfidenceBoundWidget(this, context, support, SWT.NONE, 1); + GridDataFactory.fillDefaults().span(2, 1).applyTo(cbWidget); + cbWidget = new ConfidenceBoundWidget(this, context, support, SWT.NONE, 2); + GridDataFactory.fillDefaults().span(2, 1).applyTo(cbWidget); + cbWidget = new ConfidenceBoundWidget(this, context, support, SWT.NONE, 3); + GridDataFactory.fillDefaults().span(2, 1).applyTo(cbWidget); + cbWidget = new ConfidenceBoundWidget(this, context, support, SWT.NONE, 4); + GridDataFactory.fillDefaults().span(2, 1).applyTo(cbWidget); + + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SysdynRangeHandlerFactory.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SysdynRangeHandlerFactory.java new file mode 100644 index 00000000..9f804e55 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SysdynRangeHandlerFactory.java @@ -0,0 +1,166 @@ +package org.simantics.sysdyn.ui.trend; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.jfreechart.chart.properties.RangeHandlerFactory; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.datastructures.Quad; + +public class SysdynRangeHandlerFactory implements RangeHandlerFactory { + + protected Resource getRVIRelation(ReadGraph graph) { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + return jfree.variableRVI; + } + + @Override + public Read> getRequest(final Resource series) { + // TODO Auto-generated method stub + return new Read>() { + + @Override + public LinkedHashMap perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + String realizationURI = ChartUtils.getCurrentRealizationURI(graph, series); + String rvi = graph.getPossibleRelatedValue(series, getRVIRelation(graph)); + if(rvi == null) + return null; + + rvi = rvi.replace(".", "/"); + + if(!rvi.startsWith("/")) + rvi = "/" + rvi; + + try { + // Find the variable for the current variableRVI + Variable v = Variables.getVariable(graph, realizationURI + rvi.trim()); + if(v == null) + return null; + + // Find all enumeration replacements in the variable's path + HashMap redeclarations = new HashMap(); + Variable parent = v; + while((parent = parent.getParent(graph)) != null) { + Resource represents = parent.getRepresents(graph); + Resource type = graph.getSingleObject(represents, Layer0.getInstance(graph).InstanceOf); + if(!graph.isInheritedFrom(type, sr.Module)) + break; + + for(Resource redeclaration : graph.getObjects(represents, sr.Module_redeclaration)) { + redeclarations.put( + graph.getPossibleObject(redeclaration, sr.Redeclaration_replacedEnumeration), + graph.getPossibleObject(redeclaration, sr.Redeclaration_replacingEnumeration) + ); + } + } + + + + + Resource variable = v.getRepresents(graph); + + // Return the enumerations assigned to that variable + Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList); + if(arrayIndexes != null) { + LinkedHashMap result = new LinkedHashMap(); + for(Resource enumeration : ListUtils.toList(graph, arrayIndexes)) { + + // Find possible redeclarations for enumeration + Resource redeclaration = enumeration; + while(redeclarations.get(redeclaration) != null) + redeclaration = redeclarations.get(redeclaration); + + String enumerationName = NameUtils.getSafeName(graph, redeclaration); + result.put(enumerationName, redeclaration); + } + return result; + } + } catch (DatabaseException e) { + // No variable was found, return null + } + return null; + } + + }; + } + + @Override + public ReadFactoryImpl> getRangeItemFactory(int index, Resource res) { + return new RangeItemFactory(index, res); + } + + + /** + * RangeItemFactory finds all inexes of a given enumeration + * and adds "Sum" and "All" to the returned indexes + * @author Teemu Lempinen + * + */ + public class RangeItemFactory extends ReadFactoryImpl> { + + private int index; + private Resource enumeration; + private boolean addCollections; + + + /** + * + * @param index Index of the enumeration in the variable + * @param enumeration The enumeration + */ + public RangeItemFactory(int index, Resource enumeration) { + this(index, enumeration, true); + } + + /** + * + * @param index Index of the enumeration in the variable + * @param enumeration The enumeration + * @param addCollections add "Sum" and "All" + */ + public RangeItemFactory(int index, Resource enumeration, boolean addCollections) { + this.index = index; + this.enumeration = enumeration; + this.addCollections = addCollections; + } + + public Object getIdentity(Object inputContents) { + return new Quad>(inputContents, index, enumeration, getClass()); + } + @Override + public Map perform(ReadGraph graph, Resource series) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + LinkedHashMap result = new LinkedHashMap(); + Resource enumerationIndexes = graph.getPossibleObject(enumeration, sr.Enumeration_enumerationIndexList); + List indexes = ListUtils.toList(graph, enumerationIndexes); + if(addCollections) { + // First add "All" and "Sum", then all of the enumeration indexes in order + result.put("All", "All"); + result.put("Sum", "Sum"); + } + for(Resource index : indexes) { + String name = NameUtils.getSafeName(graph, index); + result.put(name, name); + } + + return result; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendEditor.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendEditor.java new file mode 100644 index 00000000..258bae53 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendEditor.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.simantics.jfreechart.chart.ChartComposite; +import org.simantics.ui.workbench.ResourceEditorPart; + +public class TrendEditor extends ResourceEditorPart { + + private ChartComposite chart; + + @Override + public void createPartControl(Composite parent) { + chart = new ChartComposite(parent, getResourceInput().getResource(), SWT.NONE); + } + + @Override + public void setFocus() { + chart.forceFocus(); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToPng.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToPng.java new file mode 100644 index 00000000..dae65d78 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToPng.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.expressions.EvaluationContext; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.jfree.chart.ChartUtilities; +import org.jfree.chart.JFreeChart; + +/** + * Exports the current chart in TrendView + * @author Teemu Lempinen + * + */ +public class TrendToPng extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + EvaluationContext c = (EvaluationContext)event.getApplicationContext(); + Object o = c.getParent().getVariable("activePart"); + if(o != null && o instanceof TrendView) { + TrendView trendView = (TrendView) o; + int width = trendView.getPanel().getSize().width; + int height = trendView.getPanel().getSize().height; + int compressionLevel = 0; + + final Shell shell = HandlerUtil.getActiveShellChecked(event); + + while(true) { + FileDialog fd = new FileDialog(shell, SWT.SAVE); + fd.setText("Export trend to PNG"); + String[] ext = {"*.png"}; + fd.setFilterExtensions(ext); + String selected = fd.open(); + + if(selected == null) + return null; + + File file = new File(selected); + + if(file.exists()) { + MessageDialog dialog = new MessageDialog(shell, "Overwrite " + file.getName() + "?", null, file.getName() + " exits. Do you wan't to overwrite it?", 0, + new String[] { "Yes", "No" }, 0); + dialog.create(); + if (dialog.open() == 1) + continue; + } + + JFreeChart chart = trendView.getPanel().getChart(); + try { + ChartUtilities.saveChartAsPNG(file, chart, width, height, null, true, compressionLevel); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + } + return null; + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToSvg.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToSvg.java new file mode 100644 index 00000000..9da9370e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToSvg.java @@ -0,0 +1,73 @@ +package org.simantics.sysdyn.ui.trend; + +//import java.awt.geom.Rectangle2D; +//import java.io.File; +//import java.io.FileNotFoundException; +//import java.io.FileOutputStream; +//import java.io.OutputStreamWriter; +//import java.io.UnsupportedEncodingException; +//import java.io.Writer; + +import java.awt.geom.Rectangle2D; +import java.io.File; +import java.io.IOException; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.expressions.EvaluationContext; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.simantics.jfreechart.chart.ChartUtils; + +public class TrendToSvg extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + EvaluationContext c = (EvaluationContext)event.getApplicationContext(); + Object o = c.getParent().getVariable("activePart"); + if(o != null && o instanceof TrendView) { + TrendView trendView = (TrendView) o; + + Shell shell = HandlerUtil.getActiveShellChecked(event); + + while(true) { + FileDialog fd = new FileDialog(shell, SWT.SAVE); + fd.setText("Export trend to SVG"); + String[] ext = {"*.svg"}; + fd.setFilterExtensions(ext); + String selected = fd.open(); + + if(selected == null) + return null; + + File file = new File(selected); + + if(file.exists()) { + MessageDialog dialog = new MessageDialog(shell, "Overwrite " + file.getName() + "?", null, file.getName() + " exits. Do you wan't to overwrite it?", 0, + new String[] { "Yes", "No" }, 0); + dialog.create(); + if (dialog.open() == 1) + continue; + } + + try { + ChartUtils.writeSVG( + trendView.getPanel().getChart(), + new Rectangle2D.Double(0, 0, trendView.getPanel().getWidth(), trendView.getPanel().getHeight()), + file); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } + } + + return null; + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendView.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendView.java new file mode 100644 index 00000000..d3a33699 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendView.java @@ -0,0 +1,296 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.awt.Frame; +import java.util.Collection; + +import javax.swing.SwingUtilities; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.awt.SWT_AWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.AbstractXYDataset; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.IJFreeChart; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.ui.viewUtils.SysdynDatasetSelectionListener; +import org.simantics.utils.RunnableWithObject; + +/** + * Trend view that shows all active simulation results for selected variables. + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class TrendView extends ViewPart { + + private Frame frame; + private ChartPanel panel; + private SysdynDatasets sysdynDatasets = new SysdynDatasets(); + private SysdynDatasetSelectionListener sysdynDatasetSelectionListener; + private JFreeChart defaultchart; + private Composite composite; + + + public Frame getFrame() { + return frame; + } + + public ChartPanel getPanel() { + return panel; + } + + public void setPanel(ChartPanel panel) { + this.panel = panel; + } + + public SysdynDatasets getSysdynDatasets() { + return sysdynDatasets; + } + + /** + * Dataset for jFreeChart + * + * @author Teemu Lempinen + * + */ + @SuppressWarnings("serial") + class SysdynDatasets extends AbstractXYDataset { + + SysdynDataSet[] sets = new SysdynDataSet[0]; + + public void setDatasets(SysdynDataSet[] sets) { + this.sets = sets; + fireDatasetChanged(); + } + + @Override + public Number getY(int series, int item) { + return sets[series].values[item]; + } + + @Override + public Number getX(int series, int item) { + return sets[series].times[item]; + } + + @Override + public int getItemCount(int series) { + return sets[series].times.length; + } + + @Override + public Comparable getSeriesKey(int series) { + SysdynDataSet sds = sets[series]; + String name = sds.name; + if(sds.resultIndex != null) + name += "(" + sds.resultIndex + ")"; + if(sds.result == null) + return name; + else + return name + " : " + sds.result; + } + + @Override + public int getSeriesCount() { + return sets.length; + } + + } + + @Override + public void createPartControl(Composite parent) { + + composite = new Composite(parent, + SWT.NO_BACKGROUND | SWT.EMBEDDED); + frame = SWT_AWT.new_Frame(composite); + + // Create the chart + displayDefaultChart(); + + // Add a dataset listener that updates datasets for the chart according to current selection + sysdynDatasetSelectionListener = new TrendViewSelectionListner(this); + + getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(sysdynDatasetSelectionListener); + + } + + private class TrendViewSelectionListner extends SysdynDatasetSelectionListener { + + private TrendView trendView; + private CustomChartListener listener; + + public TrendViewSelectionListner(TrendView trendView) { + this.trendView = trendView; + } + + @Override + protected void selectionChanged(final Collection activeDatasets) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + if(listener != null) { + listener.dispose(); + } + trendView.getSysdynDatasets().setDatasets(activeDatasets.toArray(new SysdynDataSet[activeDatasets.size()])); + displayDefaultChart(); + } + + }); + } + + @Override + protected void selectionChanged(ReadGraph graph, final Resource chartResource) { + + if(listener != null) { + listener.dispose(); + } + + listener = new CustomChartListener(trendView); + + graph.asyncRequest(new Read() { + + @Override + public JFreeChart perform(ReadGraph graph) throws DatabaseException { + if(graph.hasStatement(chartResource)) { + IJFreeChart chart = graph.adapt(chartResource, IJFreeChart.class); + if(chart != null) { + return chart.getChart(); + } + } + return null; + } + }, listener); + } + } + + private class CustomChartListener implements Listener { + + private boolean disposed = false; + private TrendView trendView; + + public CustomChartListener(TrendView trendView) { + this.trendView = trendView; + } + + @Override + public void execute(JFreeChart result) { + if(!disposed) + displayChart(result, trendView); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + + public void dispose() { + this.disposed = true; + } + + } + + /** + * Displays jFreeChart + * @param jFreeChart + */ + private void displayChart(JFreeChart jFreeChart, TrendView trendView) { + SwingUtilities.invokeLater(new RunnableWithObject(jFreeChart, trendView) { + + @Override + public void run() { + if(count() != 2 || getObject(0) == null || getObject(1) == null) + return; + + if(!(getObject(0) instanceof JFreeChart && getObject(1) instanceof TrendView)) + return; + + JFreeChart jFreeChart = (JFreeChart) getObject(0); + TrendView trendView = (TrendView) getObject(1); + + Frame frame = trendView.getFrame(); + ChartPanel panel = trendView.getPanel(); + + // Do not just simply frame.removeAll(); + // Instead, use and reuse only the first component of the frame. + if(jFreeChart != null) { + if (panel == null || frame.getComponentCount() == 0){ + panel = new ChartPanel(jFreeChart, false, true, true, true, true); + trendView.setPanel(panel); + frame.add(panel); + } else { +// panel.setChart(jFreeChart); + if ( frame.getComponent(0) instanceof ChartPanel ){ + ChartPanel tempPanel = (ChartPanel)frame.getComponent(0); + tempPanel.setChart(jFreeChart); + trendView.setPanel(tempPanel); + } + } + } + frame.repaint(); + frame.validate(); + panel.requestFocus(); + } + + }); + } + + /** + * displays a default chart + */ + private void displayDefaultChart() { + if(defaultchart == null) { + XYPlot plot = new XYPlot( + sysdynDatasets, + new NumberAxis("time"), + new NumberAxis(""), + new XYLineAndShapeRenderer(true, false) + ); + defaultchart = new JFreeChart(plot); + } + displayChart(defaultchart, this); + } + + @Override + public void dispose() { + super.dispose(); + getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(sysdynDatasetSelectionListener); + } + + @Override + public void setFocus() { + if(panel != null) + panel.requestFocus(); + } + + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDataset.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDataset.java new file mode 100644 index 00000000..4866e219 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDataset.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Paint; +import java.awt.Stroke; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.SwingUtilities; + +import org.jfree.chart.ChartColor; +import org.jfree.chart.labels.StandardXYToolTipGenerator; +import org.jfree.chart.plot.DefaultDrawingSupplier; +import org.jfree.chart.plot.ValueMarker; +import org.jfree.chart.renderer.AbstractRenderer; +import org.jfree.chart.renderer.xy.AbstractXYItemRenderer; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.general.Dataset; +import org.jfree.data.xy.DefaultXYDataset; +import org.jfree.ui.Layer; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.procedure.adapter.DisposableListener; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.request.PossibleActiveExperiment; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.request.Read; +import org.simantics.jfreechart.chart.AbstractDataset; +import org.simantics.jfreechart.chart.IRenderer; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.Functions; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; + +/** + * Class representing a JFreeChart.XYDataset + * + * @author Teemu Lempinen + * + */ +public class XYDataset extends AbstractDataset implements org.simantics.jfreechart.chart.XYDataset{ + + protected IRenderer renderer; + + public XYDataset(ReadGraph graph, final Resource datasetResource) throws DatabaseException { + super(graph, datasetResource); + } + + protected Dataset dataset; + protected DisposableListener datasetListener; + protected DisposableListener timeListener; + + protected DisposableListener getTimeListener() { + if(timeListener == null || timeListener.isDisposed()) { + timeListener = new TimeListener(); + } + return timeListener; + } + + protected Read getTimeRequest() { + return new Read() { + @Override + public Double perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + // Get properties for all series + Resource series = graph.getPossibleObject(resource, jfree.Dataset_seriesList); + if(series != null) { + List seriesList = ListUtils.toList(graph, series); + if(seriesList != null) { + String realizationURI = getRealizationURI(graph, resource); + for(Resource r : seriesList) { + String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI); + if(rvi == null) + continue; + try { + // Get a variable for the experiment run + Variable v = Variables.getVariable(graph, realizationURI); + if(v == null) + return null; + Variable timeVar = v.browsePossible(graph, "#" + Functions.TIME + "#"); + if(timeVar != null) + return timeVar.getValue(graph, Bindings.DOUBLE); + } catch (MissingVariableException e) { + // Do nothing, if variable was not found. + } + } + } + } + return null; + } + + }; + } + + @SuppressWarnings("unchecked") + @Override + public Dataset getDataset() { + if(dataset == null) { + dataset = new DefaultXYDataset(); + } + + if(datasetListener == null || datasetListener.isDisposed()) { + datasetListener = new DataSetListener(); + SimanticsUI.getSession().asyncRequest( + new XYDatasetRequest(resource), + (DisposableListener, IRenderer>>) datasetListener); + + } + + if(timeListener == null || timeListener.isDisposed()) { + SimanticsUI.getSession().asyncRequest(getTimeRequest(), getTimeListener()); + } + return dataset; + } + + /** + * Class for identifying a time marker in a plot + * @author Teemu Lempinen + * + */ + protected class TimeMarker extends ValueMarker { + private static final long serialVersionUID = 2018755066561629172L; + + public TimeMarker(double value, Paint paint, Stroke stroke) { + super(value, paint, stroke); + } + } + + private class DataSetListener extends DisposableListener, IRenderer>> { + + @Override + public void execute(Pair, IRenderer> result) { + final ArrayList series = result.first; + renderer = result.second; + + // Modify series in AWT thread to avoid synchronization problems + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + if(dataset == null || !(dataset instanceof DefaultXYDataset)) + return; + + DefaultXYDataset ds = (DefaultXYDataset)dataset; + org.jfree.chart.plot.XYPlot plot = ((AbstractXYItemRenderer)getRenderer()).getPlot(); + + if(plot != null) { + /* + * Drawing supplier with a modified first yellow. The default first + * yellow is too light to be visible against a white background + */ + Paint[] paintSequence = ChartColor.createDefaultPaintArray(); + paintSequence[3] = new Color(0xFF, 0xDD, 0x00); + DefaultDrawingSupplier drawingsupplier = new DefaultDrawingSupplier( + paintSequence, + DefaultDrawingSupplier.DEFAULT_FILL_PAINT_SEQUENCE, + DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE, + DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE, + DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE, + DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE); + plot.setDrawingSupplier(drawingsupplier); + } + // Remove all series + for(int i = ds.getSeriesCount() - 1; i >= 0; i-- ) { + ds.removeSeries(ds.getSeriesKey(i)); + } + + // Add found series + for(int i = 0; i < series.size(); i++) { + XYDatasetTempSeries s = series.get(i); + String name = s.name; + if(ds.indexOf(name) >= 0) + name = name + (i + 1); + ds.addSeries(name, s.values); + getRenderer().setSeriesStroke(i, new BasicStroke((float)s.width)); + getRenderer().setSeriesPaint(i, s.color); + } + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + } + + + /** + * Listener for updating the time indicator for XY plots + * @author Teemu Lempinen + * + */ + protected class TimeListener extends DisposableListener { + + private ValueMarker marker; + private Stroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, + BasicStroke.JOIN_MITER, 10.0f, new float[] {5.0f, 3.0f, 1.0f, 3.0f}, 0.0f); + + public TimeListener() { + this.marker = new TimeMarker(0.0, Color.red, dashStroke); + } + + public void dispose() { + super.dispose(); + if(marker != null) { + org.jfree.chart.plot.XYPlot plot = ((AbstractXYItemRenderer)getRenderer()).getPlot(); + if(plot != null) + plot.removeDomainMarker(marker); + } + } + + @Override + public void execute(final Double time) { + // Modify in AWT thread to avoid synchronization problems + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + org.jfree.chart.plot.XYPlot plot = ((AbstractXYItemRenderer)getRenderer()).getPlot(); + + if(plot == null) + return; + + plot.removeDomainMarker(marker); + if(time != null) { + marker.setValue(time); + if(plot.getDomainMarkers(Layer.FOREGROUND) == null || !plot.getDomainMarkers(Layer.FOREGROUND).contains(marker)) { + int i = 0; + for(i = 0; i < plot.getDatasetCount(); i++) { + if(plot.getDataset(i) != null && plot.getDataset(i).equals(dataset)) + break; + } + plot.addDomainMarker(i, marker, Layer.FOREGROUND); + } + } + + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + } + + @Override + public void dispose() { + if(timeListener != null) { + timeListener.dispose(); + timeListener = null; + } + + if(datasetListener != null) { + datasetListener.dispose(); + datasetListener = null; + } + } + + + @Override + public AbstractRenderer getRenderer() { + if(renderer == null) { + + try { + renderer = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public IRenderer perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + IRenderer renderer = null; + Resource rendererResource = graph.getPossibleObject(resource, jfree.Dataset_renderer); + if(rendererResource != null) + renderer = graph.adapt(rendererResource, IRenderer.class); + return renderer; + } + }); + } catch (DatabaseException e) { + } + if(renderer == null) { + XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, false); + renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); + return renderer; + } else { + return renderer.getRenderer(); + } + } else { + return renderer.getRenderer(); + } + } + + /** + * Get the realization uri of the current dataset resource + * @param graph ReadGraph + * @return realization uri for current dataset resource + * @throws DatabaseException + */ + public static String getRealizationURI(ReadGraph graph, Resource resource) throws DatabaseException { + if(resource == null) + return null; + + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + + // Find the model where the chart is located + Resource model = resource; + do { + model = graph.getPossibleObject(model, l0.PartOf); + } while(model != null && !graph.isInstanceOf(model, mr.StructuralModel)); + + if(model == null) + return null; + + // Find the variable realization of the current experiment + String realizationURI = null; + Resource realization = graph.syncRequest(new PossibleActiveExperiment(model)); + if (realization == null) { + Layer0X L0X = Layer0X.getInstance(graph); + realization = graph.getPossibleObject(model, L0X.HasBaseRealization); + } + if (realization != null) + realizationURI = graph.getURI(realization); + + return realizationURI; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetRequest.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetRequest.java new file mode 100644 index 00000000..2a34593a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetRequest.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.awt.Color; +import java.util.ArrayList; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.request.Read; +import org.simantics.diagram.G2DUtils; +import org.simantics.jfreechart.chart.IRenderer; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.Functions; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.adapter.VariableRVIUtils; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.utils.datastructures.Pair; + +public class XYDatasetRequest implements Read, IRenderer>>{ + + protected Resource dataset; + + public XYDatasetRequest(Resource dataset) { + this.dataset = dataset; + } + + @Override + public Pair, IRenderer> perform(ReadGraph graph) throws DatabaseException { + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + + // Renderer + IRenderer renderer = null; + Resource rendererResource = graph.getPossibleObject(dataset, jfree.Dataset_renderer); + if(rendererResource != null) + renderer = graph.adapt(rendererResource, IRenderer.class); + + ArrayList series = new ArrayList(); + + String realizationURI = XYDataset.getRealizationURI(graph, dataset); + + if(realizationURI == null) + return new Pair, IRenderer>(series, renderer); // No experiment -> No results + + // Get a variable for the x-axis (if not time) + double[] domainValues = null; + Resource domainAxis = graph.getPossibleObject(dataset, jfree.Dataset_mapToDomainAxis); + if(domainAxis != null) { + String rvi = graph.getPossibleRelatedValue(domainAxis, jfree.variableRVI); + if(rvi != null && !rvi.isEmpty()) { + try { + Variable domainVariable = Variables.getVariable(graph, realizationURI + rvi); + Variable valuesVariable = domainVariable.browsePossible(graph, "#" + Functions.VALUES +"#"); + if(valuesVariable != null) { + double[][] valuesArray = valuesVariable.getValue(graph); + if(valuesArray.length > 0) + domainValues = valuesArray[0]; + } + } catch(MissingVariableException e) { + //Do nothing, use time as domain axis + } + } + } + + Resource seriesList = graph.getPossibleObject(dataset, jfree.Dataset_seriesList); + + // Get properties for all series + if(seriesList != null) { + for(Resource r : ListUtils.toList(graph, seriesList)) { + String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI); + if(rvi == null) + continue; + + try { + // Get visual properties + Integer width = graph.getPossibleRelatedValue(r, jfree.Series_lineWidth, Bindings.INTEGER); + if(width == null) width = 1; + + Resource c = graph.getPossibleObject(r, jfree.color); + Color color = c == null ? null : G2DUtils.getColor(graph, c); + + String label = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasLabel); + + // Get a variable for the series + Variable v = Variables.getVariable(graph, realizationURI + rvi); + if(v == null) + return new Pair, IRenderer>(series, renderer); + + // Get values + Variable dsVariable = v.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#"); + Object object = null; + if(dsVariable != null) + object = dsVariable.getValue(graph); + + if(object == null || !(object instanceof ArrayList)) + return new Pair, IRenderer>(series, renderer); + + ArrayList datasets = new ArrayList(); + + for(Object o : (ArrayList)object) { + if(o instanceof SysdynDataSet) + datasets.add((SysdynDataSet)o); + } + + + String[] filter = graph.getPossibleRelatedValue(r, jfree.variableFilter); + if(filter != null) { + ArrayList result2 = VariableRVIUtils.getDataset(datasets, filter); + if(result2 != null) { + datasets = result2; + } + } + + for(SysdynDataSet dataset : datasets) { + double[] va = dataset.values; + + // Get domain axis values (time OR other variable) + double[] ta; + if(domainValues != null) { + ta = domainValues; + + // If domainAxis is other than time, parameter values size is different. + if(domainValues.length > va.length) { + double value = va[0]; + va = new double[domainValues.length]; + for(int i = 0; i < domainValues.length; i++) + va[i] = value; + } + + // If domainAxis is a parameter, the domainValues array is too short + if(domainValues.length < va.length && domainValues.length == 2 && domainValues[0] == domainValues[1]) { + double value = domainValues[0]; + ta = new double[va.length]; + for(int i = 0; i < va.length; i++) + ta[i] = value; + } + + } else { + ta = dataset.times; + } + + if(ta!=null && va!=null && (va.length == ta.length)) { + // Add series if everything OK + String name = dataset.name; + if(label != null) + name = label; + if (dataset.resultIndex != null) { + name += "(" + dataset.resultIndex + ")"; + } + if(dataset.result != null && !dataset.result.isEmpty()) + name = name + " : " + dataset.result; + if(ta.length != 0 && va.length != 0) { + XYDatasetTempSeries tempSeries = new XYDatasetTempSeries(name, new double[][] {ta, va}, width, color); + getAdditionalSeriesProperties(graph, r, tempSeries); + series.add(tempSeries); + + } + + } + } + + } catch (MissingVariableException e) { + // Do nothing, if variable was not found. Move on to the next series + } + } + } + return new Pair, IRenderer>(series, renderer); + } + + + protected void getAdditionalSeriesProperties(ReadGraph graph, Resource r, XYDatasetTempSeries tempSeries) throws DatabaseException { + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetTempSeries.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetTempSeries.java new file mode 100644 index 00000000..d919baea --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetTempSeries.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.trend; + +import java.awt.Color; +import java.util.HashMap; + +/** + * Container class for holding XYDataset series + * @author Teemu Lempinen + * + */ +public class XYDatasetTempSeries { + + public double[][] values; + public String name; + public int width; + public Color color; + public HashMap properties = new HashMap(); + + public XYDatasetTempSeries(String name, double[][] values, int width, Color color) { + this.name = name; + this.values = values; + this.width = width; + this.color = color; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ArrayVariableUtils.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ArrayVariableUtils.java new file mode 100644 index 00000000..d6f024e1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ArrayVariableUtils.java @@ -0,0 +1,156 @@ +package org.simantics.sysdyn.ui.utils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.EnumerationIndex; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Variable; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField; +import org.simantics.sysdyn.utils.ModelUtils; + +public class ArrayVariableUtils { + + + /** + * Checks if the given range elements can be applied to the given variable. + * + * @param graph ReadGraph + * @param variable Resource of the variable + * @param range Range elements in the correct order. Elements are separated in range definition by ',' + * @return true if range is valid, false if not + * @throws DatabaseException + */ + public static Map isRangeValid(ReadGraph graph, Variable variable, String[] elements) throws DatabaseException { + SyntaxError error; + if(variable == null) + return null; + Map result = new HashMap(); + // Not an array variable + if(variable.getArrayIndexes() == null || + variable.getArrayIndexes() == null || + variable.getArrayIndexes().size() == 0) { + for(int i = 0; i < elements.length ; i++) { + error = new SyntaxError(); + error.setMessage("Variable is not an array variable"); + error.setType(ExpressionField.SYNTAX_ERROR); + result.put(i, error); + } + + return result; + } + ArrayList enumerations = variable.getArrayIndexes(); + // Too many elements + if(elements.length > enumerations.size()) { + error = new SyntaxError(); + error.setMessage( "Too many elements"); + error.setType(ExpressionField.SYNTAX_ERROR); + result.put(enumerations.size(), error); + } else if(elements.length < enumerations.size()) { + error = new SyntaxError(); + error.setMessage("Too few elements"); + error.setType(ExpressionField.SYNTAX_ERROR); + result.put(elements.length > 0 ? elements.length - 1 : 0, error); + } + + + for(int i = 0; i < elements.length && i < enumerations.size(); i++) { + if(elements[i].trim().equals(":")) + continue; + if(elements[i].indexOf(":") != elements[i].lastIndexOf(":")) { + error = new SyntaxError(); + error.setMessage( "Too many ':' elements"); + error.setType(ExpressionField.SYNTAX_ERROR); + result.put(i, error); + continue; + } + + String[] rangeComponents = elements[i].split(":"); + if(rangeComponents.length > 2){ + error = new SyntaxError(); + error.setMessage( "Too many ':' elements"); + error.setType(ExpressionField.SYNTAX_ERROR); + result.put(i, error); + continue; + } + // Single range component, equals to the enumeration at that index + if(rangeComponents.length == 1 && rangeComponents[0].trim().equals(enumerations.get(i).getName())) + continue; + // one or two range components, they all equal to individual indexes in the enumeration + for(String r : rangeComponents) { + r = r.trim(); + boolean componentIsValid = false; + Enumeration enumeration = enumerations.get(i); + for(EnumerationIndex ei : enumeration.getEnumerationIndexes()) { + if(ei.getName().equals(r)) { + componentIsValid = true; + break; + } + } + if(!componentIsValid && r.length() > 0) { + // Check if the range is an integer that is between 0 and enumeration indexes size + try { + int index = Integer.parseInt(r); + int min = 1; + int max = enumeration.getEnumerationIndexes().size(); + if(index >= min && index <= max || enumeration.isReplaceable()) { + componentIsValid = true; + error = new SyntaxError(); + error.setMessage("Using numbers as array indexes is not encouraged"); + error.setType(ExpressionField.SYNTAX_WARNING); + result.put(i, error); + } else { + error = new SyntaxError(); + error.setMessage("Invalid array index " + index + ". Numbered index must be between " + min + " and " + max); + error.setType(ExpressionField.SYNTAX_ERROR); + result.put(i, error); + } + } catch (NumberFormatException e) { + error = new SyntaxError(); + error.setMessage("Invalid range"); + error.setType(ExpressionField.SYNTAX_ERROR); + result.put(i, error); + } + } + } + } + if(result.isEmpty()) + return null; + else + return result; + } + + /** + * Checks if the given range can be applied to the given variable. + * + * @param graph ReadGraph + * @param variable Resource of the variable + * @param range Range WITHOUT [ and ] brackets + * @return true if range is valid, false if not + * @throws DatabaseException + */ + public static boolean isRangeValid(ReadGraph graph, Resource variable, String range) throws DatabaseException { + if(variable == null) + return true; + String[] elements = range.split(","); + SysdynModel model = ModelUtils.getModel(graph, variable); + if(model == null) + return false; + IElement e = model.getElement(variable); + if(e != null && e instanceof Variable) { + Variable v = (Variable) e; + if(isRangeValid(graph, v, elements) == null) + return true; + else + return false; + } else { + return false; + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java new file mode 100644 index 00000000..70a0d43f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java @@ -0,0 +1,647 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.utils; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.jface.resource.ColorDescriptor; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.text.Position; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.expressionParser.Token; +import org.simantics.sysdyn.expressionParser.TokenMgrError; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.EnumerationIndex; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Model; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.Sheet; +import org.simantics.sysdyn.representation.Variable; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField; +import org.simantics.sysdyn.ui.properties.widgets.expressions.IExpression; +import org.simantics.ui.SimanticsUI; + +public class ExpressionUtils { + + /** + * Determines if the given expression is a parameter expression. Parameters are numbers. + * If the expression contains anything other than numbers, it is not a parameter. + * + * @param expression The expression to be checked + * @return is the expression a parameter + */ + static public boolean isParameter(String expression) { + try { + /* + StringTokenizer st = new StringTokenizer(expression, "{}[],;"); + while(st.hasMoreTokens()) { + Double.parseDouble(st.nextToken().trim()); + } + */ + Double.parseDouble(expression.trim()); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + /** + * Color for a variable found in an expression field, used in shortcut tab. + * This is a bit silly means of communicating the state of a variable using its color. + * @param resourceManager LocalResourceManager for which the color is created. + * @return Color for such variable. + */ + public static Color variableFoundColor(LocalResourceManager resourceManager) { + return resourceManager.createColor(ColorDescriptor.createFrom(new RGB(0,0,0))); + } + + /** + * Color for a variable not found in an expression field, used in shortcut tab. + * This is a bit silly means of communicating the state of a variable using its color. + * @param resourceManager LocalResourceManager for which the color is created. + * @return Color for such variable. + */ + public static Color variableNotFoundColor(LocalResourceManager resourceManager) { + return resourceManager.createColor(ColorDescriptor.createFrom(new RGB(255,125,0))); + } + + /** + * Color for a variable itself and for the time variable, used in shortcut tab. + * This is a bit silly means of communicating the state of a variable using its color. + * @param resourceManager LocalResourceManager for which the color is created. + * @return Color for such variable. + */ + public static Color variableTimeAndSelfColor(LocalResourceManager resourceManager) { + return resourceManager.createColor(ColorDescriptor.createFrom(new RGB(127,127,127))); + } + + /** + * Validates the expressionfield of a given IExpression + * + * @param expression The expression whose fields are validated + * @param resourceManager + * @param connectedVariables Table items from the shortcut widget. (Items needed so that they can be coloured) + * @param configuration configuration where the variable is located + */ + static public void validateExpressionFields(final Resource variable, + IExpression expression, + Table variableTable, + LocalResourceManager resourceManager) { + if(variable == null || expression == null || variableTable == null) + return; + + Resource configuration = null; + try { + configuration = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource configuration = variable; + while (configuration != null) { + configuration = graph.getPossibleObject(configuration, Layer0.getInstance(graph).PartOf); + + if(configuration == null || graph.isInstanceOf(configuration, sr.Configuration)) { + break; + } + } + return configuration; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + return; + } + + if(configuration == null) + return; + + ExpressionParser parser = new ExpressionParser(new StringReader("")); + Set variables = new HashSet(); + HashMap>> references = new HashMap>>(); + final HashMap>>> ranges = new HashMap>>>(); + HashMap>> forIndices = new HashMap>>(); + HashMap>> enumerationReferences = new HashMap>>(); + HashMap>> functionReferences = new HashMap>>(); + + // Build references and variable array + boolean parsingSucceeded = false; + for(ExpressionField ef : expression.getExpressionFields()) { + ef.resetAnnotations(); + String textString = ef.getExpression(); + parser.ReInit(new StringReader(textString)); + try { + parser.expr(); + HashMap> refs = parser.getReferences(); + references.put(ef, refs); + variables.addAll(refs.keySet()); + + ranges.put(ef, parser.getRanges()); + + forIndices.put(ef, parser.getForIndices()); + + enumerationReferences.put(ef, parser.getEnumerationReferences()); + + functionReferences.put(ef, parser.getFunctionCallReferences()); + + parsingSucceeded = true; + } catch (ParseException e1) { + ef.setSyntaxError(new SyntaxError(e1.currentToken, "Syntax Error")); + + /* + * If the equation is empty, set the parsingSucceeded = true + * to allow the coloring of the variables succeed. + */ + if (textString.equals("")) { + parsingSucceeded = true; + } + } catch (TokenMgrError err) { + ef.setSyntaxError(new SyntaxError(0, textString.length(), ExpressionField.SYNTAX_ERROR, "Expression contains unsupported characters")); + } + } + + + // Get model configuration + SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession()); + SysdynModel model = sdm.getModel(configuration); +// try { +// model.update(); +// } catch (DatabaseException e1) { +// e1.printStackTrace(); +// } + Configuration conf = model.getConfiguration(); + + // Check variable references + final HashMap modelVariables = new HashMap(); + HashSet ignoreVariables = new HashSet(); + if(!variables.isEmpty() || !functionReferences.isEmpty()) { + Set noSuchVariables = new HashSet(); + ArrayList elements = conf.getElements(); + for(IElement e : elements) { + if(e instanceof Variable) { + Variable v = (Variable) e; + modelVariables.put(v.getName(), v); + } else if(e instanceof Module) { + ignoreVariables.add(((Module)e).getName()); + } + } + + // VARIABLE NAMES + + if(variables.contains("time")) + variables.remove("time"); + + // Remove variable references to for indices + for(ExpressionField ef : forIndices.keySet()) { + for(Token t : forIndices.get(ef).keySet()) { + if(variables.contains(t.image)) + variables.remove(t.image); + } + } + + // Examine sheets + for(ExpressionField ef : functionReferences.keySet()) { + for(String key : functionReferences.get(ef).keySet()) { + + List errors = examineSheetReferences(conf, key, functionReferences.get(ef).get(key), ef.getExpression(), references.get(ef)); + if(errors != null) { + for(SyntaxError error : errors) + ef.setSyntaxError(error); + } + } + } + + // Examine variable references + for(String v : variables) { + ReferenceOption option = getReferenceOption(conf, v); + switch(option) { + case DOES_NOT_EXIST: + noSuchVariables.add(v); + break; + case CANNOT_BE_CONNECTED: + ignoreVariables.add(v); + break; + case CAN_BE_CONNECTED: + } + } + + if(!noSuchVariables.isEmpty()) { + noSuchVariables.removeAll(ignoreVariables); + // remove no such variables from variable list + for(String s : noSuchVariables) + variables.remove(s); + // create annotations + HashMap> positions = getPositionsForVariables(references, noSuchVariables); + for(ExpressionField ef : positions.keySet()) { + ef.setNoSuchVariableAnnotations(positions.get(ef)); + } + } + } + + // Check that the variables that exist have connections and the connected variables have references in the expressions + // If there are syntax errors, keep the previous coloring. + String selfName = null; + if(variableTable != null && !variableTable.isDisposed()) { + + // Get the name of the variable itself + try { + selfName = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Object selfName = graph.getPossibleRelatedValue(variable, l0.HasName); + if(selfName != null) { + return (String)selfName; + } + return null; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // Color the items in the table + TableItem[] connectedVariables = variableTable.getItems(); + for(TableItem ti : connectedVariables) { + if (ti.getText().equals("time") || ti.getText().equals(selfName)) { + ti.setForeground(variableTimeAndSelfColor(resourceManager)); + } else if (parsingSucceeded && !variables.contains(ti.getText())) { + ti.setForeground(variableNotFoundColor(resourceManager)); + } else if (parsingSucceeded) { + ti.setForeground(variableFoundColor(resourceManager)); + variables.remove(ti.getText()); + } + } + + // Remove all enumerations and sheets, they cannot have connections + variables.removeAll(ignoreVariables); + + // Always remove self + variables.remove(selfName); + + if(!variables.isEmpty()) { + HashMap> positions = getPositionsForVariables(references, variables); + for(ExpressionField ef : positions.keySet()) { + ef.setMissingLinkAnnotations(positions.get(ef)); + } + + } + } + + for(final ExpressionField ef : ranges.keySet()) { + List errors = new ArrayList(); + // RANGES + errors.addAll(examineArrayRanges(conf, ranges.get(ef), forIndices.get(ef))); + + // ENUMERATION REFERENCES IN FOR-LOOPS + errors.addAll(examineEnumerationReferences(conf, enumerationReferences.get(ef))); + + for(SyntaxError error : errors) + ef.setSyntaxError(error); + } + } + + + static public List examineArrayRanges( + final Configuration configuration, + final HashMap>> ranges, + final HashMap> forIndices) { + + List result = Collections.emptyList(); + try { + result = SimanticsUI.getSession().syncRequest(new Read>() { + + @Override + public List perform(ReadGraph graph) throws DatabaseException { + return examineArrayRanges(graph, configuration, ranges, forIndices); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return result; + } + + static public List examineEnumerationReferences(Configuration configuration, HashMap> enumRefList) { + ArrayList result = new ArrayList(); + for(String enumeration : enumRefList.keySet()) { + for(Token et : enumRefList.get(enumeration)) { + Object o = getElement(configuration, enumeration); + if(o != null && o instanceof Enumeration) { + boolean isFound = false; + Enumeration e = (Enumeration)o; + + if(enumeration.equals(et.image) || + "size".equals(et.image) || + "elements".equals(et.image)){ + // The full enumeration + isFound = true; + } else { + for(EnumerationIndex ei : e.getEnumerationIndexes()) { + if(ei.getName().equals(et.image)) { + isFound = true; + break; + } + } + } + + if(!isFound) { + StringBuilder sb = new StringBuilder(); + sb.append("Enumeration "); + sb.append(enumeration); + sb.append(" has no such index.\nAvailable indexes are: "); + Iterator iterator = e.getEnumerationIndexes().iterator(); + while(iterator.hasNext()) { + sb.append(iterator.next().getName()); + if(iterator.hasNext()) + sb.append(", "); + } + result.add(new SyntaxError(et, sb.toString())); + } + + + } else { + result.add(new SyntaxError(et, "No such enumeration (" + enumeration + ")")); + } + } + } + return result; + } + + /** + * + * @param graph + * @param configuration + * @param ranges + * @param forIndices + * @return + * @throws DatabaseException + */ + static public List examineArrayRanges( + ReadGraph graph, + Configuration configuration, + HashMap>> ranges, + HashMap> forIndices) throws DatabaseException { + HashMap errors = new HashMap(); + for(String name : ranges.keySet()) { + if(ranges.get(name) != null) { + for(List l : ranges.get(name)) { + String[] rangeReferences = new String[l.size()]; + for(int i = 0; i < l.size(); i++) { + rangeReferences[i] = l.get(i).image; + } + + Object o = getElement(configuration, name); + if(o != null && o instanceof Variable) { + Map invalidRanges = ArrayVariableUtils.isRangeValid(graph, (Variable)o, rangeReferences); + if(invalidRanges != null && !invalidRanges.isEmpty()) { + for(Integer i : invalidRanges.keySet()) { + SyntaxError error = invalidRanges.get(i); + error.setToken(l.get(i)); + errors.put(l.get(i), error); + } + } + } + } + } + } + + + // FOR-INDICES + + HashSet removes = new HashSet(); + for(Token t : forIndices.keySet()) { +// boolean isFound = false; + for(Token rt : errors.keySet()) { + if(rt.image.equals(t.image)) { +// isFound = true; + // remove range token from invalid ranges + removes.add(rt); + } + } +// Why would this be invalid if the index just is not used anywhere? +// {1+2 for i in range} + +// if(!isFound) { +// SyntaxError error = new SyntaxError(t, "Invalid index"); +// errors.put(t, error); +// } + } + + for(Token t : removes) + errors.remove(t); + + return new ArrayList(errors.values()); + } + + + /** + * Examine if a given functionKey is a sheet reference and whether all the tokens in the function ( Sheet1(token1, token2) ) + * are valid. + * + * @param configuration Configuration where the function is called + * @param functionKey Function name + * @param functionTokens Function parameters (sheet reference, either a cell or cell range) + * @param expression The whole expression where the function reference is + * @param expressionReferences All variable references, including function parameters + * @return A list of possible errors + */ + static public List examineSheetReferences( + Configuration configuration, + String functionKey, + List functionTokens, + String expression, + HashMap> expressionReferences) { + + List result = new ArrayList(); + + String[] parts = functionKey.split("\\."); + Object current = configuration; + for(int i = 0; i < parts.length && current != null; i++) { + current = getElement(current, parts[i]); + } + + if(current == null && configuration.getModuleType() != null) { + // Sheets are currently located in the model root. Try to find the sheet. + current = configuration.getModuleType().getParent(); // Get module type parent (should be a model) + if(current instanceof Model) + current = getElement(((Model)current).getModelConfiguration(), parts[0]); // Try to get the sheet + } + + if(current != null && current instanceof Sheet) { + Sheet sheet = (Sheet) current; + int start = 0, end = 0, call = 0; + String cellOrRange = null; + while((call = expression.indexOf(functionKey, end)) >= 0) { + start = expression.indexOf("(", call) +1; + end = expression.indexOf(")", start); + if(start < 0 || end < 0 || end < start) { + break; + } + Pattern p = Pattern.compile("[-\\+\\*\\/\\(\\)\\{\\}\\[\\],\\.\\t\\n\\r\\f]"); + cellOrRange = expression.substring(start, end); + Matcher m = p.matcher(cellOrRange); + if (m.find() || cellOrRange.split(":").length > 2) { + result.add(new SyntaxError(start, end - start, ExpressionField.SYNTAX_ERROR, "Not a valid cell or range", cellOrRange)); + } + } + + + for(Token cell : functionTokens) { + List refs = expressionReferences.get(cell.image); + if(refs != null) + refs.remove(cell); + if(!sheet.getCells().containsKey(cell.image)) + result.add(new SyntaxError(cell.image, "Invalid cell", cell.beginLine, cell.beginColumn, cell.endLine, cell.endColumn)); + } + + } + + return result; + } + + + /** + * Option for a reference. Whether the reference does not exist, + * it can be connected (normal variable) or it cannot be + * connected even though it exists (e.g. enumeration index) + * + * @author Teemu Lempinen + * + */ + static public enum ReferenceOption {DOES_NOT_EXIST, CAN_BE_CONNECTED, CANNOT_BE_CONNECTED}; + + /** + * Get the reference option for a reference (name) in a configuration. + * + * @param conf Configuration + * @param name Referred variable + * @return The result tells does the referred name exist and can it be connected to + */ + static public ReferenceOption getReferenceOption(Configuration conf, String name) { + + String[] parts = name.split("\\."); + Object element = conf; + for(int i = 0; i < parts.length && element != null; i++) { + element = getElement(element, parts[i]); + } + if(element == null) + return ReferenceOption.DOES_NOT_EXIST; + else if(Boolean.TRUE.equals(element)) + return ReferenceOption.CANNOT_BE_CONNECTED; + else if(element instanceof Variable || element instanceof Module) { + if(element instanceof Enumeration || element instanceof Sheet || element instanceof Module || parts.length > 1) + return ReferenceOption.CANNOT_BE_CONNECTED; + else + return ReferenceOption.CAN_BE_CONNECTED; + } + else + return ReferenceOption.DOES_NOT_EXIST; + } + + static private Object getElement(Object parent, String name) { + Configuration c = null; + if(parent instanceof Module) { + Module m = (Module)parent; + c = m.getType().getConfiguration(); + } else if (parent instanceof Configuration) { + c = (Configuration)parent; + } + + if(c != null) { + for(IElement e : c.getElements()) { + if(e instanceof Variable && ((Variable)e).getName().equals(name)) { + return e; + } else if(e instanceof Module && ((Module)e).getName().equals(name)) { + return e; + } + } + } else if(parent instanceof Sheet) { + Sheet s = (Sheet)parent; + for(String key : s.getCells().keySet()) { + if(key.equals(name)) { + return Boolean.TRUE; + } + } + + } else if(parent instanceof Enumeration) { + Enumeration e = (Enumeration)parent; + if(name.equals("size") || name.equals("elements")) + return Boolean.TRUE; + + for(EnumerationIndex ei : e.getEnumerationIndexes()) { + if(ei.getName().equals(name)) { + return Boolean.TRUE; + } + } + + } + + return null; + } + + @SuppressWarnings("unchecked") + static private HashMap> getPositionsForVariables(HashMap>> references, Set variables) { + HashMap> result = new HashMap>(); + for(String s : variables) { + List tlist = new ArrayList(); + for(ExpressionField ef : references.keySet()) { + ArrayList positions = new ArrayList(); + tlist = references.get(ef).get(s); + if(tlist != null) + for(Token t : tlist) { + StyledText st = ef.getSourceViewer().getTextWidget(); + if (st != null) { + int start = st.getOffsetAtLine(t.beginLine - 1) + t.beginColumn - 1; + int offset = st.getOffsetAtLine(t.endLine - 1) + t.endColumn - start; + positions.add(new Position( + start, + offset)); + } + } + if(result.keySet().contains(ef)) { + result.get(ef).addAll((ArrayList)positions.clone()); + } else { + result.put(ef, (ArrayList)positions.clone()); + } + } + } + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionLibraryNameValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionLibraryNameValidator.java new file mode 100644 index 00000000..bf67e477 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionLibraryNameValidator.java @@ -0,0 +1,74 @@ +package org.simantics.sysdyn.ui.utils; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; + +/** + * Name validator for function libraries. + * @author Tuomas Miettinen + * + */ +public class FunctionLibraryNameValidator extends NameValidator { + + @Override + protected boolean nameIsTaken(ReadGraph graph, Resource functionLibrary, String name) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + + if(functionLibrary == null) + return false; + + Resource containingLibrary = graph.getPossibleObject(functionLibrary, l0.PartOf); + if(containingLibrary == null) + return true; + + // Check if the function is right under the model. + if (graph.isInstanceOf(containingLibrary, sr.SysdynModel)) { + Resource configurationResource = graph.getPossibleObject(containingLibrary, SIMU.HasConfiguration); + if(configurationResource == null) + return true; + SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource); + sysdynModel.update(graph); + + if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, null, name)) return true; + + // Check that the functioLibrary name != model name (== containingLibrary name) + if (NameUtils.getSafeName(graph, containingLibrary).equals(name)) return true; + + if (nameTakenByBuiltInFunction(graph, name)) return true; + + if (nameTakenBySharedFunctionLibrary(graph, containingLibrary, null, name)) return true; + + if (nameTakenBySheet(sysdynModel, name)) return true; + } + + // Containing library may also be the model + if (nameTakenByItemUnderLibrary(graph, containingLibrary, functionLibrary, name)) return true; + + return false; + } + + @Override + public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName) + throws DatabaseException { + // TODO Auto-generated method stub + + } + + @Override + public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName) + throws DatabaseException { + // TODO Auto-generated method stub + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionNameValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionNameValidator.java new file mode 100644 index 00000000..95b7d974 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionNameValidator.java @@ -0,0 +1,70 @@ +package org.simantics.sysdyn.ui.utils; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; + +/** + * Name validator for functions. + * @author Tuomas Miettinen + * + */ +public class FunctionNameValidator extends NameValidator { + + @Override + public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName) throws DatabaseException { + // TODO + } + + @Override + public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName) throws DatabaseException { + // TODO + } + + @Override + protected boolean nameIsTaken(ReadGraph graph, Resource function, String name) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + + if(function == null) + return false; + + Resource library = graph.getPossibleObject(function, l0.PartOf); + if(library == null) + return true; + + // Check if the function is right under the model. + if (graph.isInstanceOf(library, sr.SysdynModel)) { + Resource configurationResource = graph.getPossibleObject(library, SIMU.HasConfiguration); + if(configurationResource == null) + return true; + SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource); + sysdynModel.update(graph); + + if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, null, name)) return true; + + // Check that the function name != model name (== library name) + if (NameUtils.getSafeName(graph, library).equals(name)) return true; + + if (nameTakenByBuiltInFunction(graph, name)) return true; + + if (nameTakenBySharedFunctionLibrary(graph, library, null, name)) return true; + + if (nameTakenBySheet(sysdynModel, name)) return true; + } + + // Containing library may also be the model + if (nameTakenByItemUnderLibrary(graph, library, function, name)) return true; + + return false; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/HandlerUtils.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/HandlerUtils.java new file mode 100644 index 00000000..cfc88559 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/HandlerUtils.java @@ -0,0 +1,49 @@ +package org.simantics.sysdyn.ui.utils; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.simantics.sysdyn.ui.properties.RemoveFocusBeforeExperimentComposite; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionComposite; + +/** + * Utility methods for handlers. + * @author Tuomas Miettinen + * + */ +public class HandlerUtils { + + /** + * Save the equation of EquationTab, if the keyboard focus is somewhere inside an EquationTab. + * + * @param event ExecutionEvent of which triggering event is used to determine who has focus. + */ + public static void saveBeforeExperimentRun(ExecutionEvent event) { + if (event.getTrigger() instanceof Event) { + Event trigger = (Event)event.getTrigger(); + Control focusControl = trigger.display.getFocusControl(); + if(focusControl == null) { + new Exception( + "Could not determine, if equation needs to be saved before action. focusControl == null") + .printStackTrace(); + return; + } + Composite parent = focusControl.getParent(); + + /* Scan bottom-up if we come across an EquationTab. + * If so, ask it to save the expression.*/ + while (parent != null) { + if (parent instanceof ExpressionComposite) { + ExpressionComposite expressionComposite = (ExpressionComposite)parent; + expressionComposite.saveExpression(); + break; + } else if(parent instanceof RemoveFocusBeforeExperimentComposite) { + focusControl.getParent().forceFocus(); + break; + } + parent = parent.getParent(); + } + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelNameValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelNameValidator.java new file mode 100644 index 00000000..ec53c882 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelNameValidator.java @@ -0,0 +1,56 @@ +package org.simantics.sysdyn.ui.utils; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; + +/** + * Name validator for model. + * @author Tuomas Miettinen + * + */ +public class ModelNameValidator extends NameValidator { + + @Override + protected boolean nameIsTaken(ReadGraph graph, Resource model, String name) throws DatabaseException { + SimulationResource SIMU = SimulationResource.getInstance(graph); + + if(model == null) + return false; + + if (nameTakenByFunctionFunctionLibraryOrModuleType(graph, model, name)) return true; + + Resource configurationResource = graph.getPossibleObject(model, SIMU.HasConfiguration); + if(configurationResource == null) + return true; + SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource); + sysdynModel.update(graph); + + if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, null, name)) return true; + + if (nameTakenByBuiltInFunction(graph, name)) return true; + + if (nameTakenBySharedFunctionLibrary(graph, model, null, name)) return true; + + if (nameTakenBySheet(sysdynModel, name)) return true; + + return false; + } + + @Override + public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName) + throws DatabaseException { + + } + + @Override + public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName) + throws DatabaseException { + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModuleTypeNameValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModuleTypeNameValidator.java new file mode 100644 index 00000000..8a3c851c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModuleTypeNameValidator.java @@ -0,0 +1,84 @@ +package org.simantics.sysdyn.ui.utils; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; + +/** + * Name validator for module types. + * @author Tuomas Miettinen + * + */ +public class ModuleTypeNameValidator extends NameValidator { + + @Override + protected boolean nameIsTaken(ReadGraph graph, Resource moduleTypeSymbol, String name) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + if(moduleTypeSymbol == null) + return false; + + Resource moduleType; + if (graph.isInheritedFrom(moduleTypeSymbol, sr.Module)) { + // Renamed in model browser + moduleType = moduleTypeSymbol; + } else { + // Renamed in ModuleTypeTab + moduleType = graph.getPossibleObject(moduleTypeSymbol, mr.SymbolToComponentType); + } + if(moduleType == null) + return true; + + // All ModuleTypes are under the top level model + Resource model = graph.getPossibleObject(moduleType, l0.PartOf); + if(model == null) + return true; + + Resource configurationResource = graph.getPossibleObject(model, SIMU.HasConfiguration); + if(configurationResource == null) + return true; + SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource); + sysdynModel.update(graph); + + if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, null, name)) return true; + + // Check that the module name != model name + if (NameUtils.getSafeName(graph, model).equals(name)) return true; + + if (nameTakenByBuiltInFunction(graph, name)) return true; + + if (nameTakenBySharedFunctionLibrary(graph, model, null, name)) return true; + + if (nameTakenBySheet(sysdynModel, name)) return true; + + if (nameTakenByItemUnderLibrary(graph, model, moduleType, name)) return true; + + return false; + } + + @Override + public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName) + throws DatabaseException { + // TODO Auto-generated method stub + + } + + @Override + public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName) + throws DatabaseException { + // TODO Auto-generated method stub + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/NameValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/NameValidator.java new file mode 100644 index 00000000..b86d035b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/NameValidator.java @@ -0,0 +1,377 @@ +package org.simantics.sysdyn.ui.utils; + +import java.util.Collection; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.spreadsheet.resource.SpreadsheetResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.Sheet; +import org.simantics.sysdyn.representation.Variable; +import org.simantics.sysdyn.ui.modelica.ModelicaSourceViewerConfiguration; +import org.simantics.sysdyn.utils.Function; +import org.simantics.ui.SimanticsUI; + + +/** + * This class is used when renaming an element to check that there + * are no elements in the database that would cause a conflict. There + * are two kinds of different conflicts: + * 1) There is an element in the database which has the same URI. + * Adding another causes damage or even a fatal corruption in the + * database. + * 2) Multiple different elements in the database are accessed with + * identical identifiers in the generated Modelica model. This will + * prevent the simulation from running. + * + * @author Tuomas Miettinen + * @author Teemu Lempinen + * + */ +public abstract class NameValidator { + + /** + * This method tells the validator whether the proposed name is taken. To be more precise, + * it tells if the proposed name should not be used for any reason. E.g. similarly named + * resources cause problems in some occasions and are fine in others. In addition, there + * (at least )are two reasons to decline a name proposition: firstly, the data base might + * have a similarly named entity, and secondly, accepting a proposed name would lead in + * naming conflicts in the generated OpenModelica model. + * + * @param graph + * @param resource the Resource which is being renamed + * @param name the proposed name + * @return true iff the name proposition is denied + * @throws DatabaseException + */ + protected abstract boolean nameIsTaken(ReadGraph graph, Resource resource, String name) throws DatabaseException; + + /** + * Replaces variable names in all the expressions in the defined configuration. + * Replace doesn't have to replace words in other configurations than the configuration where the renamed variable is + * because input variables handle the transitions between configurations (modules). + * + * @param graph WriteGraph + * @param configuration The configuration where the renamed variable is located + * @param originalName The original name of the variable + * @param newName New name of the variable + */ + public abstract void renameInEquations(WriteGraph graph, Resource resource, String originalName, String newName) throws DatabaseException; + + public abstract void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName) throws DatabaseException; + + /** + * Checks that the syntax of the given name is valid and there + * are no other functions that have the same name in neither the + * configuration nor among built in functions + * + * @param graph ReadGraph + * @param resource The variable that is being renamed + * @param name The new name of the variable + * @return true iff the new name is valid + * @throws DatabaseException + */ + public boolean isValid(ReadGraph graph, Resource resource, String name) throws DatabaseException { + // Decline empty string + if(name.length() < 1) return false; + + // Decline names based on the type of the resource + if(nameIsTaken(graph, resource, name)) return false; + + // Decline names which are against Modelica naming rules + boolean allowSpaces = doesResourceAllowSpacedName(graph, resource); + if(!isValidModelica(name, allowSpaces)) return false; + return true; + } + + /** + * Determine whether a Sysdyn Variable can have whitespace in its name (based on its type). + * @param graph + * @param resource Resource of the variable + * @return true iff spaces are allowed in the name + */ + protected boolean doesResourceAllowSpacedName(ReadGraph graph, + Resource resource) { + SysdynResource sr = SysdynResource.getInstance(graph); + SpreadsheetResource sheet = SpreadsheetResource.getInstance(graph); + try { + if (resource == null) + return false; + // Function, FunctionLibrary, and SharedFunctionLibrary are not + // allowed to have whitespace. + if (graph.isInstanceOf(resource, sr.Variable) +// || graph.isInstanceOf(resource, sr.Module) +// || graph.isInstanceOf(resource, sr.ModuleType) + || graph.isInstanceOf(resource, sr.Enumeration) + || graph.isInstanceOf(resource, sr.EnumerationIndex) + || graph.isInstanceOf(resource, sheet.Spreadsheet) + || graph.isInstanceOf(resource, sr.SysdynModel)) { + return true; + } + } catch (ServiceException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return false; + } + + /** + * Checks that the syntax of the given name is valid and there + * are no other variables that have the same name in the configuration + * + * @param variable The variable that is being renamed + * @param name The new name of the variable + * @return true iff the new name is valid + * @throws DatabaseException + */ + public boolean isValid(final Resource resource, final String name) { + boolean result = false; + + try { + result = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + return isValid(graph, resource, name); + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return result; + } + + /** + * Checks that the syntax of the given name is valid + * and that it is not a keyword in Modelica. + * + * @param name name that is validated + * @return true iff the syntax of the name is valid + */ + public boolean isValidModelica(String name, boolean allowSpaces) { + String lowerCase = name.toLowerCase(); + String pattern = "[a-zA-Z][a-zA-Z0-9]*" + (allowSpaces ? "( [a-zA-Z][a-zA-Z0-9]*)*" : ""); + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(lowerCase); + if (!m.matches()) { + return false; + } else { + String[] splitNames= name.split("\\s+"); + for (String splitName : splitNames) { + // Do not allow Modelica keywords to be a part of a whitespaced name + if (ModelicaSourceViewerConfiguration.keywords.contains(splitName)) { + return false; + } + } + } + return true; + } + + /** + * Checks that there is no similarly named spread sheet in the top level model. + * + * @param graph ReadGraph + * @param configurationResource Resource of the configuration of the model + * @param resource Resource being validated + * @param name proposed new name for resource + * @return + * @throws DatabaseException + */ + protected boolean nameTakenBySheet( + ReadGraph graph, + Resource configurationResource, + Resource resource, + String name) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph); + for (Resource r : graph.getObjects(configurationResource, l0.ConsistsOf)) { + if (graph.isInstanceOf(r, SHEET.Book)) { + for (Resource s : graph.getObjects(r, l0.ConsistsOf)) { + if (NameUtils.getSafeName(graph, s).equals(name) && !s.equals(resource)) { + return true; + } + } + // Assume only one book + break; + } + } + return false; + } + + /** + * Checks that there is no similarly named spread sheet in the top level model. + * + * @param sysdynModel the model + * @param name proposed new name for resource + * @return + */ + public boolean nameTakenBySheet( + SysdynModel sysdynModel, + String name) { + Configuration configuration = sysdynModel.getConfiguration(); + if (configuration == null) + return true; + for (IElement e : configuration.getElements()) { + if (e instanceof Sheet) { + if (((Sheet)e).getName().equals(name)) { + return true; + } + } + } + return false; + } + + /** + * Check that there are no similarly named functions, module types, or any + * other items in the same library. There are actually plenty of items that have + * to be avoided, probably all of them, they are all included in this test. + * + * @param graph ReadGraph + * @param library Resource which is studied + * @param resource Resource being validated + * @param name proposed new name for resource + * @return + * @throws DatabaseException + */ + protected boolean nameTakenByItemUnderLibrary( + ReadGraph graph, + Resource library, + Resource resource, + String name) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + for (Resource r : graph.getObjects(library, l0.ConsistsOf)) { + if (NameUtils.getSafeName(graph, r).equals(name) && !r.equals(resource)) { + return true; + } + } + return false; + } + + /** + * Check that there is no similarly named function library among shared function libraries. + * + * @param graph ReadGraph + * @param model resource of the top level model under which the resource is + * @param resource Resource being validated + * @param name proposed new name for resource + * @return + * @throws DatabaseException + */ + protected boolean nameTakenBySharedFunctionLibrary( + ReadGraph graph, + Resource model, + Resource resource, + String name) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Collection linkedResources = graph.getObjects(model, l0.IsLinkedTo); + for (Resource r : linkedResources) { + // Find the "Shared functions" library + if (graph.isInstanceOf(r, sr.SharedFunctionOntology)) { + if (NameUtils.getSafeName(graph, r).equals(name) && !r.equals(resource)) { + return true; + } + } + } + return false; + } + + /** + * Check that there is no similarly named function among built-in functions + * + * @param graph ReadGraph + * @param name name that is checked + * @return + * @throws DatabaseException + */ + protected boolean nameTakenByBuiltInFunction( + ReadGraph graph, + String name) throws DatabaseException { + for (Function f : Function.getAllBuiltInFunctions(graph)) { + if (f.getName().equals(name)) { + return true; + } + } + return false; + } + + /** + * Check that the top level of the model doesn't contain + * a variable or module with the same name. + * + * @param graph ReadGraph + * @param sysdynModel the model + * @param resource Resource being validated + * @param name proposed new name for resource + * @return + * @throws DatabaseException + */ + protected boolean nameTakenByTopLevelVariableOrModule( + ReadGraph graph, + SysdynModel sysdynModel, + Resource resource, + String name) throws DatabaseException { + Configuration configuration = sysdynModel.getConfiguration(); + if(configuration == null) + return true; + IElement current = sysdynModel.getElement(resource); + for(IElement e : configuration.getElements()) { + if(e instanceof Variable) { + Variable v = (Variable) e; + if(!v.equals(current) && v.getName() != null && v.getName().equals(name)) { + return true; + } + } else if (e instanceof Module) { + Module m = (Module)e; + if(!m.equals(current) && m.getName() != null && m.getName().equals(name)) { + return true; + } + } + } + return false; + } + + /** + * Check that there is no similarly named function, function library, + * or module type directly under a library + * + * This function should not be used by functions, function libraries, or module types + * + * @param graph ReadGraph + * @param library Resource which is studied + * @param name proposed new name for resource + * @return + * @throws DatabaseException + */ + protected boolean nameTakenByFunctionFunctionLibraryOrModuleType( + ReadGraph graph, + Resource library, + String name) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + for (Resource r : graph.getObjects(library, l0.ConsistsOf)) { + if (graph.isInstanceOf(r, sr.SysdynModelicaFunctionLibrary) + || graph.isInstanceOf(r, sr.SysdynModelicaFunction) + || graph.isInheritedFrom(r, sr.Module)) { + if (NameUtils.getSafeName(graph, r).equals(name)) { + return true; + } + } + } + return false; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/OldTransferableGraph1.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/OldTransferableGraph1.java new file mode 100644 index 00000000..558f5a33 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/OldTransferableGraph1.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.utils; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.serialization.Serializer; +import org.simantics.graph.representation.External; +import org.simantics.graph.representation.Identity; +import org.simantics.graph.representation.Internal; +import org.simantics.graph.representation.Root; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.graph.representation.Value; + + +/** + * Transferable graph datatype. + * See specification. + * @author Hannu Niemistö + */ +public class OldTransferableGraph1 { + public static Binding BINDING = Bindings.getBindingUnchecked(TransferableGraph1.class); + public static Serializer SERIALIZER = Bindings.getSerializerUnchecked(BINDING); + + public int resourceCount; + public Identity[] identities; + public int[] statements; + public Value[] values; + + public OldTransferableGraph1() { + } + + public OldTransferableGraph1(int resourceCount, Identity[] identities, + int[] statements, Value[] values) { + this.resourceCount = resourceCount; + this.identities = identities; + this.statements = statements; + this.values = values; + } + + public void print() { + System.out.println("Identities"); + for(Identity id : identities) { + System.out.print(" " + id.resource + " = "); + if(id.definition instanceof Root) { + Root def = (Root)id.definition; + System.out.println("ROOT(" + def.name + ")"); + } + else if(id.definition instanceof External) { + External def = (External)id.definition; + System.out.println("EXTERNAL(" + def.parent + ", " + def.name + ")"); + } + else if(id.definition instanceof Internal) { + Internal def = (Internal)id.definition; + System.out.println("INTERNAL(" + def.parent + ", " + def.name + ")"); + } + } + System.out.println("Statements:"); + for(int i=0;i 0) { + try { + start = document.getLineOffset(beginLine - 1) + beginColumn - 1; + } catch (BadLocationException e) { + //e.printStackTrace(); + } + } + return start; + } else { + return 0; + } + } + + /** + * Get offset data of the issue. If offset has not been set, + * document is used to calculate it. + * + * @param document + * @return + */ + public int getOffset(IDocument document) { + if(this.offset != null) + return this.offset; + else if(document != null){ + int start = getStart(document); + int offset = document.getLength(); + if(document.getLength() > 0) { + try { + offset = document.getLineOffset(endLine - 1) + endColumn - start; + } catch (BadLocationException e) { + //e.printStackTrace(); + } + } + return offset; + } else { + return 0; + } + } + + public void setToken(Token token){ + this.image = token.image; + this.beginLine = token.beginLine; + this.beginColumn = token.beginColumn; + this.endLine = token.endLine; + this.endColumn = token.endColumn; + } + + public void setToken(org.simantics.sysdyn.tableParser.Token token){ + this.image = token.image; + this.beginLine = token.beginLine; + this.beginColumn = token.beginColumn; + this.endLine = token.endLine; + this.endColumn = token.endColumn; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + + public int getBeginLine() { + return beginLine; + } + + public void setBeginLine(int beginLine) { + this.beginLine = beginLine; + } + + public int getBeginColumn() { + return beginColumn; + } + + public void setBeginColumn(int beginColumn) { + this.beginColumn = beginColumn; + } + + public int getEndLine() { + return endLine; + } + + public void setEndLine(int endLine) { + this.endLine = endLine; + } + + public int getEndColumn() { + return endColumn; + } + + public void setEndColumn(int endColumn) { + this.endColumn = endColumn; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SysdynWorkbenchUtils.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SysdynWorkbenchUtils.java new file mode 100644 index 00000000..987fce90 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SysdynWorkbenchUtils.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ + +package org.simantics.sysdyn.ui.utils; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.canvas.IToolMode; +import org.simantics.modeling.ui.diagramEditor.DiagramEditor; +import org.simantics.sysdyn.ui.elements.SysdynElementHints; +import org.simantics.utils.datastructures.hints.IHintContext; +import org.simantics.utils.threads.ThreadUtils; + +/** + * Workbench utilities. + * + * @author Tuomas Miettinen + */ +public class SysdynWorkbenchUtils { + + /** + * Get the active page of the diagram editor. + * + * @return active page of the diagram editor. + */ + public static IWorkbenchPage getActivePageOfEditor() { + DiagramEditor editor = null; + IWorkbench workbench = PlatformUI.getWorkbench(); + IWorkbenchWindow[] windows = workbench.getWorkbenchWindows(); + IWorkbenchPage page = null; + // To ask for the active window doesn't work, so browse through all + // windows and when an active editor is found, use that + for (IWorkbenchWindow window : windows) { + page = window.getActivePage(); + if (page != null) { + try { + editor = (DiagramEditor)page.getActiveEditor(); + if (editor != null) + // Found one + break; + } catch (ClassCastException e) { + continue; + } + } + } + return page; + } + + public static IToolMode getSysdynToolMode() { + IWorkbenchPage p = SysdynWorkbenchUtils.getActivePageOfEditor(); + IEditorPart editor = p.getActiveEditor(); + final ICanvasContext context = (ICanvasContext)(editor.getAdapter(ICanvasContext.class)); + ToolQuery toolQuery = new ToolQuery(context); + ThreadUtils.syncExec(context.getThreadAccess(), toolQuery); + return toolQuery.getSysdynToolMode(); + } + + static class ToolQuery implements Runnable { + + private IToolMode mode; + private ICanvasContext context; + + ToolQuery(ICanvasContext context) { + this.context = context; + this.mode = null; + } + + @Override + public void run() { + IHintContext hc = context.getDefaultHintContext(); + if (hc == null) + return; + IToolMode sysdynMode = hc.getHint(SysdynElementHints.SYSDYN_KEY_TOOL); + mode = sysdynMode; + } + + public IToolMode getSysdynToolMode() { + return mode; + } + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/VariableNameValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/VariableNameValidator.java new file mode 100644 index 00000000..5775f80a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/VariableNameValidator.java @@ -0,0 +1,266 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.utils; + +import java.io.StringReader; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.StringTokenizer; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.expressionParser.Token; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.Model; +import org.simantics.sysdyn.representation.ModuleType; +import org.simantics.sysdyn.utils.ModelUtils; +import org.simantics.ui.SimanticsUI; + +/** + * Name validator for variables, modules, and enumerations. + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class VariableNameValidator extends NameValidator { + + @Override + public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName) throws DatabaseException { + /*FIXME: + * How this works when range used in equations has the same string as + * the renamed variable? Should it be possible? + */ + if(originalName.equals(newName)) + return; // Do nothing + + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource expressions = graph.getPossibleObject(variable, sr.Variable_expressionList); + if(expressions != null) { + List expressionList = ListUtils.toList(graph, expressions); + for(Resource s : expressionList) { + for(Resource p : graph.getPredicates(s)) { + Resource o = graph.getPossibleObject(s, p); + if(o != null && graph.isInstanceOf(o, l0.String) && !p.equals(sr.Expression_arrayRange)) { + String string = graph.getRelatedValue(s, p); + String replaced = replaceAllWords(string, originalName, newName); + graph.claimLiteral(s, p, replaced); + } + } + } + } + } + + @Override + public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName) throws DatabaseException { + if(originalName.equals(newName)) + return; // Do nothing + + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource r : graph.getObjects(configuration, l0.ConsistsOf)) { + if(graph.isInstanceOf(r, sr.IndependentVariable)) { + renameInEquations(graph, r, originalName, newName); + } + } + } + + private static String replaceAllWords(String original, String find, String replacement) { + // Test if the new name (String find) is found in the original + // string in some format. + String pattern = "(.|\r|\n)*" + find.replace(" ", "\\s+") + "(.|\r|\n)*"; + if(!original.matches(pattern)) return original; + if (find.equals(replacement)) return original; + + ExpressionParser parser = new ExpressionParser(new StringReader(original)); + try { + parser.expr(); + } catch (ParseException e) { + // Best effort; if there are syntax errors, the replace may fail. + } + + // Collect all references + HashMap> allReferences = new HashMap>(); + allReferences.putAll(parser.getReferences()); + allReferences.putAll(parser.getFunctionCallReferences()); + allReferences.putAll(parser.getEnumerationReferences()); + + List replacedTokens = allReferences.get(find); + if (replacedTokens == null) + return original; + + // Sort the tokens so that they are in the reversed order based on + // their location in the expression. + Collections.sort(replacedTokens); + Collections.reverse(replacedTokens); + + // Go through the tokens in the reversed order + String result = new String(original); + for (Token token : replacedTokens) { + // Find the place where the last token points to in the original string + // First find where the correct line starts: + int startingPoint = 0; + for (int i = 0; i < token.beginLine - 1; ++i) + startingPoint = result.indexOf('\n', startingPoint) + 1; + // Then where the replaced string starts: + startingPoint += token.beginColumn - 1; + + // Cut the string + String begin = result.substring(0, startingPoint); + String end = result.substring(startingPoint); + + // Replace the string + String regex = find.replaceAll(" ", "\\\\s+"); + end = end.replaceFirst(regex, replacement); + result = begin + end; + } + + return result; + } + + + @Override + protected boolean nameIsTaken(ReadGraph graph, Resource variable, String name) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + if(variable == null) + return false; + + SysdynModel sysdynModel = ModelUtils.getModel(graph, variable); + if(sysdynModel == null) + return true; + sysdynModel.update(graph); + + Configuration configuration = sysdynModel.getConfiguration(); + if(configuration == null) + return true; + + // Get the top level model + Model rootModel = null; + ModuleType moduleType = configuration.getModuleType(); + if (moduleType != null) { + Object o = moduleType.getParent(); + if (o instanceof Model) { + rootModel = (Model)o; + } + } else { + rootModel = configuration.getModel(); + } + + // Get the top level model (SysdynModel) + // Resource library should be used with care if it is not instance of sr.SysdynModel + Resource library = graph.getPossibleObject(variable, l0.PartOf); + if(library == null) { + return true; + } else { + library = graph.getPossibleObject(library, l0.PartOf); + if(library == null) { + return true; + } + } + + // Check if the function is right under the model. + if (graph.isInstanceOf(library, sr.SysdynModel)) { + // Check that the function name != model name (== library name) + if (NameUtils.getSafeName(graph, library).equals(name)) return true; + + if (nameTakenByBuiltInFunction(graph, name)) return true; + + if (nameTakenBySharedFunctionLibrary(graph, library, null, name)) return true; + + if (nameTakenBySheet(sysdynModel, name)) return true; + } + + if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, variable, name)) return true; + + if (rootModel != null) { + // Browse through all ModuleTypes within the whole model + if (rootModel.containsModuleType(name)) + return true; + } + + if (nameTakenByFunctionFunctionLibraryOrModuleType(graph, library, name)) return true; + + return false; + } + + /** + * Checks that the syntax of the given name is valid and there + * are no other variables that have the same name in the configuration + * + * @param graph ReadGraph + * @param variable The variable that is being renamed + * @param name The new name of the variable + * @return + * @throws DatabaseException + */ + public boolean isValid(ReadGraph graph, Resource variable, String name, boolean hasRange) throws DatabaseException { + if(hasRange) { + String range = null; + if(name.contains("[")) { + StringTokenizer st = new StringTokenizer(name, "[]", true); + if(st.countTokens() != 4) + return false; + name = st.nextToken(); + if(!st.nextToken().equals("[")) return false; + range = st.nextToken(); + if(!st.nextToken().equals("]")) return false; + } + if(range != null && !ArrayVariableUtils.isRangeValid(graph, variable, range)) return false; + } + return isValid(graph, variable, name); + } + + + /** + * Checks that the syntax of the given name is valid and there + * are no other variables that have the same name in the configuration + * + * @param variable The variable that is being renamed + * @param name The new name of the variable + * @return + * @throws DatabaseException + */ + public boolean isValid(final Resource variable, final String name, final boolean hasRange) { + if (variable == null || name == null) + return false; + + boolean result = false; + try { + result = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + return isValid(graph, variable, name, hasRange); + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtilsUI.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtilsUI.java new file mode 100644 index 00000000..3e0eed57 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtilsUI.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - Bug #4192 + *******************************************************************************/ +package org.simantics.sysdyn.ui.utils.imports; + +import java.io.File; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.simantics.db.Resource; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.utils.imports.ImportUtils; + +/** + * Utilities for importing tg files: Models, Modules and Function libraries + * @author Teemu Lempinen + * + */ +public class ImportUtilsUI { + + public static String IMPORTMODELTPATH = "IMPORT_MODEL_PATH"; + public static String IMPORTMODULETPATH = "IMPORT_MODULE_PATH"; + public static String IMPORTFUNCTIONLIBRARYPATH = "IMPORT_FUNCTION_LIBRARY_PATH"; + + + /* ********************************* */ + /* ******* IMPORT MODEL ********* */ + /* ********************************* */ + public static IStatus importModelFile(String path, IProgressMonitor monitor) { + Activator.getDefault().getPreferenceStore().setValue(IMPORTMODELTPATH, (new File(path)).getParent()); + return ImportUtils.importModelFile(path, monitor); + } + + + /* ********************************* */ + /* ******* IMPORT MODULE ********* */ + /* ********************************* */ + public static IStatus importModuleFile(Resource model, String path, IProgressMonitor monitor) { + Activator.getDefault().getPreferenceStore().setValue(IMPORTMODULETPATH, (new File(path)).getParent()); + return ImportUtils.importModuleFile(model, path, monitor); + } + + + + /* ********************************* */ + /* *** IMPORT FUNCTION LIBRARY *** */ + /* ********************************* */ + + public static IStatus importFunctionLibrary(Resource functionLibrary, String path, IProgressMonitor monitor) { + Activator.getDefault().getPreferenceStore().setValue(IMPORTFUNCTIONLIBRARYPATH, (new File(path)).getParent()); + return ImportUtils.importFunctionLibrary(functionLibrary, path, monitor); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java new file mode 100644 index 00000000..99865d00 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java @@ -0,0 +1,350 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.simantics.db.Issue; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.layer0.Layer0; +import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.expressionParser.Token; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField; +import org.simantics.sysdyn.ui.utils.ExpressionUtils; +import org.simantics.sysdyn.ui.utils.ExpressionUtils.ReferenceOption; +import org.simantics.sysdyn.ui.utils.SyntaxError; +import org.simantics.utils.datastructures.collections.CollectionUtils; + +/** + * Evaluates issues related to Dependencies (arrows) + * + * @author Teemu Lempinen + * + */ +public class DependencyFunction { + + // Set containing the names of variables that can be used everywhere, like "time" + private static Set GLOBAL_VARIABLES = CollectionUtils.toSet("time"); + + /** + * Evaluates dependency-related issues for a component. + * + * Issues include: Unused dependency + * + * @param graph ReadGraph + * @param component Evaluated component (Variable) + * @return list of issues related to component + * @throws DatabaseException + */ + @SCLValue(type = "ReadGraph -> Resource -> [Issue]") + public static List dependencyValidator(ReadGraph graph, Resource component) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + if (!graph.isInstanceOf(component, sr.IndependentVariable)) + return Collections.emptyList(); + + if (!graph.hasStatement(component) || !graph.hasStatement(component, l0.PartOf)) + return Collections.emptyList(); + + ArrayList result = new ArrayList(); + Set references = null; + + // Find all references in equations of component + try { + references = ValidationUtils.getAllReferences(graph, component).getVariableReferences(); + } catch (Exception e) { + return result; + } + + // Find all variables that are linked to component with arrows + Set dependencies = ValidationUtils.getDependencies(graph, component); + + // Check that all arrow dependencies are used in equations + if (dependencies != null) { + for (String dependency : dependencies) { + if (references == null || !references.contains(dependency)) { + result.add(new IssueWithStringContext(sr.Validations_UnusedDependencyIssue, component, dependency)); + } + } + } + + return result; + } + + + private static Configuration getConfiguration(ReadGraph graph, Resource component) throws DatabaseException { + Resource configuration = graph.getPossibleObject(component, Layer0.getInstance(graph).PartOf); + + if(configuration == null) + return null; + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, configuration); + if(sm == null) + return null; + + sm.update(graph); + return sm.getConfiguration(); + } + + /** + * Evaluates dependency-related issues for a component. + * + * Issues include: Missing link No such variable + * + * @param graph ReadGraph + * @param component Evaluated component (Variable) + * @return list of issues related to component + * @throws DatabaseException + */ + @SCLValue(type = "ReadGraph -> Resource -> [Issue]") + public static List missingDependencyValidator(ReadGraph graph, Resource component) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + if (!graph.isInstanceOf(component, sr.IndependentVariable)) + return Collections.emptyList(); + + if (!graph.hasStatement(component) || !graph.hasStatement(component, l0.PartOf)) + return Collections.emptyList(); + + // Find all references in equations of component + References references = null; + try { + references = ValidationUtils.getAllReferences(graph, component); + } catch (Exception e) { + return Collections.emptyList(); + } + + Configuration configuration = getConfiguration(graph, component); + ArrayList result = new ArrayList(); + + // Examine possible for-index references. Remove if found + for(Resource expressionResource : references.forIndices.keySet()) { + if(references.forIndices.containsKey(expressionResource)) { + for(Token token : references.forIndices.get(expressionResource).keySet()) { + if(references.references.containsKey(expressionResource) && + references.references.get(expressionResource).containsKey(token.image)) { + references.references.get(expressionResource).remove(token.image); + } + } + } + } + + // Examine Sheet references + for(Resource expressionResource : references.functionReferences.keySet()) { + for(String functionKey : references.functionReferences.get(expressionResource).keySet()) { + List sheetErrors = ExpressionUtils.examineSheetReferences( + configuration, + functionKey, + references.functionReferences.get(expressionResource).get(functionKey), + references.expressions.get(expressionResource), + references.references.get(expressionResource)); + if(sheetErrors != null) { + for(SyntaxError error : sheetErrors) + result.add(new IssueWithStringContext(sr.Validations_InvalidSheetReferenceIssue, component, error.getMessage(), error.getImage())); + } + } + } + + + // Examine dependencies + Set variablesReferences = references.getVariableReferences(); + if(variablesReferences == null || variablesReferences.isEmpty()) + return result; + + // Remove references to self + String name = NameUtils.getSafeName(graph, component); + if(name != null && variablesReferences.contains(name)) + variablesReferences.remove(name); + + // Find all variables that are linked to component with arrows + Set dependencies = ValidationUtils.getDependencies(graph, component); + dependencies.addAll(GLOBAL_VARIABLES); + + // Remove all dependency variables from reference maps + for(String dependency : dependencies) + variablesReferences.remove(dependency); + + boolean isStock = isStock(graph, component); + ReferenceOption option; + + for(String reference : variablesReferences) { + option = ExpressionUtils.getReferenceOption(configuration, reference); + switch(option) { + case DOES_NOT_EXIST: + result.add(new IssueWithStringContext(sr.Validations_NoSuchVariableIssue, component, reference)); + case CAN_BE_CONNECTED: + if(isStock) { + /* Stocks do not get incoming dependencies. They are allowed + to have references without arrows */ + } else { + result.add(new IssueWithStringContext(sr.Validations_MissingLinkIssue, component, reference)); + } + break; + case CANNOT_BE_CONNECTED: + } + } + + + for(Resource expression : references.ranges.keySet()) { + List errors = new ArrayList(); + // RANGES + errors.addAll(ExpressionUtils.examineArrayRanges(graph, configuration, references.ranges.get(expression), references.forIndices.get(expression))); + + // ENUMERATION REFERENCES IN FOR-LOOPS + errors.addAll(ExpressionUtils.examineEnumerationReferences(configuration, references.enumerationReferences.get(expression))); + + for(SyntaxError error : errors) { + Resource type = sr.Validations_RangeIssue; + if(ExpressionField.SYNTAX_WARNING.equals(error.getType())) { + type = sr.Validations_RangeWarning; + } + result.add(new IssueWithStringContext(type, component, error.getMessage())); + + } + } + + return result; + + } + + private static boolean isStock(ReadGraph graph, Resource variable) throws DatabaseException { + List expressionList = ValidationUtils.getExpressions(graph, variable); + if(expressionList == null || expressionList.isEmpty()) { + return false; + } else { + for(Resource expression : expressionList) { + if(!graph.isInstanceOf(expression, SysdynResource.getInstance(graph).StockExpression)) + return false; + } + return true; + } + } + + /** + * Missing link description + * + * @param graph ReadGraph + * @param converter + * @param issue Issue + * @return issue description + * @throws DatabaseException + */ + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String missingLinkIssueDescription(ReadGraph graph, Resource converter, Variable property) + throws DatabaseException { + + List contexts = IssueWithStringContext.getStringContexts(graph, property); + String result = "Missing a link to "; + if (contexts.size() > 0) { + result = result + contexts.get(0); + } + + return result; + + } + + /** + * Unused dependency description + * + * @param graph ReadGraph + * @param converter + * @param issue Issue + * @return issue description + * @throws DatabaseException + */ + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String unusedDependencyIssueDescription(ReadGraph graph, Resource converter, Variable property) + throws DatabaseException { + + List contexts = IssueWithStringContext.getStringContexts(graph, property); + String result = "Unused dependency: "; + if (contexts.size() > 0) { + result = result + contexts.get(0); + } + + return result; + } + + /** + * No such variable description. Finds all variables that the component + * refers to and adds their names to the issue description. + * + * @param graph ReadGraph + * @param converter + * @param issue Issue + * @return issue description + * @throws DatabaseException + */ + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String noSuchVariableIssueDescription(ReadGraph graph, Resource converter, Variable property) + throws DatabaseException { + + List contexts = IssueWithStringContext.getStringContexts(graph, property); + String result = "Refers to unexisting variable "; + if (contexts.size() > 0) { + result = result + contexts.get(0); + } + + return result; + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String invalidSheetReferenceIssueDescription(ReadGraph graph, Resource converter, Variable property) + throws DatabaseException { + + List contexts = IssueWithStringContext.getStringContexts(graph, property); + String result = ""; + + if(contexts.size() == 2) + result = contexts.get(0) + ": " + contexts.get(1); + else + result = "Spreadsheet reference error"; + + return result; + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String rangeIssueDescription(ReadGraph graph, Resource converter, Variable property) + throws DatabaseException { + + List contexts = IssueWithStringContext.getStringContexts(graph, property); + if (contexts.size() > 0) { + return contexts.get(0); + } else { + return "Range Issue"; + } + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String rangeWarningDescription(ReadGraph graph, Resource converter, Variable property) + throws DatabaseException { + return rangeIssueDescription(graph, converter, property); + } + + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/EnumerationFunction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/EnumerationFunction.java new file mode 100644 index 00000000..96b687ca --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/EnumerationFunction.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import java.util.Collections; +import java.util.List; + +import org.simantics.db.Issue; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.issue.StandardIssue; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.sysdyn.SysdynResource; + +/** + * Functions for checking issues in Enumerations + * @author Teemu Lempinen + * + */ +public class EnumerationFunction { + + private static String NO_INDEXES = "Enumeration does not contain indexes."; + + @SCLValue(type = "ReadGraph -> Resource -> [Issue]") + public static List enumerationIndexValidator(ReadGraph graph, Resource component) throws DatabaseException { + + SysdynResource sr = SysdynResource.getInstance(graph); + + if(!graph.isInstanceOf(component, sr.Enumeration)) { + return Collections.emptyList(); + } + + boolean noIndexes = false; + + try { + Resource indexList = graph.getPossibleObject(component, sr.Enumeration_enumerationIndexList); + List indexes = ListUtils.toList(graph, indexList); + if(indexes.size() == 0) + noIndexes = true; + } catch (DatabaseException e) { + noIndexes = true; + } + + if(noIndexes) + return Collections.singletonList(new StandardIssue(sr.Validations_EmptyEnumerationIssue, component)); + else + return Collections.emptyList(); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String emptyEnumerationIssueDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException { + return NO_INDEXES; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ExpressionIssueFunction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ExpressionIssueFunction.java new file mode 100644 index 00000000..8a55a522 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ExpressionIssueFunction.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import java.util.Collections; +import java.util.List; + +import org.simantics.db.Issue; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.issue.StandardIssue; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.issues.common.IssueUtils; +import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.sysdyn.SysdynResource; + +/** + * Detects syntax errors, unsupported characters and undefined expressions from variables. + * + * @author tlteemu + * + */ +public class ExpressionIssueFunction { + + private static String SYNTAX_ERROR = "Syntax error"; + private static String UNSUPPORTED_CHARACTERS = "Unsupported characters"; + private static String UNDEFINED_EXPRESSION = "Undefined expression"; + + @SCLValue(type = "ReadGraph -> Resource -> [Issue]") + public static List expressionValidator(ReadGraph graph, Resource component) throws DatabaseException { + + SysdynResource sr = SysdynResource.getInstance(graph); + + if(!graph.isInstanceOf(component, sr.IndependentVariable)) { + return Collections.emptyList(); + } + + // Try if there are any errors while parsing the expressions + try { + ValidationUtils.getAllReferences(graph, component); + } catch (Exception e) { + return Collections.singletonList(new StandardIssue(sr.Validations_ExpressionIssue, component)); + } + return Collections.emptyList(); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String expressionIssueDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException { + + List contexts = IssueUtils.getContextsForProperty(graph, property); + Resource component = contexts.get(0); + + // There should be an error + try { + ValidationUtils.getAllReferences(graph, component); + } catch (SyntaxErrorException e) { + return SYNTAX_ERROR; + } catch (UnsupportedCharactersException e) { + return UNSUPPORTED_CHARACTERS; + } catch (UndefinedExpressionException e) { + return UNDEFINED_EXPRESSION; + } + return "Erroneus error"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/Functions.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/Functions.java new file mode 100644 index 00000000..eca08108 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/Functions.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.issues.common.IssueUtils; +import org.simantics.layer0.Layer0; +import org.simantics.project.ontology.ProjectResource; +import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.sysdyn.SysdynResource; + +/** + * Generic functions for validations + * + * @author Teemu Lempinen + * + */ +public class Functions { + + @SCLValue(type = "ReadGraph -> Resource -> Resource") + public static Resource baseRealizationFunction(ReadGraph graph, Resource model) throws DatabaseException { + return model; + } + + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String path(ReadGraph graph, Resource source, Variable property) throws DatabaseException { + List contexts = IssueUtils.getContextsForProperty(graph, property); + if (contexts.size() > 0) { + Resource component = contexts.get(0); + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + ProjectResource PROJECT = ProjectResource.getInstance(graph); + StringBuilder sb = new StringBuilder(""); + Resource parent = graph.getPossibleObject(component, L0.PartOf); + boolean first = true; + while(parent != null && !graph.isInstanceOf(parent, PROJECT.Project)) { + if(!graph.isInstanceOf(parent, sr.Configuration)) { + String name = NameUtils.getSafeName(graph, parent); + if(first) { + sb.append(name); + first = false; + } else { + sb.insert(0, "/"); + sb.insert(0, name); + } + } + parent = graph.getPossibleObject(parent, L0.PartOf); + } + return sb.toString(); + } else { + return ""; + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/IssueWithStringContext.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/IssueWithStringContext.java new file mode 100644 index 00000000..906124fb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/IssueWithStringContext.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.issue.StandardIssue; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; + +/** + * Issue that can have string contexts. + * + * String contexts are written to a graph like resource contexts and can be accessed + * in issue description functions. This eliminates the need for making complex calculations + * for obtaining values that have already been calculated in the issue source function. + * + * @author Teemu Lempinen + * + */ +public class IssueWithStringContext extends StandardIssue { + + String[] stringContexts; + + /** + * Creates an issue with one resource context and an arbitrary number of string contexts + * @param type + * @param context + * @param stringContexts + */ + public IssueWithStringContext(Resource type, Resource context, String... stringContexts) { + super(type, context); + this.stringContexts = stringContexts; + } + + /** + * Get the string contexts of this issue + * @return string contexts + */ + public String[] getStringContexts() { + return stringContexts; + } + + /** + * Overridden function from StandardResource. This writes a list of string contexts to the database. + */ + public void writeAdditionalContext(WriteGraph graph, Resource issue) throws DatabaseException { + super.writeAdditionalContext(graph, issue); + + // Add possible string contexts to the contexts array + if(stringContexts != null && stringContexts.length > 0) { + SysdynResource SR = SysdynResource.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + List contexts = new ArrayList(); + for(String s : stringContexts) { + Resource r = graph.newResource(); + graph.claim(r, L0.InstanceOf, L0.String); + graph.claimValue(r, s, Bindings.STRING); + contexts.add(r); + } + graph.claim(issue, SR.Validations_Issue_stringContexts, ListUtils.create(graph, L0.List, contexts)); + } + + } + + /** + * Gets string contexts from IssueWithStringContexts + * @param graph ReadGraph + * @param property issue property + * @return String contexts of issue or empty list if none is found + * @throws DatabaseException + */ + public static List getStringContexts(ReadGraph graph, Variable property) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + Variable issueVariable = property.getParent(graph); + Resource issueResource = issueVariable.getRepresents(graph); + Resource list = graph.getPossibleObject(issueResource, SR.Validations_Issue_stringContexts); + if(list == null) { + return Collections.emptyList(); + } else { + List stringResources = ListUtils.toList(graph, list); + ArrayList result = new ArrayList(stringResources.size()); + for(Resource r : stringResources) { + result.add((String)graph.getValue(r, Bindings.STRING)); + } + return result; + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ModuleStandardIssue.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ModuleStandardIssue.java new file mode 100644 index 00000000..4cbdf730 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ModuleStandardIssue.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.issue.StandardIssue; +import org.simantics.db.exception.DatabaseException; +import org.simantics.issues.ontology.IssueResource; + +public class ModuleStandardIssue extends StandardIssue { + + public ModuleStandardIssue(Resource type, Resource ... contexts) { + super(type, contexts); + } + + @Override + public void writeAdditionalContext(WriteGraph graph, Resource issue) throws DatabaseException { + super.writeAdditionalContext(graph, issue); + + if(contexts.length >= 2) { + IssueResource IR = IssueResource.getInstance(graph); + // Input / output context + graph.claim(issue, IR.Issue_HasContext, IR.Issue_HasContext_Inverse, contexts[1]); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/NoSuchVariableException.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/NoSuchVariableException.java new file mode 100644 index 00000000..4ec11767 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/NoSuchVariableException.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +public class NoSuchVariableException extends RuntimeException { + private static final long serialVersionUID = -5766352512554068379L; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ParameterExistsValidator.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ParameterExistsValidator.java new file mode 100644 index 00000000..0fb44b63 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ParameterExistsValidator.java @@ -0,0 +1,50 @@ +package org.simantics.sysdyn.ui.validation; + +import java.util.Collection; + +import org.simantics.browsing.ui.swt.widgets.TrackedText; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.jfreechart.chart.properties.AllVariablesOfModel; +import org.simantics.jfreechart.chart.properties.ChartVariable; +import org.simantics.jfreechart.chart.properties.VariableExistsValidator; +import org.simantics.db.Resource; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.AdaptionUtils; + +public class ParameterExistsValidator extends VariableExistsValidator { + + public ParameterExistsValidator(WidgetSupport support, TrackedText text) { + super(support, text); + } + + @Override + public void setInput(ISessionContext context, Object input) { + final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class); + if(resource == null) + return; + + SimanticsUI.getSession().asyncRequest( + new AllVariablesOfModel(resource) + , new Listener>() { + + @Override + public void execute(Collection variables) { + ParameterExistsValidator.this.variables = variables; + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return ParameterExistsValidator.this.text.isDisposed(); + } + + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/References.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/References.java new file mode 100644 index 00000000..0d9ed3d9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/References.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.simantics.db.Resource; +import org.simantics.sysdyn.expressionParser.Token; + +/** + * Container for different types of references got from expression parser + * @author Teemu Lempinen + * + */ +public class References { + public HashMap expressions = new HashMap(); + public HashMap>> references = new HashMap>>(); + public HashMap>>> ranges = new HashMap>>>(); + public HashMap>> forIndices = new HashMap>>(); + public HashMap>> enumerationReferences = new HashMap>>(); + public HashMap>> functionReferences = new HashMap>>(); + + + /** + * Get all variable references from all expressions of the variable in a single set + * @return All variable references + */ + public Set getVariableReferences() { + HashSet result = new HashSet(); + for(HashMap> map : references.values()) { + for(String key : map.keySet()) { + if(!map.get(key).isEmpty()) + result.add(key); + } + } + + return result; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/SyntaxErrorException.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/SyntaxErrorException.java new file mode 100644 index 00000000..0592a5d7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/SyntaxErrorException.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +public class SyntaxErrorException extends RuntimeException { + private static final long serialVersionUID = -6466653179001958636L; + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UndefinedExpressionException.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UndefinedExpressionException.java new file mode 100644 index 00000000..1c53cd87 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UndefinedExpressionException.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +public class UndefinedExpressionException extends RuntimeException { + private static final long serialVersionUID = 7352486116119189105L; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnitFunction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnitFunction.java new file mode 100644 index 00000000..dbf2e2d0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnitFunction.java @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +import org.simantics.Simantics; +import org.simantics.db.Issue; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.issue.StandardIssue; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.issues.common.IssueUtils; +import org.simantics.layer0.Layer0; +import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.expressions.IExpression; +import org.simantics.sysdyn.representation.utils.UnitUtils; +import org.simantics.sysdyn.utils.Function; +import org.simantics.sysdyn.utils.ModelUtils; + +public class UnitFunction { + + @SCLValue(type = "ReadGraph -> Resource -> [Issue]") + public static List unitValidator(ReadGraph graph, Resource component) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + if(graph.isInstanceOf(component, SR.Variable) && !graph.isInstanceOf(component, SR.Cloud)) + return variableValidator(graph, component); + else if(graph.isInstanceOf(component, SR.Module)) + return moduleValidator(graph, component); + else + return Collections.emptyList(); + } + + private static List variableValidator(ReadGraph graph, Resource variable) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + + Resource configuration = graph.getPossibleObject(variable, L0.PartOf); + if(configuration == null) + return Collections.emptyList(); + + // Make sure unit updates are listened to + String unit = graph.getPossibleRelatedValue(variable, SR.Variable_unit); + if(unit == null || unit.trim().length() == 0) + return Collections.singletonList(new StandardIssue(SR.Validations_UnitWarning, variable)); + + if(!graph.isInstanceOf(variable, SR.IndependentVariable)) + return Collections.emptyList(); + + Resource expressionList = graph.getPossibleObject(variable, SR.Variable_expressionList); + + if(expressionList == null) + return Collections.emptyList(); + + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, configuration); + sm.getMapping().domainModified(variable); + + sm.update(graph); + Object var = sm.getMapping().get(variable); + + ArrayList issues = new ArrayList(); + + for(Resource expression : ListUtils.toList(graph, expressionList)) { + for(Resource r : graph.getObjects(expression, SR.Expression_equation)) { + graph.getValue(r); + } + + sm.getMapping().domainModified(expression); + sm.update(graph); + + Object expr = sm.getMapping().get(expression); + + if(expr != null && var != null && expr instanceof IExpression && var instanceof IndependentVariable) { + String result = ((IExpression)expr).validateUnits(graph, sm); + if(result != null) { + Issue issue = new StandardIssue(SR.Validations_UnitWarning, variable, expression, graph.getPossibleObject(variable, SR.Variable_unit)); + issues.add(issue); + } + } + } + return issues; + } + + private static List moduleValidator(ReadGraph graph, Resource module) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + + if(module == null) + return Collections.emptyList(); + + Resource configuration = graph.getPossibleObject(module, L0.PartOf); + if(configuration == null) + return Collections.emptyList(); + + SysdynModel model = ModelUtils.getModel(graph, module); + String result = null; + ArrayList issues = new ArrayList(); + for(Resource outputRelation : graph.getObjects(module, SR.Variable_isTailOf)) { + Resource reference = graph.getPossibleObject(outputRelation, SR.Dependency_refersTo); + if(reference != null) { + Resource output = graph.getPossibleObject(outputRelation, SR.Variable_HasHead); + if(output == null) + continue; + String left = graph.getPossibleRelatedValue(output, SR.Variable_unit); + String right = graph.getPossibleRelatedValue(reference, SR.Variable_unit); + ArrayList functions = Function.getAllBuiltInFunctions(graph); + result = UnitUtils.matchUnits(left, right, functions, UnitUtils.allowEquivalents(graph, model)); + if(result != null) + issues.add(new ModuleStandardIssue(SR.Validations_ModuleOutputUnitWarning, module, output, reference)); + } + } + for(Resource inputRelation : graph.getObjects(module, SR.Variable_isHeadOf)) { + Resource reference = graph.getPossibleObject(inputRelation, SR.Dependency_refersTo); + if(reference != null) { + Resource variable = graph.getPossibleObject(inputRelation, SR.Variable_HasTail); + if(variable == null) + continue; + String left = graph.getPossibleRelatedValue(variable, SR.Variable_unit); + String right = graph.getPossibleRelatedValue(reference, SR.Variable_unit); + ArrayList functions = Function.getAllBuiltInFunctions(graph); + result = UnitUtils.matchUnits(left, right, functions, UnitUtils.allowEquivalents(graph, model)); + if(result != null) + issues.add(new ModuleStandardIssue(SR.Validations_ModuleInputUnitWarning, module, variable, reference)); + } + } + return issues; + } + + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String unitWarningDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException { + List contexts = IssueUtils.getContextsForProperty(graph, property); + + if(contexts.size() == 0) + return "Error, No contexts"; + + Resource variable = contexts.get(0); + String unit = graph.getPossibleRelatedValue(variable, SysdynResource.getInstance(graph).Variable_unit); + + if(unit == null || unit.length() == 0) + return "No unit defined"; + + if(contexts.size() < 2) + return "Error, not enough contexts"; + + Layer0 L0 = Layer0.getInstance(graph); + Resource configuration = graph.getPossibleObject(variable, L0.PartOf); + if(configuration == null) + return "Error, No Confiugration"; + + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, configuration); + + SysdynResource SR = SysdynResource.getInstance(graph); + for(Resource r : graph.getObjects(contexts.get(1), SR.Expression_equation)) { + graph.getValue(r); + } + + Object expr = sm.getMapping().get(contexts.get(1)); + String result = ((IExpression)expr).validateUnits(graph, sm); + + return result; + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String moduleOutputUnitWarningDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException { + List contexts = IssueUtils.getContextsForProperty(graph, property); + + if(contexts.size() < 3) + return "Error, No contexts"; + + Resource output = contexts.get(1); + Resource reference = contexts.get(2); + + return moduleInterfaceDescription(graph, output, reference, "Module output has different unit. (", ")"); + + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String moduleInputUnitWarningDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException { + List contexts = IssueUtils.getContextsForProperty(graph, property); + + if(contexts.size() < 3) + return "Error, No contexts"; + + Resource output = contexts.get(1); + Resource reference = contexts.get(2); + + return moduleInterfaceDescription(graph, output, reference, "Module input has different unit. (", ")"); + + } + + private static String moduleInterfaceDescription(ReadGraph graph, Resource leftResource, Resource rightResource, String prefix, String suffix) throws DatabaseException { + if(leftResource == null) + return "Erroneus error: left == null"; + + if(rightResource == null) + return "Erroneus error: right == null"; + + SysdynResource SR = SysdynResource.getInstance(graph); + + String left = graph.getPossibleRelatedValue(leftResource, SR.Variable_unit); + if(left == null || left.isEmpty()) + return "No unit defined for " + NameUtils.getSafeName(graph, leftResource); + + String right = graph.getPossibleRelatedValue(rightResource, SR.Variable_unit); + if(right == null || right.isEmpty()) + return "No unit defined for " + NameUtils.getSafeName(graph, rightResource); + + SysdynModel model = ModelUtils.getModel(graph, leftResource); + ArrayList functions = Function.getAllBuiltInFunctions(graph); + String result = UnitUtils.matchUnits(left, right, functions, UnitUtils.allowEquivalents(graph, model)); + + if(result != null) + result = prefix + result + suffix; + + return result; + } + + + + + @SCLValue(type = "ReadGraph -> [Resource] -> [Resource]") + public static List moduleInterfaceExtension(ReadGraph graph, List rs) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + + HashSet components = new HashSet(); + HashSet searchedModuleTypes = new HashSet(); + for(Resource r : rs) { + if(!graph.isInstanceOf(r, SR.Variable)) + continue; + + if(graph.isInstanceOf(r, SR.Input)) { + Resource connection = graph.getPossibleObject(r, SR.Variable_isHeadOf); + if(connection != null) + components.add(graph.getPossibleObject(connection, SR.Variable_HasTail)); + } + + for(Resource connection : graph.getObjects(r, SR.Variable_isTailOf)) { + Resource head = graph.getPossibleObject(connection, SR.Variable_HasHead); + if(head != null && graph.isInstanceOf(head, SR.Module)) { + components.add(head); + } + } + + Layer0 L0 = Layer0.getInstance(graph); + Resource configuration = graph.getPossibleObject(r, L0.PartOf); + Resource possibleModule = graph.getPossibleObject(configuration, L0.PartOf); + if(graph.isInheritedFrom(possibleModule, SR.Module) && !searchedModuleTypes.contains(possibleModule)) { + searchedModuleTypes.add(possibleModule); + for(Resource model : graph.syncRequest(new ObjectsWithType(Simantics.getProject().get(), L0.ConsistsOf, SR.SysdynModel))) { + Collection found = org.simantics.db.indexing.IndexUtils.findByType(graph, model, possibleModule); + components.addAll(found); + } + } + + } + + if(!components.isEmpty()) { + rs.addAll(components); + } + + return rs; + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnsupportedCharactersException.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnsupportedCharactersException.java new file mode 100644 index 00000000..b2aa82f4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnsupportedCharactersException.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +public class UnsupportedCharactersException extends RuntimeException { + private static final long serialVersionUID = 8210873686720503188L; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java new file mode 100644 index 00000000..d90fd960 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2007, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import java.io.StringReader; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.expressionParser.Token; +import org.simantics.sysdyn.expressionParser.TokenMgrError; + +/** + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ValidationUtils { + + /** + * Find all variables that are referred to in the expressions of variable r + * @param graph ReadGraph + * @param r Variable resource + * @return All names of the variables that are referred to in the expressions of r + * @throws DatabaseException + * @throws SyntaxErrorException + * @throws UnsupportedCharactersException + * @throws UndefinedExpressionException + */ + public static References getAllReferences(ReadGraph graph, Resource r) throws DatabaseException, SyntaxErrorException, UnsupportedCharactersException, UndefinedExpressionException { + References result = new References(); + + ExpressionParser parser = new ExpressionParser(new StringReader("")); + + SysdynResource sr = SysdynResource.getInstance(graph); + List expressionList = getExpressions(graph, r); + if(expressionList == null || expressionList.isEmpty()) + throw new UndefinedExpressionException(); + for(Resource expression : expressionList) { + + Collection statements = graph.getStatements(expression, sr.Expression_equation); + if(statements.isEmpty()) + throw new UndefinedExpressionException(); + + for(Statement statement : statements) { + Object v = graph.getValue(statement.getObject()); + String value = v.toString(); + + if(value.length() == 0) { + // Empty might be allowed + if(!graph.isSubrelationOf(statement.getPredicate(), sr.HasEquationOrEmpty)) + throw new UndefinedExpressionException(); + } + + parser.ReInit(new StringReader(value)); + try { + parser.expr(); + + HashMap> refs = parser.getReferences(); + result.references.put(expression, refs); + result.ranges.put(expression, parser.getRanges()); + result.forIndices.put(expression, parser.getForIndices()); + result.enumerationReferences.put(expression, parser.getEnumerationReferences()); + result.functionReferences.put(expression, parser.getFunctionCallReferences()); + result.expressions.put(expression, value); + + } catch (ParseException e1) { + throw new SyntaxErrorException(); + } catch (TokenMgrError err) { + throw new UnsupportedCharactersException(); + } + } + } + return result; + } + + /** + * Get all expressions of a variable r + * @param graph ReadGraph + * @param r Variable with expressions + * @return List of expression (resources) + * @throws DatabaseException + */ + public static List getExpressions(ReadGraph graph, Resource r) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource hasExpressions = graph.getPossibleObject(r, sr.Variable_expressionList); + if(hasExpressions != null) + return ListUtils.toList(graph, hasExpressions); + else + return null; + } + + + /** + * Returns the names of the related variables (dependencies) + * For stocks, find also both the incoming and outgoing flows + * + * @param graph + * @param r + * @return + * @throws DatabaseException + */ + public static HashSet getDependencies(ReadGraph graph, Resource r) throws DatabaseException { + HashSet variables = new HashSet(); + if(graph != null && r != null) { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + // Add incoming dependencies and flows + Collection dependencies = graph.getObjects(r, sr.Variable_isHeadOf); + for(Resource d : dependencies) { + if(graph.isInstanceOf(d, sr.Dependency) + || (graph.isInstanceOf(d, sr.Flow) && graph.isInstanceOf(r, sr.Stock))) { + Resource tail = graph.getPossibleObject(d, sr.Variable_HasTail); + if(tail != null) { + + if(graph.isInstanceOf(tail, sr.Shadow)) { + tail = graph.getPossibleObject(tail, sr.Shadow_original); + if(tail == null) + continue; + } + + Object name = graph.getPossibleRelatedValue(tail, l0.HasName); + if(name != null) + variables.add((String)name); + } + } + } + + // Add also the outgoing flows + Collection outgoingFlows = graph.getObjects(r, sr.Variable_isTailOf); + for(Resource f : outgoingFlows) { + if(graph.isInstanceOf(f, sr.Flow) && graph.isInstanceOf(r, sr.Stock)) { + Resource head = graph.getPossibleObject(f, sr.Variable_HasHead); + if(head != null) { + + Object name = graph.getPossibleRelatedValue(head, l0.HasName); + if(name != null) + variables.add((String)name); + } + } + } + } + return variables; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java new file mode 100644 index 00000000..6908c0ea --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.values; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.part.ViewPart; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.ui.viewUtils.SysdynDatasetSelectionListener; + +/** + * A view that shows the values of currently selected variables in a table. + * One column (first by default) is always time values. + * + * @author Teemu Lempinen + * + */ +public class ValueView extends ViewPart { + + private boolean disposed; + private Composite baseComposite; + private ISelectionListener selectionListener; + private Table table; + + @Override + public void createPartControl(Composite parent) { + + disposed = false; + GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(parent); + baseComposite = new Composite(parent, + SWT.NO_BACKGROUND | SWT.EMBEDDED); + GridLayoutFactory.fillDefaults().applyTo(baseComposite); + GridDataFactory.fillDefaults().grab(true, true).applyTo(baseComposite); + + // Result table + table = new Table (baseComposite, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION); + GridDataFactory.fillDefaults().grab(true, true).applyTo(table); + table.setLinesVisible (true); + table.setHeaderVisible (true); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.heightHint = 200; + table.setLayoutData(data); + + + // Add selectionListener for updating the table + selectionListener = new SysdynDatasetSelectionListener() { + + @Override + protected void selectionChanged(final Collection activeDatasets) { + if(disposed) return; + table.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + updateTable(activeDatasets); + } + }); + } + + @Override + protected void selectionChanged(ReadGraph graph, Resource resource) { + // Do nothing + } + + }; + getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(selectionListener); + + // Refreshes the table. There might be a selection already before the table is shown. + ISelection selection = getSite().getWorkbenchWindow().getSelectionService().getSelection(); + if(selection != null) + selectionListener.selectionChanged(getSite().getPart(), selection); + + + /* + * A primitive copy paste to support exporting data from table to excel + * + * columnName\tcolumnName\tcolumnName\n + * value\tvalue\tvalue\n + * ... + * value\tvalue\tvalue\n + * + */ + KeyListener kl = new KeyListener() { + + @Override + public void keyReleased(KeyEvent e) { + + } + + @Override + public void keyPressed(KeyEvent e) { + if (e.stateMask == SWT.CTRL && e.keyCode == 99) + { + + Clipboard cb = new Clipboard(e.display); + + TextTransfer textTransfer = TextTransfer.getInstance(); + + // Add names of the columns first. Selection is always full, print all columns + StringBuilder sb = new StringBuilder(); + int columnCount = table.getColumnCount(); + for(int i = 0; i < columnCount; i++) { + TableColumn tc = table.getColumn(i); + sb.append(tc.getText()); + if(i < columnCount - 1) + sb.append("\t"); + else + sb.append("\n"); + } + + // Print all selected rows. + for(TableItem ti : table.getSelection()) + for(int i = 0; i < columnCount; i++) { + sb.append(ti.getText(i)); + if(i < columnCount - 1) + sb.append("\t"); + else + sb.append("\n"); + } + + cb.setContents(new Object[]{sb.toString()}, new Transfer[]{textTransfer}); + } + } + }; + + table.addKeyListener(kl); + + + } + + /** + * Updates the table after selection has been changed + * + * @param activeDatasets + */ + private void updateTable(Collection activeDatasets) { + + if(activeDatasets.isEmpty() || !(activeDatasets instanceof ArrayList)) return; + + // Clear the old table + table.removeAll(); + if(table.getColumnCount() > 0) { + for(int i = table.getColumnCount() - 1; i>=0; i--) { + table.getColumn(i).dispose(); + } + } + + // Create new columns + ArrayList datasets = (ArrayList) activeDatasets; + + ArrayList titleList = new ArrayList(); + titleList.add("Time"); + double[] times = new double[0]; + for (int i=0; i times.length) { + times = datasets.get(i).times; + } + } + + + Listener sortListener = new Listener() { + public void handleEvent(Event e) { + TableItem[] items = table.getItems(); + TableColumn column = (TableColumn)e.widget; + + TableColumn sortColumn = table.getSortColumn(); + int dir = table.getSortDirection(); + if (sortColumn == column) { + dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; + } else { + table.setSortColumn(column); + dir = SWT.UP; + } + + int index = 0; + while(index < table.getColumnCount()) { + if(table.getColumn(index) == column) + break; + index++; + } + for (int i = 1; i < items.length; i++) { + String v1 = items[i].getText(index); + if(v1.contains("*")) + v1 = v1.substring(0, v1.indexOf("*")); + Double value1; + try { + value1 = Double.parseDouble(v1); + } catch(NumberFormatException ne) { + continue; + } + for (int j = 0; j < i; j++){ + String v2 = items[j].getText(index); + if(v2.contains("*")) + v2 = v2.substring(0, v2.indexOf("*")); + Double value2; + try { + value2 = Double.parseDouble(v2); + } catch(NumberFormatException ne) { + continue; + } + int result = value1.compareTo(value2); + if (dir == SWT.UP && result < 0 || dir == SWT.DOWN && result > 0) { + int columns = table.getColumnCount(); + String[] values = new String[columns]; + for(int k = 0; k < columns; k++) { + values[k] = items[i].getText(k); + } + items[i].dispose(); + TableItem item = new TableItem(table, SWT.NONE, j); + item.setText(values); + items = table.getItems(); + break; + } + } + } + table.setSortColumn(column); + table.setSortDirection(dir); + } + }; + + + + String[] titles = titleList.toArray(new String[titleList.size()]); + + for (int i=0; i dataset.times[dataset.times.length - 1] || + time < dataset.times[0]) { + return "---"; + } + + // Make sure the index is within times array + if(index >= dataset.times.length) + index = dataset.times.length - 1; + + // times match, no approximation needed + double t; + for(int i = 0; i < dataset.times.length; i++) { + t = dataset.times[i]; + if(t == time) + return String.valueOf(dataset.values[i]); + } + + // Search the position on datasets' timeline + int dir = table.getSortDirection(); + while(dataset.times[index] > time) { + index = dir == SWT.UP ? index - 1 : index + 1; + } + while(dataset.times[index] <= time) + index = dir == SWT.UP ? index + 1 : index - 1; + + int a = dir == SWT.UP ? index - 1 : index; + int b = dir == SWT.UP ? index : index - 1; + + // Calculate and return approximation + return dataset.values[a] + + (dataset.values[b] - dataset.values[a]) * + (time - dataset.times[a]) / + (dataset.times[b] - dataset.times[a]) + "*"; + } + + @Override + public void setFocus() { + + } + + @Override + public void dispose() { + super.dispose(); + getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(selectionListener); + disposed = true; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java new file mode 100644 index 00000000..688ba1f7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.viewUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.procedure.adapter.DisposableListener; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.SelectionHints; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.request.PossibleActiveVariableFromVariable; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.request.Read; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.modeling.ModelingUtils; +import org.simantics.sysdyn.Functions; +import org.simantics.sysdyn.JFreeChartResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.ui.trend.PinTrend; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ISelectionUtils; + +/** + * Selection listener for listening datasets of the selected variables. Selections can come + * from both diagram and model browser. Listener provides the active datasets + * of the selected variable(s) or the JFreeChart of a selected chart definition. + * + * @author Teemu Lempinen + * + */ +public abstract class SysdynDatasetSelectionListener implements ISelectionListener { + + /** + * Triggered after a variable is selected from diagram or model browser + * Subclasses implement. + * @param activeDatasets Active dataset(s) of the selected variable(s) + */ + protected abstract void selectionChanged(Collection activeDatasets); + + /** + * Triggered after a chart definition is selected from model browser + * Subclasses implement + * + * @param graph ReadGraph + * @param resource Chart definition resource + */ + protected abstract void selectionChanged(ReadGraph graph, Resource resource); + + + + public void dispose() { + if(listener != null) + listener.dispose(); + } + + DisposableListener> listener; + + @Override + public void selectionChanged(IWorkbenchPart part, final ISelection selection) { + // Empty selection or pinned trend -> Do nothing + if(selection.isEmpty() || Boolean.TRUE.equals(PinTrend.getState())) + return; + + if(selection instanceof IStructuredSelection) { + Session session = SimanticsUI.peekSession(); + if (session == null) + return; + + if(listener != null) + listener.dispose(); + + listener = new DisposableListener>() { + + @Override + public void execute(ArrayList vars) { + if(vars != null) + selectionChanged(vars); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + }; + + try { + session.syncRequest(new Read>() { + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + + // Model browser provides variables + Collection vars = ISelectionUtils.filterSetSelection(selection, Variable.class); + + if(vars.isEmpty()) { + // Selection did not contain variables + Set ress = ISelectionUtils.filterSetSelection(selection, Resource.class); + List runtimes = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_VARIABLE_RESOURCE, Resource.class); + if(!runtimes.isEmpty()) { + // Selection is most probably in a diagram + Resource runtime = runtimes.get(0); + + // Get variables for selected resources + for(Resource resource : ress) { + Variable variable = getVariable(graph, resource, runtime); + if(variable != null) + vars.add(variable); + } + + // If there is no vars and only one selection, it can be a chart + if(vars.isEmpty() && ress.size() == 1) { + Resource r = ress.iterator().next(); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + if(graph.isInstanceOf(r, jfree.ChartElement)) { + if(graph.hasStatement(r, jfree.ChartElement_component)) { + r = graph.getSingleObject(r, jfree.ChartElement_component); + selectionChanged(graph, r); + return null; + } + } + } + + } else { + // Selection is a jfreechart + if(ress.size() == 1) { + Resource r = ress.iterator().next(); + JFreeChartResource jfree = JFreeChartResource.getInstance(graph); + if(graph.isInstanceOf(r, jfree.Chart)) { + selectionChanged(graph, r); + return null; + } + } + } + } + + // Update datasets and add result listeners to models + return getDatasets(graph, vars); + + } + }, listener); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + } + + + + /** + * Updates datasets for the selected variables + * @param graph ReadGraph + * @param variables Selected variables + * @throws DatabaseException + */ + private ArrayList getDatasets(ReadGraph graph, Collection variables) throws DatabaseException { + + ArrayList datasets = new ArrayList(); + for(Variable variable : variables) { + Variable v = graph.syncRequest(new PossibleActiveVariableFromVariable(variable)); + if(v == null) + continue; + // Get all active datasets for the variable and add them to the result + Variable dsVariable = v.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#"); + Object object = null; + if(dsVariable != null) + object = dsVariable.getValue(graph); + + if(object != null && object instanceof ArrayList) + for(Object o : (ArrayList)object) { + if(o instanceof SysdynDataSet) + datasets.add((SysdynDataSet)o); + } + } + + return datasets; + } + + + /** + * Find a variable representing element + * + * @param g ReadGraph + * @param element Element resource + * @param runtime runtime resource + * @return Variable representing element + * @throws DatabaseException + */ + private Variable getVariable(ReadGraph g, Resource element, Resource runtime) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + DiagramResource dr = DiagramResource.getInstance(g); + if(runtime == null) return null; + Resource resource = ModelingUtils.getPossibleElementCorrespondendence(g, element); + if(resource != null && g.isInstanceOf(resource, sr.Shadow)) resource = g.getPossibleObject(resource, sr.Shadow_original); + if(resource == null || !g.isInstanceOf(resource, sr.Variable)) return null; + String variableURI = g.getPossibleRelatedValue(runtime, dr.RuntimeDiagram_HasVariable); + if(variableURI != null) { + try { + Variable compositeVariable = Variables.getVariable(g, variableURI); + return compositeVariable.browsePossible(g, resource); + } catch (MissingVariableException e) {} + } + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ExportWizardFunction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ExportWizardFunction.java new file mode 100644 index 00000000..5b5667b1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ExportWizardFunction.java @@ -0,0 +1,53 @@ +package org.simantics.sysdyn.ui.wizards.functions; + + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; +import org.simantics.db.Resource; +import org.simantics.utils.ui.AdaptionUtils; + + +public class ExportWizardFunction extends Wizard implements IImportWizard { + + private WizardFunctionsExportPage mainPage; + private IStructuredSelection currentSelection = null; + private String initialPath = null; + public Resource selection; + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ExportWizardFunction() { + this(null); + } + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ExportWizardFunction(String initialPath) + { + super(); + this.initialPath = initialPath; + } + + public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + setWindowTitle("Export"); + this.currentSelection = currentSelection; + selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class); + } + + public void addPages() { + super.addPages(); + mainPage = new WizardFunctionsExportPage( + "wizardFunctionsExportPage", initialPath, currentSelection); //$NON-NLS-1$ + addPage(mainPage); + } + + @Override + public boolean performFinish() { + return mainPage.createProjects(selection); + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeFunctionLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeFunctionLabeler.java new file mode 100644 index 00000000..37d85e05 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeFunctionLabeler.java @@ -0,0 +1,20 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode; + +public class FunctionTreeFunctionLabeler extends LabelerContributor>{ + + @Override + public String getLabel(ReadGraph graph, FunctionLibraryNode input) + throws DatabaseException { + String name = NameUtils.getSafeName(graph, input.data); + return name; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeLibraries.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeLibraries.java new file mode 100644 index 00000000..f2344247 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeLibraries.java @@ -0,0 +1,37 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode; +import org.simantics.sysdyn.ui.browser.nodes.ModelNode; + +public class FunctionTreeLibraries extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, ModelNode model) + throws DatabaseException { + ArrayList> result = new ArrayList>(); + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + for (Resource r : graph.syncRequest(new ObjectsWithType(model.data, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))){ + result.add(new FunctionLibraryNode(r)); + } + + return result; + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModelLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModelLabeler.java new file mode 100644 index 00000000..1a2003ab --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModelLabeler.java @@ -0,0 +1,17 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.ModelNode; + +public class FunctionTreeModelLabeler extends LabelerContributorImpl{ + + @Override + public String getLabel(ReadGraph graph, ModelNode input) + throws DatabaseException { + return NameUtils.getSafeName(graph, input.data); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModels.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModels.java new file mode 100644 index 00000000..623f1a30 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModels.java @@ -0,0 +1,43 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.ModelNode; + +public class FunctionTreeModels extends ViewpointContributorImpl { + + @Override + public Collection getContribution(ReadGraph graph, Resource input) + throws DatabaseException { + + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + ArrayList> result = new ArrayList>(); + for(Resource r : graph.syncRequest(new ObjectsWithType(input, l0.ConsistsOf, sr.SysdynModel))) { + result.add(new ModelNode(r)); + } + Resource sharedlibrary = graph.getPossibleResource("http://SharedOntologies"); + if (sharedlibrary != null) + result.add(new SharedFunctionsFolderNode(sharedlibrary)); + + return result; + } + + @Override + public String getViewpointId() { + return "Function Library Import"; + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedFolderLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedFolderLabeler.java new file mode 100644 index 00000000..17f53686 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedFolderLabeler.java @@ -0,0 +1,15 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; + +public class FunctionTreeSharedFolderLabeler extends LabelerContributorImpl{ + + @Override + public String getLabel(ReadGraph graph, SharedFunctionsFolderNode input) + throws DatabaseException { + return "Shared Functions"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraries.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraries.java new file mode 100644 index 00000000..e9003a1a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraries.java @@ -0,0 +1,35 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode; + +public class FunctionTreeSharedLibraries extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, SharedFunctionsFolderNode folder) + throws DatabaseException { + ArrayList result = new ArrayList(); + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Resource sharedlibrary = graph.getPossibleResource("http://SharedOntologies"); + for (Resource r : graph.syncRequest(new ObjectsWithType(sharedlibrary, l0.ConsistsOf, sr.SharedFunctionOntology))){ + result.add(new SharedFunctionLibraryNode(r)); + } + return result; + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraryLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraryLabeler.java new file mode 100644 index 00000000..e054cf60 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraryLabeler.java @@ -0,0 +1,17 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode; + +public class FunctionTreeSharedLibraryLabeler extends LabelerContributorImpl{ + + @Override + public String getLabel(ReadGraph graph, SharedFunctionLibraryNode input) + throws DatabaseException { + return NameUtils.getSafeName(graph, input.data); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSubLibraries.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSubLibraries.java new file mode 100644 index 00000000..c88421a3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSubLibraries.java @@ -0,0 +1,36 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode; + +public class FunctionTreeSubLibraries extends ViewpointContributor> { + + @Override + public Collection getContribution(ReadGraph graph, FunctionLibraryNode library) + throws DatabaseException { + ArrayList> result = new ArrayList>(); + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + for (Resource r : graph.syncRequest(new ObjectsWithType(library.data, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))){ + result.add(new FunctionLibraryNode(r)); + } + + return result; + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ImportWizardFunction.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ImportWizardFunction.java new file mode 100644 index 00000000..b51a3226 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ImportWizardFunction.java @@ -0,0 +1,54 @@ +package org.simantics.sysdyn.ui.wizards.functions; + + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; +import org.simantics.db.Resource; +import org.simantics.utils.ui.AdaptionUtils; + + +public class ImportWizardFunction extends Wizard implements IImportWizard { + + private WizardFunctionsImportPage mainPage; + private IStructuredSelection currentSelection = null; + private String initialPath = null; + public Resource selection; + + /** + * Constructor for ImportWizardFunction. + */ + public ImportWizardFunction() { + this(null); + } + + /** + * Constructor for ImportWizardFunction. + */ + public ImportWizardFunction(String initialPath) + { + super(); + this.initialPath = initialPath; + } + + public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + setWindowTitle("Import"); + this.currentSelection = currentSelection; + selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class); + } + + public void addPages() { + super.addPages(); + mainPage = new WizardFunctionsImportPage( + "wizardFunctionsImportPage", initialPath, currentSelection); //$NON-NLS-1$ + addPage(mainPage); + } + + @Override + public boolean performFinish() { + return mainPage.createProjects(); + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/SharedFunctionsFolderNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/SharedFunctionsFolderNode.java new file mode 100644 index 00000000..2658fb65 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/SharedFunctionsFolderNode.java @@ -0,0 +1,60 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDropTargetNode; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode; +import org.simantics.ui.SimanticsUI; +import org.simantics.ui.utils.ResourceAdaptionUtils; + +public class SharedFunctionsFolderNode extends FunctionLibraryNode implements IDropTargetNode { + + public SharedFunctionsFolderNode(Resource resource) { + super(resource); + } + + @Override + public void delete() throws DeleteException { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + + graph.deny(data, l0.PartOf); + graph.deny(data, l0.IsLinkedTo_Inverse); + + // TODO: remove file + } + }); + } + + @Override + public void drop(Object data) { + final Resource[] resources = ResourceAdaptionUtils.toResources(data); + final Resource library = this.data; + if(resources.length > 0) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + for(Resource tobeMoved : resources) { + if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) || + graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) { + graph.deny(tobeMoved, l0.PartOf); + graph.claim(tobeMoved, l0.PartOf, library); + } + } + } + }); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsExportPage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsExportPage.java new file mode 100644 index 00000000..06b421f2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsExportPage.java @@ -0,0 +1,366 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.simantics.browsing.ui.swt.AdaptableHintContext; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Files; +import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.primitiverequest.PossibleRelatedValue; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.TransferableGraphRequest2; +import org.simantics.db.request.Read; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.datastructures.Pair; + +public class WizardFunctionsExportPage extends WizardPage { + + // dialog store id constants + private Text filePathField; + + // Keep track of the archive that we browsed to last time + // the wizard was invoked. + private static String previouslyBrowsedFile = ""; + + private Button browseDirectoriesButton; + + //private IStructuredSelection currentSelection; + + GraphExplorerComposite functionLibraryExplorer; + + private boolean selectionMade = false; + + /** + * Creates a new project creation wizard page. + * + */ + public WizardFunctionsExportPage() { + this("wizardFunctionsExportPage", null, null); //$NON-NLS-1$ + } + + /** + * Create a new instance of the receiver. + * + * @param pageName + */ + public WizardFunctionsExportPage(String pageName) { + this(pageName,null, null); + } + + /** + * More (many more) parameters. + * + * @param pageName + * @param initialPath + * @param currentSelection + * @since 3.5 + */ + public WizardFunctionsExportPage(String pageName,String initialPath, + IStructuredSelection currentSelection) { + super(pageName); + //this.currentSelection = currentSelection; + setPageComplete(false); + setTitle("Export Function Library"); + setDescription("Choose the Function Library and the export location, then press Finish."); + } + + public void createControl(Composite parent) { + + initializeDialogUnits(parent); + + Composite workArea = new Composite(parent, SWT.NONE); + setControl(workArea); + + workArea.setLayout(new GridLayout()); + workArea.setLayoutData(new GridData(GridData.FILL_BOTH + | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); + + createProjectsRoot(workArea); + createTree(workArea); + + } + + private void createProjectsRoot(Composite workArea) { + + // set label for field + Label title = new Label(workArea, SWT.NONE); + title.setText("Select the export location for Function Library:"); + + Composite projectGroup = new Composite(workArea, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 0; + + projectGroup.setLayout(layout); + projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // function library location entry field + this.filePathField = new Text(projectGroup, SWT.BORDER); + + GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false); + directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25); + filePathField.setLayoutData(directoryPathData); + + filePathField.addModifyListener(new ModifyListener(){ + @Override + public void modifyText(ModifyEvent e) { + previouslyBrowsedFile = filePathField.getText(); + } + }); + if (previouslyBrowsedFile != null){ + filePathField.setText(previouslyBrowsedFile); + validatePage(); + } + + // browse button + browseDirectoriesButton = new Button(projectGroup, SWT.PUSH); + browseDirectoriesButton.setText("Browse"); + setButtonLayoutData(browseDirectoriesButton); + + browseDirectoriesButton.addSelectionListener(new SelectionAdapter() { + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.SelectionAdapter#widgetS + * elected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + handleLocationDirectoryButtonPressed(); + } + }); + + } + + private void createTree(Composite workArea){ + + //set label for tree + Label title = new Label(workArea, SWT.NONE); + title.setText("Select Function Library to export:"); + + try { + Resource input = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) + throws DatabaseException { + Resource model = SimanticsUI.getProject().get(); + return model; + } + + }); + + functionLibraryExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE); + + functionLibraryExplorer + .setBrowseContexts(SysdynResource.URIs.FunctionTree); + + functionLibraryExplorer.finish(); + + functionLibraryExplorer.setInput(null, input); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + functionLibraryExplorer); + + ((Tree)functionLibraryExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + setMessage(null); + selectionMade = true; + validatePage(); + } + @Override + public void widgetDefaultSelected(SelectionEvent e) { + setMessage(null); + selectionMade = true; + validatePage(); + } + }); + + } catch (DatabaseException e) { + e.printStackTrace(); + } + + + } + + //Set filePathField active + public void setVisible(boolean visible) { + super.setVisible(visible); + this.filePathField.setFocus(); + } + + + //Open dialog for choosing the file + protected void handleLocationDirectoryButtonPressed() { + + final Shell shell = filePathField.getShell(); + + FileDialog dialog = new FileDialog(shell, SWT.SAVE); + + String[] ext = {"*.tg"}; + dialog.setFilterExtensions(ext); + + dialog.setText("Export Function Library"); + + String dirName = filePathField.getText().trim(); + + File path = new File(dirName); + if (path.exists()) { + dialog.setFilterPath(new Path(dirName).toOSString()); + } + + String selectedFile = dialog.open(); + if (selectedFile != null) { + filePathField.setText(selectedFile); + validatePage(); + } + + } + + //Get selection from the tree + @SuppressWarnings("unchecked") + public static T getExplorerResource(GraphExplorerComposite explorer, + Class clazz) { + if(explorer == null) + return null; + ISelection selection = ((ISelectionProvider) explorer + .getAdapter(ISelectionProvider.class)).getSelection(); + if (selection == null) + return null; + IStructuredSelection iss = (IStructuredSelection) selection; + AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement(); + if (inc == null) + return null; + final T resource = (T) inc.getAdapter(clazz); + + return resource; + } + + public boolean createProjects(Resource selection) { + + final String selected = previouslyBrowsedFile; + if(selected == null) return false; + + final Resource functionLibrary = getExplorerResource(functionLibraryExplorer, Resource.class); + if(functionLibrary == null) return false; + + String name = null; + try { + name = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + if (!graph.hasStatement(functionLibrary, Layer0.getInstance(graph).PartOf)) + return null; + Layer0 l0 = Layer0.getInstance(graph); + String name = graph.syncRequest(new PossibleRelatedValue(functionLibrary, l0.HasName, Bindings.STRING )); + return name; + + } + + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + if(name == null) return false; + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + String name = graph.syncRequest(new PossibleRelatedValue(functionLibrary, l0.HasName, Bindings.STRING )); + ArrayList> roots = new ArrayList>(); + roots.add(Pair.make(functionLibrary, name)); + TransferableGraph1 tg = graph.syncRequest(new TransferableGraphRequest2(roots, functionLibrary)); + + try { + Files.createFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class), tg); + } catch (RuntimeBindingConstructionException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + + } + }); + + return true; + } + + void validatePage() { + + if (previouslyBrowsedFile.isEmpty() || selectionMade == false){ + setPageComplete(false); + return; + } + + if (functionLibraryExplorer != null){ + final Resource selectedResource = getExplorerResource(functionLibraryExplorer, Resource.class); + + String root = null; + try { + root = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Resource model = graph.getPossibleObject(selectedResource, l0.PartOf); + String rootName = NameUtils.getSafeName(graph, model); + + return rootName; + } + + }); + if (root != null && root.equalsIgnoreCase("Development Project")){ + setPageComplete(false); + setMessage("Select Function Library folder under the Model or from the Shared Functions folder."); + return; + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + setPageComplete(true); + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsImportPage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsImportPage.java new file mode 100644 index 00000000..3e5600ae --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsImportPage.java @@ -0,0 +1,441 @@ +package org.simantics.sysdyn.ui.wizards.functions; + +import java.io.File; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.simantics.browsing.ui.swt.AdaptableHintContext; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; + +public class WizardFunctionsImportPage extends WizardPage{ + + // dialog store id constants + private Text filePathField; + + // Keep track of the archive that we browsed to last time + // the wizard was invoked. + private static String previouslyBrowsedFile = ""; + + private Button browseDirectoriesButton; + + private Shell shell; + + //private IStructuredSelection currentSelection; + + private Resource selectedModel; + + GraphExplorerComposite functionLibraryExplorer; + + private boolean selectionMade = false; + + /** + * Creates a new project creation wizard page. + * + */ + public WizardFunctionsImportPage() { + this("wizardFunctionsImportPage", null, null); //$NON-NLS-1$ + } + + /** + * Create a new instance of the receiver. + * + * @param pageName + */ + public WizardFunctionsImportPage(String pageName) { + this(pageName,null, null); + } + + /** + * More (many more) parameters. + * + * @param pageName + * @param initialPath + * @param currentSelection + * @since 3.5 + */ + public WizardFunctionsImportPage(String pageName,String initialPath, + IStructuredSelection currentSelection) { + super(pageName); + setPageComplete(false); + //this.currentSelection = currentSelection; + setTitle("Import Function Library"); + setDescription("Choose the Function Library file and the import location, then press Finish."); + } + + public void createControl(Composite parent) { + + initializeDialogUnits(parent); + + Composite workArea = new Composite(parent, SWT.NONE); + setControl(workArea); + + workArea.setLayout(new GridLayout()); + workArea.setLayoutData(new GridData(GridData.FILL_BOTH + | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); + + createProjectsRoot(workArea); + + createTree(workArea); + + + } + + private void createProjectsRoot(Composite workArea) { + + //set label for field + Label title = new Label(workArea, SWT.NONE); + title.setText("Select Function Library source:"); + + Composite projectGroup = new Composite(workArea, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 0; + + projectGroup.setLayout(layout); + projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // module location entry field + this.filePathField = new Text(projectGroup, SWT.BORDER); + + GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false); + directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25); + filePathField.setLayoutData(directoryPathData); + + + filePathField.addModifyListener(new ModifyListener(){ + @Override + public void modifyText(ModifyEvent e) { + previouslyBrowsedFile = filePathField.getText(); + } + }); + if (previouslyBrowsedFile != null){ + filePathField.setText(previouslyBrowsedFile); + validatePage(); + } + + // browse button + browseDirectoriesButton = new Button(projectGroup, SWT.PUSH); + browseDirectoriesButton.setText("Browse"); + setButtonLayoutData(browseDirectoriesButton); + + browseDirectoriesButton.addSelectionListener(new SelectionAdapter() { + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.SelectionAdapter#widgetS + * elected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + handleLocationDirectoryButtonPressed(); + } + }); + + } + + private void createTree(Composite workArea){ + + //set label for tree + Label title = new Label(workArea, SWT.NONE); + title.setText("Select import location:"); + + try { + Resource input = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) + throws DatabaseException { + Resource model = SimanticsUI.getProject().get(); + return model; + } + + }); + + functionLibraryExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE); + + functionLibraryExplorer + .setBrowseContexts(SysdynResource.URIs.FunctionTree); + + functionLibraryExplorer.finish(); + + functionLibraryExplorer.setInput(null, input); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + functionLibraryExplorer); + + ((Tree)functionLibraryExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + selectionMade = true; + validatePage(); + } + @Override + public void widgetDefaultSelected(SelectionEvent e) { + selectionMade = true; + validatePage(); + } + }); + + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + //Set filePathField active + public void setVisible(boolean visible) { + super.setVisible(visible); + this.filePathField.setFocus(); + } + + //Open dialog for choosing the file + protected void handleLocationDirectoryButtonPressed() { + + shell = filePathField.getShell(); + + FileDialog dialog = new FileDialog(shell, SWT.OPEN); + + String[] ext = {"*.tg"}; + dialog.setFilterExtensions(ext); + + dialog.setText("Import Function Library"); + + String dirName = filePathField.getText().trim(); + + File path = new File(dirName); + if (path.exists()) { + dialog.setFilterPath(new Path(dirName).toOSString()); + } + + String selectedFile = dialog.open(); + if (selectedFile != null) { + filePathField.setText(selectedFile); + validatePage(); + } + } + + //Get selection from the tree + @SuppressWarnings("unchecked") + public static T getExplorerResource(GraphExplorerComposite explorer, + Class clazz) { + + if(explorer == null) + return null; + ISelection selection = ((ISelectionProvider) explorer + .getAdapter(ISelectionProvider.class)).getSelection(); + if (selection == null) + return null; + IStructuredSelection iss = (IStructuredSelection) selection; + AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement(); + if (inc == null) + return null; + final T resource = (T) inc.getAdapter(clazz); + + return resource; + } + + //Create project after finish is pressed. + public boolean createProjects() { + + selectedModel= getExplorerResource(functionLibraryExplorer, Resource.class); + if(selectedModel == null){ + setErrorMessage("Error when retrieving resource"); + return false; + } + + String selected = previouslyBrowsedFile; + if(selected == null){ + setErrorMessage("No file selected"); + return false; + } + + IStatus status = ImportUtilsUI.importFunctionLibrary(selectedModel, selected, null); + + /* + TransferableGraph1 tg = null; + try { + tg = (TransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class)); + } catch (RuntimeBindingConstructionException e) { + e.printStackTrace(); + return false; + } catch (IOException e) { + setErrorMessage("The imported file is not of type: Function Library"); + return false; + } + if(tg == null){ + setErrorMessage("The imported file is not of type: Function Library"); + return false; + } + + + try { + Boolean hasSharedOntologies; + hasSharedOntologies = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + try { + graph.getResource("http://SharedOntologies"); + } catch (ResourceNotFoundException e) { + return false; + } + return true; + } + }); + + if(!hasSharedOntologies) { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + GraphUtils.create2(graph, l0.Library, + l0.HasName, "SharedOntologies", + l0.PartOf, graph.getResource("http:/")); + } + }); + + } + } catch (DatabaseException e) { + e.printStackTrace(); + return false; + } + + + SysdynFunctionLibraryImportAdvisor ia = new SysdynFunctionLibraryImportAdvisor(selectedModel); + try { + DefaultPasteHandler.defaultExecute(tg, selectedModel, ia); + } catch (Exception e) { + e.printStackTrace(); + } + + final Resource root = ia.getRoot(); + + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + if(graph.isInstanceOf(root, SysdynResource.getInstance(graph).SharedFunctionOntology)) { + Resource library = graph.getResource("http://SharedOntologies"); + if(!graph.hasStatement(library, l0.ConsistsOf, root)) { + graph.claim(library, l0.ConsistsOf, root); + } + + SysdynResource sr = SysdynResource.getInstance(graph); + Resource model = selectedModel; + while(!graph.isInstanceOf(model, sr.SysdynModel) && graph.isInstanceOf(model, l0.Ontology)) + model = graph.getSingleObject(model, l0.PartOf); + if(graph.isInstanceOf(model, sr.SysdynModel)) { + graph.claim(model, l0.IsLinkedTo, l0.IsLinkedTo_Inverse, root); + } + + } else if(!graph.isInstanceOf(root, SysdynResource.getInstance(graph).SysdynModelicaFunctionLibrary)) { + Resource instanceOf = graph.getPossibleObject(root,l0.InstanceOf); + String type = "..."; + if(instanceOf != null) + type = NameUtils.getSafeName(graph, instanceOf); + else { + Resource inheritedFrom = graph.getPossibleObject(root, l0.Inherits); + if(inheritedFrom != null) + type = NameUtils.getSafeName(graph, inheritedFrom); + } + graph.deny(root, l0.PartOf); + error = type; + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + if (!error.isEmpty()){ + setErrorMessage("The imported file is not of type: Function Library (" + error +")"); + error = ""; + return false; + } + */ + if(status == null || !status.equals(Status.OK_STATUS)) { + setErrorMessage(status.getMessage()); + return false; + } + return true; + } + /* + + private class SysdynFunctionLibraryImportAdvisor extends DefaultPasteImportAdvisor { + + public SysdynFunctionLibraryImportAdvisor(Resource library) { + super(library); + } + + @Override + public void analyzeType(ReadGraph graph, Root root) throws DatabaseException { + if(root.type.equals(SysdynResource.URIs.SharedFunctionOntology)) { + try { + library = graph.getResource("http://SharedOntologies"); + } catch (ResourceNotFoundException e) { + e.printStackTrace(); + } + } + } + + @Override + public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException { + Layer0 l0 = graph.getService(Layer0.class); + this.root = graph.newResource(); + graph.claim(library, l0.ConsistsOf, l0.PartOf, this.root); + String name = root.name; + String newName = nameMappings.get(name); + graph.addLiteral(this.root, l0.HasName, l0.NameOf, l0.String, newName, Bindings.STRING); + return this.root; + + } + + } + */ + + void validatePage() { + + if (previouslyBrowsedFile.isEmpty() || selectionMade == false){ + setPageComplete(false); + return; + } + setErrorMessage(null); + setPageComplete(true); + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/ImportWizardMdl.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/ImportWizardMdl.java new file mode 100644 index 00000000..91422841 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/ImportWizardMdl.java @@ -0,0 +1,47 @@ +package org.simantics.sysdyn.ui.wizards.mdl; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; + +public class ImportWizardMdl extends Wizard implements IImportWizard { + + private WizardMdlImportPage mainPage; + private IStructuredSelection currentSelection = null; + private String initialPath = null; + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ImportWizardMdl() { + this(null); + } + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ImportWizardMdl(String initialPath) + { + super(); + this.initialPath = initialPath; + } + + public void addPages() { + super.addPages(); + mainPage = new WizardMdlImportPage( + "wizardMdlImportPage", initialPath, currentSelection); //$NON-NLS-1$ + addPage(mainPage); + } + + public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + setWindowTitle("Import"); + this.currentSelection = currentSelection; + } + + @Override + public boolean performFinish() { + return mainPage.createProjects(); + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/WizardMdlImportPage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/WizardMdlImportPage.java new file mode 100644 index 00000000..bf813ba6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/WizardMdlImportPage.java @@ -0,0 +1,204 @@ +package org.simantics.sysdyn.ui.wizards.mdl; + +import java.io.File; + +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.mdlImport.MdlParser; +import org.simantics.sysdyn.mdlImport.mdlElements.Model; +import org.simantics.ui.SimanticsUI; + +public class WizardMdlImportPage extends WizardPage{ + + // dialog store id constants + private Text filePathField; + + // Keep track of the archive that we browsed to last time + // the wizard was invoked. + private static String previouslyBrowsedFile = ""; + + private Button browseDirectoriesButton; + + /** + * Creates a new project creation wizard page. + * + */ + public WizardMdlImportPage() { + this("wizardMdlImportPage", null, null); //$NON-NLS-1$ + } + + /** + * Create a new instance of the receiver. + * + * @param pageName + */ + public WizardMdlImportPage(String pageName) { + this(pageName,null, null); + } + + /** + * More (many more) parameters. + * + * @param pageName + * @param initialPath + * @param currentSelection + * @since 3.5 + */ + public WizardMdlImportPage(String pageName,String initialPath, + IStructuredSelection currentSelection) { + super(pageName); + setPageComplete(false); + setTitle("Import Vensim model"); + setDescription("Choose the Vensim model file (.mdl), then press Finish."); + } + + public void createControl(Composite parent) { + + initializeDialogUnits(parent); + + Composite workArea = new Composite(parent, SWT.NONE); + setControl(workArea); + + workArea.setLayout(new GridLayout()); + workArea.setLayoutData(new GridData(GridData.FILL_BOTH + | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); + + createProjectsRoot(workArea); + } + + private void createProjectsRoot(Composite workArea) { + + // set label for field + Label title = new Label(workArea, SWT.NONE); + title.setText("Select Vensim model source:"); + + Composite projectGroup = new Composite(workArea, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 0; + + projectGroup.setLayout(layout); + projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // model location entry field + this.filePathField = new Text(projectGroup, SWT.BORDER); + + GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false); + directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25); + filePathField.setLayoutData(directoryPathData); + filePathField.addModifyListener(new ModifyListener(){ + @Override + public void modifyText(ModifyEvent e) { + previouslyBrowsedFile = filePathField.getText(); + } + }); + if (previouslyBrowsedFile != null){ + filePathField.setText(previouslyBrowsedFile); + validatePage(); + } + + // browse button + browseDirectoriesButton = new Button(projectGroup, SWT.PUSH); + browseDirectoriesButton.setText("Browse"); + setButtonLayoutData(browseDirectoriesButton); + + browseDirectoriesButton.addSelectionListener(new SelectionAdapter() { + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.SelectionAdapter#widgetS + * elected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + handleLocationDirectoryButtonPressed(); + } + }); + + } + + //Set filePathField active + public void setVisible(boolean visible) { + super.setVisible(visible); + this.filePathField.setFocus(); + } + + //Open dialog for choosing the file + protected void handleLocationDirectoryButtonPressed() { + + final Shell shell = filePathField.getShell(); + + FileDialog dialog = new FileDialog(shell, SWT.OPEN); + String[] ext = {"*.mdl"}; + dialog.setFilterExtensions(ext); + dialog.setText("Import Vensim model (.mdl)"); + + String dirName = filePathField.getText().trim(); + + File path = new File(dirName); + if (path.exists()) { + dialog.setFilterPath(new Path(dirName).toOSString()); + } + + String selectedFile = dialog.open(); + if (selectedFile != null) { + filePathField.setText(selectedFile); + validatePage(); + } + + } + + //Create project after finish is pressed. + public boolean createProjects() { + + final Resource project = SimanticsUI.getProject().get(); + if(project == null) return false; + + String selected = previouslyBrowsedFile; + if(selected == null) return false; + + File file = new File(selected); + + final Model model = MdlParser.parse(file); + + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + model.write(graph, project); + } + }); + + return true; + + } + void validatePage(){ + + if (previouslyBrowsedFile.isEmpty()){ + setPageComplete(false); + return; + } + + setPageComplete(true); + } +} + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ExportWizardModel.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ExportWizardModel.java new file mode 100644 index 00000000..ac820561 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ExportWizardModel.java @@ -0,0 +1,52 @@ +package org.simantics.sysdyn.ui.wizards.models; + + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; +import org.simantics.db.Resource; +import org.simantics.utils.ui.AdaptionUtils; + +public class ExportWizardModel extends Wizard implements IImportWizard { + + private WizardModelsExportPage mainPage; + private IStructuredSelection currentSelection = null; + private String initialPath = null; + public Resource selection; + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ExportWizardModel() { + this(null); + } + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ExportWizardModel(String initialPath) + { + super(); + this.initialPath = initialPath; + } + + public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + setWindowTitle("Export"); + this.currentSelection = currentSelection; + selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class); + } + + public void addPages() { + super.addPages(); + mainPage = new WizardModelsExportPage( + "wizardModelsExportPage", initialPath, currentSelection); //$NON-NLS-1$ + addPage(mainPage); + } + + @Override + public boolean performFinish() { + return mainPage.createProjects(); + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ImportWizardModel.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ImportWizardModel.java new file mode 100644 index 00000000..e743d750 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ImportWizardModel.java @@ -0,0 +1,48 @@ +package org.simantics.sysdyn.ui.wizards.models; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; + + +public class ImportWizardModel extends Wizard implements IImportWizard { + + private WizardModelsImportPage mainPage; + private IStructuredSelection currentSelection = null; + private String initialPath = null; + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ImportWizardModel() { + this(null); + } + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ImportWizardModel(String initialPath) + { + super(); + this.initialPath = initialPath; + } + + public void addPages() { + super.addPages(); + mainPage = new WizardModelsImportPage( + "wizardModelsImportPage", initialPath, currentSelection); //$NON-NLS-1$ + addPage(mainPage); + } + + public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + setWindowTitle("Import"); + this.currentSelection = currentSelection; + } + + @Override + public boolean performFinish() { + return mainPage.createProjects(); + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsExportPage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsExportPage.java new file mode 100644 index 00000000..a7194de6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsExportPage.java @@ -0,0 +1,320 @@ +package org.simantics.sysdyn.ui.wizards.models; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.simantics.browsing.ui.swt.AdaptableHintContext; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Files; +import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.primitiverequest.PossibleRelatedValue; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.TransferableGraphRequest2; +import org.simantics.db.request.Read; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.datastructures.Pair; + +public class WizardModelsExportPage extends WizardPage { + + // dialog store id constants + private Text filePathField; + + // Keep track of the archive that we browsed to last time + // the wizard was invoked. + + private static String previouslyBrowsedFile = ""; + + private Button browseDirectoriesButton; + + //private IStructuredSelection currentSelection; + + private Resource selectedModel; + + GraphExplorerComposite modelExplorer; + + private boolean selectionMade = false; + + + + /** + * Creates a new project creation wizard page. + * + */ + public WizardModelsExportPage() { + this("wizardModelsExportPage", null, null); //$NON-NLS-1$ + } + + /** + * Create a new instance of the receiver. + * + * @param pageName + */ + public WizardModelsExportPage(String pageName) { + this(pageName,null, null); + } + + /** + * More (many more) parameters. + * + * @param pageName + * @param initialPath + * @param currentSelection + * @since 3.5 + */ + public WizardModelsExportPage(String pageName,String initialPath, + IStructuredSelection currentSelection) { + super(pageName); + //this.currentSelection = currentSelection; + setPageComplete(false); + setTitle("Export Model"); + setDescription("Choose the Model and the export location, then press Finish."); + } + + public void createControl(Composite parent) { + + initializeDialogUnits(parent); + + Composite workArea = new Composite(parent, SWT.NONE); + setControl(workArea); + + workArea.setLayout(new GridLayout()); + workArea.setLayoutData(new GridData(GridData.FILL_BOTH + | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); + + createProjectsRoot(workArea); + createTree (workArea); + } + + private void createProjectsRoot(Composite workArea) { + + // set label for field + Label title = new Label(workArea, SWT.NONE); + title.setText("Select the export location for Model:"); + + Composite projectGroup = new Composite(workArea, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 0; + + projectGroup.setLayout(layout); + projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // model location entry field + this.filePathField = new Text(projectGroup, SWT.BORDER); + + GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false); + directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25); + filePathField.setLayoutData(directoryPathData); + + filePathField.addModifyListener(new ModifyListener(){ + @Override + public void modifyText(ModifyEvent e) { + previouslyBrowsedFile = filePathField.getText(); + } + }); + if (previouslyBrowsedFile != null){ + filePathField.setText(previouslyBrowsedFile); + validatePage(); + } + + // browse button + browseDirectoriesButton = new Button(projectGroup, SWT.PUSH); + browseDirectoriesButton.setText("Browse"); + setButtonLayoutData(browseDirectoriesButton); + + browseDirectoriesButton.addSelectionListener(new SelectionAdapter() { + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.SelectionAdapter#widgetS + * elected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + handleLocationDirectoryButtonPressed(); + } + }); + + } + + private void createTree(Composite workArea){ + + //set label for tree + Label title = new Label(workArea, SWT.NONE); + title.setText("Select Model to export:"); + + try { + Resource input = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) + throws DatabaseException { + Resource model = SimanticsUI.getProject().get(); + return model; + } + + }); + + modelExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE); + + modelExplorer + .setBrowseContexts(SysdynResource.URIs.ImportModuleTree); + + modelExplorer.finish(); + + modelExplorer.setInput(null, input); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + modelExplorer); + + ((Tree)modelExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + selectionMade = true; + validatePage(); + } + @Override + public void widgetDefaultSelected(SelectionEvent e) { + selectionMade = true; + validatePage(); + } + }); + + + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + //Set filePathField active + public void setVisible(boolean visible) { + super.setVisible(visible); + this.filePathField.setFocus(); + } + + //Open dialog for choosing the file + protected void handleLocationDirectoryButtonPressed() { + final Shell shell = filePathField.getShell(); + + FileDialog dialog = new FileDialog(shell, SWT.SAVE); + + String[] ext = {"*.tg"}; + dialog.setFilterExtensions(ext); + + dialog.setText("Export Model"); + + String dirName = filePathField.getText().trim(); + + File path = new File(dirName); + if (path.exists()) { + dialog.setFilterPath(new Path(dirName).toOSString()); + } + + String selectedFile = dialog.open(); + if (selectedFile != null) { + filePathField.setText(selectedFile); + validatePage(); + } + + } + //Get selection from the tree + @SuppressWarnings("unchecked") + public static T getExplorerResource(GraphExplorerComposite explorer, + Class clazz) { + + if(explorer == null) + return null; + ISelection selection = ((ISelectionProvider) explorer + .getAdapter(ISelectionProvider.class)).getSelection(); + if (selection == null) + return null; + IStructuredSelection iss = (IStructuredSelection) selection; + AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement(); + if (inc == null) + return null; + final T resource = (T) inc.getAdapter(clazz); + + return resource; + } + + public boolean createProjects() { + + final String selected = previouslyBrowsedFile; + if(selected == null) return false; + + selectedModel= getExplorerResource(modelExplorer, Resource.class); + if(selectedModel == null) + return false; + + // FIXME: Model browser doesn't change its selection even if the selected object is removed, + // so you can try to export a removed model + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + String name = graph.syncRequest(new PossibleRelatedValue(selectedModel, l0.HasName, Bindings.STRING )); + ArrayList> roots = new ArrayList>(); + roots.add(Pair.make(selectedModel, name)); + TransferableGraph1 tg = graph.syncRequest(new TransferableGraphRequest2(roots, selectedModel)); + + try { + Files.createFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class), tg); + } catch (RuntimeBindingConstructionException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + }); + + return true; + } + + void validatePage() { + + if (previouslyBrowsedFile.isEmpty() || selectionMade == false){ + setPageComplete(false); + return; + } + + setPageComplete(true); + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsImportPage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsImportPage.java new file mode 100644 index 00000000..636fd688 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsImportPage.java @@ -0,0 +1,446 @@ +package org.simantics.sysdyn.ui.wizards.models; + +import java.io.File; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; +import org.simantics.ui.SimanticsUI; + +public class WizardModelsImportPage extends WizardPage{ + + private Text filePathField; + + // Keep track of the archive that we browsed to last time + // the wizard was invoked. + private static String previouslyBrowsedFile = ""; + + private Button browseDirectoriesButton; + + private Shell shell; + + /** + * Creates a new project creation wizard page. + * + */ + public WizardModelsImportPage() { + this("wizardModelsImportPage", null, null); //$NON-NLS-1$ + } + + /** + * Create a new instance of the receiver. + * + * @param pageName + */ + public WizardModelsImportPage(String pageName) { + this(pageName,null, null); + } + + /** + * More (many more) parameters. + * + * @param pageName + * @param initialPath + * @param currentSelection + * @since 3.5 + */ + public WizardModelsImportPage(String pageName,String initialPath, + IStructuredSelection currentSelection) { + super(pageName); + //this.initialPath = initialPath; + //this.currentSelection = currentSelection; + setPageComplete(false); + setTitle("Import Model"); + setDescription("Choose the Model file, then press Finish."); + } + + + public void createControl(Composite parent) { + + initializeDialogUnits(parent); + + Composite workArea = new Composite(parent, SWT.NONE); + setControl(workArea); + + workArea.setLayout(new GridLayout()); + workArea.setLayoutData(new GridData(GridData.FILL_BOTH + | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); + + createProjectsRoot(workArea); + } + + private void createProjectsRoot(Composite workArea) { + + // set label for field + Label title = new Label(workArea, SWT.NONE); + title.setText("Select Model source:"); + + Composite projectGroup = new Composite(workArea, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 0; + + projectGroup.setLayout(layout); + projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // model location entry field + this.filePathField = new Text(projectGroup, SWT.BORDER); + + GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false); + directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25); + filePathField.setLayoutData(directoryPathData); + filePathField.addModifyListener(new ModifyListener(){ + @Override + public void modifyText(ModifyEvent e) { + previouslyBrowsedFile = filePathField.getText(); + } + }); + if (previouslyBrowsedFile != null){ + filePathField.setText(previouslyBrowsedFile); + validatePage(); + } + + // browse button + browseDirectoriesButton = new Button(projectGroup, SWT.PUSH); + browseDirectoriesButton.setText("Browse"); + setButtonLayoutData(browseDirectoriesButton); + + browseDirectoriesButton.addSelectionListener(new SelectionAdapter() { + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.SelectionAdapter#widgetS + * elected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + setErrorMessage(null); + handleLocationDirectoryButtonPressed(); + } + }); + } + + + //Set filePathField active + public void setVisible(boolean visible) { + super.setVisible(visible); + this.filePathField.setFocus(); + } + + + //Open dialog for choosing the file + protected void handleLocationDirectoryButtonPressed() { + + shell = filePathField.getShell(); + + FileDialog dialog = new FileDialog(shell, SWT.OPEN); + + String[] ext = {"*.tg"}; + dialog.setFilterExtensions(ext); + + dialog.setText("Import Model"); + + String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODELTPATH); + if(path.isEmpty() || !(new File(path).exists())) + path = Platform.getLocation().toOSString(); + dialog.setFilterPath(path); + + String selectedFile = dialog.open(); + if (selectedFile != null) { + filePathField.setText(selectedFile); + validatePage(); + } + + } + + //Create project after finish is pressed. + public boolean createProjects() { + + Resource project = SimanticsUI.getProject().get(); + if(project == null){ + setErrorMessage("Error when retrieving resource"); + return false; + } + + final String selected = previouslyBrowsedFile; + if(selected == null){ + setErrorMessage("No file selected"); + return false; + } + + IStatus status = ImportUtilsUI.importModelFile(selected, null); + + /* + TransferableGraph1 tg = null; + try { + tg = (TransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class)); + } catch (RuntimeBindingConstructionException e) { + e.printStackTrace(); + } catch (IOException e) { + try { + OldTransferableGraph1 otg = (OldTransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(OldTransferableGraph1.class)); + tg = new TransferableGraph1(otg.resourceCount, otg.identities, otg.statements, otg.values); + } catch (RuntimeBindingConstructionException e1) { + e1.printStackTrace(); + } catch (IOException e1) { + setErrorMessage("The imported file is not of type: System Dynamics Model"); + return false; + } + } + if(tg == null){ + setErrorMessage("The imported file is not of type: System Dynamics Model"); + return false; + } + + try { + + DefaultPasteImportAdvisor ia = new DefaultPasteImportAdvisor(project); + DefaultPasteHandler.defaultExecute(tg, SimanticsUI.getProject().get(), ia); + + // Check that imported resource was actually a model + //and fix changes made to old ontology versions + final Resource root = ia.getRoot(); + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + + if(!graph.isInstanceOf(root, SysdynResource.getInstance(graph).SysdynModel)) { + Resource instanceOf = graph.getPossibleObject(root, Layer0.getInstance(graph).InstanceOf); + String type = "..."; + if(instanceOf != null) + type = NameUtils.getSafeName(graph, instanceOf); + else { + Resource inheritedFrom = graph.getPossibleObject(root, Layer0.getInstance(graph).Inherits); + if(inheritedFrom != null) + type = NameUtils.getSafeName(graph, inheritedFrom); + } + graph.deny(root, Layer0.getInstance(graph).PartOf); + error = type; + } else { + updateOldConfigurationToBaseRealization(graph, root); + addDefaultOntologyLinks(graph, root); + addURIsToDiagrams(graph, root); + addSpreadSheetBook(graph, root); + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + + if (!error.isEmpty()){ + setErrorMessage("The imported file is not of type: System Dynamics Model (" + error +")"); + error = ""; + return false; + } + */ + if(status == null || !status.equals(Status.OK_STATUS)) { + setErrorMessage(status.getMessage()); + return false; + } + return true; + } + + /** + * In old versions base realization was separate. Newer versions use configuration as base realization. + * @param graph WriteGraph + * @param model Imported model + */ + /* + private static void updateOldConfigurationToBaseRealization(WriteGraph graph, Resource model) { + Layer0X L0X = Layer0X.getInstance(graph); + try { + Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration); + if(configuration != null && !graph.hasStatement(configuration, L0X.IsBaseRealizationOf, model)) + graph.claim(configuration, L0X.IsBaseRealizationOf, model); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + */ + + /** + * Links should be exported and imported automatically. If it has failed, the + * default ontology links sysdyn and layer0 are added. + * + * @param graph WriteGraph + * @param model Imported model + */ + /* + private static void addDefaultOntologyLinks(WriteGraph graph, Resource model) { + try { + Layer0 l0 = Layer0.getInstance(graph); + // The links should be exported and imported automatically + Resource sysdyn = graph.getResource("http://www.simantics.org/Sysdyn-1.1"); + Resource layer0 = graph.getResource("http://www.simantics.org/Layer0-1.1"); + if(!graph.hasStatement(model, l0.IsLinkedTo, sysdyn)) + graph.claim(model, l0.IsLinkedTo, sysdyn); + if(!graph.hasStatement(model, l0.IsLinkedTo, layer0)) + graph.claim(model, l0.IsLinkedTo, layer0); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + private static void addURIsToDiagrams(WriteGraph graph, Resource model) { + Layer0 l0 = Layer0.getInstance(graph); + SimulationResource simu = SimulationResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + try { + HashSet configurations = new HashSet(); + + Resource configuration = graph.getPossibleObject(model, simu.HasConfiguration); + if(configuration != null) + configurations.add(configuration); + + for(Resource r : graph.getObjects(model, l0.ConsistsOf)) { + if(graph.isInheritedFrom(r, sr.Module)) { + Resource moduleConfiguration = graph.getPossibleObject(r, sr2.IsDefinedBy); + if(moduleConfiguration != null) + configurations.add(moduleConfiguration); + } + } + + for(Resource conf : configurations) { + Resource configurationDiagram = graph.getPossibleObject(conf, mr.CompositeToDiagram); + if(configurationDiagram != null && !graph.hasStatement(configurationDiagram, l0.PartOf)) { + GraphUtils.create2(graph, l0.Library, + l0.HasName, "__CONTAINER__", + l0.PartOf, conf, + l0.ConsistsOf, configurationDiagram); + } + } + + } catch (DatabaseException e) { + e.printStackTrace(); + } + } +*/ + + /** + * Add a missing spreadsheet book to the model + * + * @param graph + * @param model + */ + /* + private static void addSpreadSheetBook(WriteGraph graph, Resource model) { + try { + Layer0 l0 = Layer0.getInstance(graph); + SpreadsheetResource ssr = SpreadsheetResource.getInstance(graph); + SimulationResource simu = SimulationResource.getInstance(graph); + Resource conf = graph.getPossibleObject(model, simu.HasConfiguration); + if(conf != null && graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, ssr.Book)).isEmpty()) { + Resource book = graph.newResource(); + graph.claim(book, l0.InstanceOf, null, ssr.Book); + graph.addLiteral(book, l0.HasName, l0.NameOf, l0.String, "Book" + UUID.randomUUID().toString(), Bindings.STRING); + graph.claim(conf, l0.ConsistsOf, l0.PartOf, book); + + createSheet(graph, book, "Sheet1", new String[] { }, new int[] { 50 }); + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + */ + /** + * Create a sheet (Copied from SysdynProject) + * + * @param graph + * @param book + * @param name + * @param colNames + * @param colWidths + * @return + * @throws DatabaseException + */ + /* + private static Resource createSheet(WriteGraph graph, Resource book, String name, String[] colNames, int[] colWidths) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + SpreadsheetResource sr = SpreadsheetResource.getInstance(graph); + + Resource result = graph.newResource(); + graph.claim(result, L0.InstanceOf, null, sr.Spreadsheet); + + if(name == null) { + name = NameUtils.findFreshEscapedName(graph, "Sheet", book, sr.HasSheet); + } + graph.claimLiteral(result, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING); + graph.claim(book, L0.ConsistsOf, L0.PartOf, result); + + { + Resource newCell = graph.newResource(); + graph.claim(newCell, L0.InstanceOf, null, sr.Dimensions); + graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Dimensions", Bindings.STRING); + graph.addLiteral(newCell, sr.Dimensions_fitColumns, sr.Dimensions_fitColumns_Inverse, L0.Boolean, false, Bindings.BOOLEAN); + graph.addLiteral(newCell, sr.Dimensions_fitRows, sr.Dimensions_fitRows_Inverse, L0.Boolean, false, Bindings.BOOLEAN); + graph.addLiteral(newCell, sr.Dimensions_columnCount, sr.Dimensions_columnCount_Inverse, L0.Integer, 128, Bindings.INTEGER); + graph.addLiteral(newCell, sr.Dimensions_rowCount, sr.Dimensions_rowCount_Inverse, L0.Integer, 256, Bindings.INTEGER); + graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell); + } + + { + Resource newCell = graph.newResource(); + graph.claim(newCell, L0.InstanceOf, null, sr.Dimensions); + graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Headers", Bindings.STRING); + graph.addLiteral(newCell, sr.Headers_columnLabels, sr.Headers_columnLabels_Inverse, L0.StringArray, colNames, Bindings.STRING_ARRAY); + graph.addLiteral(newCell, sr.Headers_columnWidths, sr.Headers_columnWidths_Inverse, L0.IntegerArray, colWidths, Bindings.INT_ARRAY); + graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell); + } + + { + + double[] doubles = new double[10*2]; + for(int i=0;i<10*2;i++) doubles[i] = i; + + Resource newCell = graph.newResource(); + graph.claim(newCell, L0.InstanceOf, null, sr.DoubleArrayCell); + graph.addLiteral(newCell, sr.DoubleArrayCell_HasWidth, sr.DoubleArrayCell_HasWidth_Inverse, L0.Integer, 10, Bindings.INTEGER); + graph.addLiteral(newCell, sr.HasLocation, sr.HasLocation_Inverse, L0.String, "B2", Bindings.STRING); + graph.addLiteral(newCell, sr.DoubleArrayCell_HasDoubleArray, sr.DoubleArrayCell_HasDoubleArray_Inverse, L0.DoubleArray, doubles, Bindings.DOUBLE_ARRAY); + graph.claim(result, L0X.HasChildVariables, L0X.HasChildVariables_Inverse, newCell); + + } + + return result; + + } + */ + void validatePage(){ + + if (previouslyBrowsedFile.isEmpty()){ + setPageComplete(false); + return; + } + setErrorMessage(null); + setPageComplete(true); + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ExportWizardModule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ExportWizardModule.java new file mode 100644 index 00000000..a8084439 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ExportWizardModule.java @@ -0,0 +1,54 @@ +package org.simantics.sysdyn.ui.wizards.modules; + + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; +import org.simantics.db.Resource; +import org.simantics.utils.ui.AdaptionUtils; + + +public class ExportWizardModule extends Wizard implements IImportWizard { + + private WizardModulesExportPage mainPage; + private IStructuredSelection currentSelection = null; + private String initialPath = null; + public Resource selection; + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ExportWizardModule() { + this(null); + } + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ExportWizardModule(String initialPath) + { + super(); + this.initialPath = initialPath; + } + + public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + setWindowTitle("Export"); + this.currentSelection = currentSelection; + selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class); + } + + public void addPages() { + super.addPages(); + mainPage = new WizardModulesExportPage( + "wizardModulesExportPage", initialPath, currentSelection); //$NON-NLS-1$ + addPage(mainPage); + } + + @Override + public boolean performFinish() { + return mainPage.createProjects(); + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ImportWizardModule.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ImportWizardModule.java new file mode 100644 index 00000000..a3893667 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ImportWizardModule.java @@ -0,0 +1,54 @@ +package org.simantics.sysdyn.ui.wizards.modules; + + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; +import org.simantics.db.Resource; +import org.simantics.utils.ui.AdaptionUtils; + + +public class ImportWizardModule extends Wizard implements IImportWizard { + + private WizardModulesImportPage mainPage; + private IStructuredSelection currentSelection = null; + private String initialPath = null; + public Resource selection; + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ImportWizardModule() { + this(null); + } + + /** + * Constructor for ExternalProjectImportWizard. + */ + public ImportWizardModule(String initialPath) + { + super(); + this.initialPath = initialPath; + } + + public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + setWindowTitle("Import"); + this.currentSelection = currentSelection; + selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class); + } + + public void addPages() { + super.addPages(); + mainPage = new WizardModulesImportPage( + "wizardModulesImportPage", initialPath, currentSelection); //$NON-NLS-1$ + addPage(mainPage); + } + + @Override + public boolean performFinish() { + return mainPage.createProjects(); + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleComponentTypeNode.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleComponentTypeNode.java new file mode 100644 index 00000000..7b501811 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleComponentTypeNode.java @@ -0,0 +1,161 @@ +package org.simantics.sysdyn.ui.wizards.modules; + +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.common.node.DeleteException; +import org.simantics.browsing.ui.common.node.IDeletableNode; +import org.simantics.browsing.ui.common.node.IModifiableNode; +import org.simantics.browsing.ui.content.Labeler.Modifier; +import org.simantics.browsing.ui.graph.impl.LabelModifier; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.layer0.adapter.PasteHandler; +import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.ui.SimanticsUI; + +public class ModuleComponentTypeNode extends AbstractNode implements IDeletableNode, IModifiableNode { + + + Listener configurationNameSynchronizer; + private boolean disposed = false; + private Resource configuration; + + public ModuleComponentTypeNode(Resource resource) { + super(resource); + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + configuration = graph.getPossibleObject(data, sr2.IsDefinedBy); + } + }); + + // Not the best solution for name sync + configurationNameSynchronizer = new Listener() { + + @Override + public void execute(final String result) { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + if(configuration != null) + graph.claimLiteral(configuration, Layer0.getInstance(graph).HasLabel, result); + } + }); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + }; + + SimanticsUI.getSession().asyncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + return graph.getRelatedValue(data, l0.HasName); + } + + }, configurationNameSynchronizer); + + } + + @Override + public Modifier getModifier(String columnId) { + Modifier modifier = null; + try { + modifier = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Modifier perform(ReadGraph graph) throws ManyObjectsForFunctionalRelationException, ServiceException { + ModelingResources mr = ModelingResources.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource type = graph.getPossibleObject(data, mr.SymbolToComponentType); + + LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), type, l0.HasName) { + @Override + public String isValid(String label) { + if (label.isEmpty()) + return "Empty name not allowed"; + return null; + } + }; + + + return modifier; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + return modifier; + } + + @Override + public void delete() throws DeleteException { + disposed = true; + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 st = StructuralResource2.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + + Resource type = graph.getPossibleObject(data, mr.SymbolToComponentType); + Resource model = graph.getSingleObject(type, l0.PartOf); + Resource modelConfiguration = graph.getSingleObject(model, SimulationResource.getInstance(graph).HasConfiguration); + if (!graph.syncRequest(new ObjectsWithType(modelConfiguration, l0.ConsistsOf, type)).isEmpty()) { + System.out.println("The module is used at the model configuration"); + return; + } + Collection moduleTypes = graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, st.ComponentType)); + for(Resource r : moduleTypes) { + Resource configuration = graph.getSingleObject(r, st.IsDefinedBy); + if(!graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, type)).isEmpty()) { + System.out.println("The module is used at another module: " + graph.getRelatedValue(r, l0.HasName)); + return; + } + } + graph.deny(model, l0.ConsistsOf, type); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + if(PasteHandler.class == adapter && configuration != null) + return new DefaultPasteHandler(configuration); + return super.getAdapter(adapter); + } +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModels.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModels.java new file mode 100644 index 00000000..272a2af5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModels.java @@ -0,0 +1,40 @@ +package org.simantics.sysdyn.ui.wizards.modules; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.common.node.AbstractNode; +import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.browser.nodes.ModelNode; + +public class ModuleTreeModels extends ViewpointContributorImpl { + + @Override + public Collection getContribution(ReadGraph graph, Resource input) + throws DatabaseException { + + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + ArrayList> result = new ArrayList>(); + for(Resource r : graph.syncRequest(new ObjectsWithType(input, l0.ConsistsOf, sr.SysdynModel))) { + result.add(new ModelNode(r)); + } + + return result; + } + + @Override + public String getViewpointId() { + return "Module Import"; + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModules.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModules.java new file mode 100644 index 00000000..76f76f85 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModules.java @@ -0,0 +1,35 @@ +package org.simantics.sysdyn.ui.wizards.modules; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.ui.browser.nodes.ModelNode; + +public class ModuleTreeModules extends ViewpointContributor { + + @Override + public Collection getContribution(ReadGraph graph, ModelNode model) + throws DatabaseException { + ArrayList result = new ArrayList(); + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + for (Resource r : graph.syncRequest(new ObjectsWithType(model.data, l0.ConsistsOf, sr2.ComponentType))){ + result.add(new ModuleComponentTypeNode(r)); + } + + return result; + } + + @Override + public String getViewpointId() { + return "Standard"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModulesLabeler.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModulesLabeler.java new file mode 100644 index 00000000..0aa030a9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModulesLabeler.java @@ -0,0 +1,16 @@ +package org.simantics.sysdyn.ui.wizards.modules; + +import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl; +import org.simantics.db.ReadGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; + +public class ModuleTreeModulesLabeler extends LabelerContributorImpl{ + + @Override + public String getLabel(ReadGraph graph, ModuleComponentTypeNode input) + throws DatabaseException { + return NameUtils.getSafeName(graph, input.data); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesExportPage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesExportPage.java new file mode 100644 index 00000000..d14135a9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesExportPage.java @@ -0,0 +1,475 @@ +package org.simantics.sysdyn.ui.wizards.modules; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.simantics.browsing.ui.swt.AdaptableHintContext; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Files; +import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.primitiverequest.PossibleRelatedValue; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.TransferableGraphRequest2; +import org.simantics.db.request.Read; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; +import org.simantics.utils.datastructures.Pair; + +public class WizardModulesExportPage extends WizardPage { + + // dialog store id constants + private Text filePathField; + + // Keep track of the archive that we browsed to last time + // the wizard was invoked. + private static String previouslyBrowsedFile = ""; + + private Button browseDirectoriesButton; + + private Resource selectedModule; + + GraphExplorerComposite modelExplorer; + + private boolean selectionMade = false; + + /** + * Creates a new project creation wizard page. + * + */ + public WizardModulesExportPage() { + this("wizardModulesExportPage", null, null); //$NON-NLS-1$ + } + + /** + * Create a new instance of the receiver. + * + * @param pageName + */ + public WizardModulesExportPage(String pageName) { + this(pageName,null, null); + } + + /** + * More (many more) parameters. + * + * @param pageName + * @param initialPath + * @param currentSelection + * @since 3.5 + */ + public WizardModulesExportPage(String pageName,String initialPath, + IStructuredSelection currentSelection) { + super(pageName); + //this.currentSelection = currentSelection; + setPageComplete(false); + setTitle("Export Module"); + setDescription("Choose the Module and the export location, then press Finish."); + } + + public void createControl(Composite parent) { + + initializeDialogUnits(parent); + + Composite workArea = new Composite(parent, SWT.NONE); + setControl(workArea); + + workArea.setLayout(new GridLayout()); + workArea.setLayoutData(new GridData(GridData.FILL_BOTH + | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); + + createProjectsRoot(workArea); + createTree(workArea); + } + + private void createProjectsRoot(Composite workArea) { + + // set label for field + Label title = new Label(workArea, SWT.NONE); + title.setText("Select the export location for Module:"); + + Composite projectGroup = new Composite(workArea, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 0; + + projectGroup.setLayout(layout); + projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // module location entry field + this.filePathField = new Text(projectGroup, SWT.BORDER); + + GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false); + directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25); + filePathField.setLayoutData(directoryPathData); + + filePathField.addModifyListener(new ModifyListener(){ + @Override + public void modifyText(ModifyEvent e) { + previouslyBrowsedFile = filePathField.getText(); + } + }); + if (previouslyBrowsedFile != null){ + filePathField.setText(previouslyBrowsedFile); + validatePage(); + } + + // browse button + browseDirectoriesButton = new Button(projectGroup, SWT.PUSH); + browseDirectoriesButton.setText("Browse"); + setButtonLayoutData(browseDirectoriesButton); + + browseDirectoriesButton.addSelectionListener(new SelectionAdapter() { + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.SelectionAdapter#widgetS + * elected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + handleLocationDirectoryButtonPressed(); + } + }); + + } + + private void createTree(Composite workArea){ + + //set label for tree + Label title = new Label(workArea, SWT.NONE); + title.setText("Select Module to export:"); + + try { + Resource input = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) + throws DatabaseException { + Resource model = SimanticsUI.getProject().get(); + return model; + } + + }); + + modelExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE); + + modelExplorer + .setBrowseContexts(SysdynResource.URIs.ExportModuleTree); + + modelExplorer.finish(); + + modelExplorer.setInput(null, input); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + modelExplorer); + + ((Tree)modelExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + setMessage(null); + selectionMade = true; + validatePage(); + } + @Override + public void widgetDefaultSelected(SelectionEvent e) { + setMessage(null); + selectionMade = true; + validatePage(); + } + }); + + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + //Set filePathField active + public void setVisible(boolean visible) { + super.setVisible(visible); + this.filePathField.setFocus(); + } + + //Open dialog for choosing the file + protected void handleLocationDirectoryButtonPressed() { + + final Shell shell = filePathField.getShell(); + + FileDialog dialog = new FileDialog(shell, SWT.SAVE); + + String[] ext = {"*.tg"}; + dialog.setFilterExtensions(ext); + + dialog.setText("Export Module"); + + String dirName = filePathField.getText().trim(); + + File path = new File(dirName); + if (path.exists()) { + dialog.setFilterPath(new Path(dirName).toOSString()); + } + + String selectedFile = dialog.open(); + if (selectedFile != null) { + filePathField.setText(selectedFile); + validatePage(); + } + + } + + //Get selection from the tree + @SuppressWarnings("unchecked") + public static T getExplorerResource(GraphExplorerComposite explorer, + Class clazz) { + + if(explorer == null) + return null; + ISelection selection = ((ISelectionProvider) explorer + .getAdapter(ISelectionProvider.class)).getSelection(); + if (selection == null) + return null; + IStructuredSelection iss = (IStructuredSelection) selection; + AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement(); + if (inc == null) + return null; + final T resource = (T) inc.getAdapter(clazz); + + return resource; + } + + //Create export file when finish is pressed + public boolean createProjects() { + + final String selected = previouslyBrowsedFile; + if(selected == null) return false; + + selectedModule= getExplorerResource(modelExplorer, Resource.class); + if(selectedModule == null) + return false; + + String name = null; + try { + name = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + + Resource component = selectedModule; + if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf)) + return null; + + Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy); + if (configuration == null) + return null; + + ArrayList dependencies = null; + for(Resource r : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Module))) { + if(dependencies == null) + dependencies = new ArrayList(); + String name = NameUtils.getSafeName(graph, r); + String instanceOf = NameUtils.getSafeName(graph, graph.getSingleObject(r, l0.InstanceOf)); + dependencies.add(name + " : " + instanceOf); + } + if(dependencies != null && !dependencies.isEmpty()) + throw new ContainsDependenciesException(dependencies); + + String name = graph.getPossibleRelatedValue(component, l0.HasName, Bindings.STRING); + return name; + + } + + }); + } + catch (DatabaseException e1) { + e1.printStackTrace(); + } + if(name == null) return false; + + SimanticsUI.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + + final Resource component = selectedModule; + //final Resource component = graph.getPossibleObject(modulesymbol, mr.SymbolToComponentType); + if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf)) + return; + String name = graph.syncRequest(new PossibleRelatedValue(component, l0.HasName, Bindings.STRING )); + final ArrayList> roots = new ArrayList>(); + roots.add(Pair.make(component, name)); + + graph.asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + final Resource modulesymbol = graph.getPossibleObject(component, mr.ComponentTypeToSymbol); + Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy); + if (!graph.hasStatement(configuration, l0.PartOf, component)&& + !graph.hasStatement(modulesymbol, l0.PartOf, component)) { + // Make sure that configuration and symbol are included. + // In old versions, they were attached to model, not to module. + Resource previousPartof = graph.getSingleObject(configuration, l0.PartOf); + + graph.deny(configuration, l0.PartOf); + graph.deny(modulesymbol, l0.PartOf); + graph.claim(configuration, l0.PartOf, l0.ConsistsOf, component); + graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, component); + + export(graph, selected, roots, component); + + graph.deny(configuration, l0.PartOf); + graph.deny(modulesymbol, l0.PartOf); + graph.claim(configuration, l0.PartOf, l0.ConsistsOf, previousPartof); + graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, previousPartof); + } else { + // Normal export + export(graph, selected, roots, component); + } + } + }); + + } + }); + + return true; + } + + private void export(WriteGraph graph, String path, ArrayList> roots, Resource component) { + + // FIXME: Enumeration replacement handling like this is not suitable. + try { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + + Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy); + ArrayList> replacements = new ArrayList>(); + + for(Resource enumeration : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) { + if(graph.hasStatement(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) { + for(Resource replacement : graph.getObjects(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) { + replacements.add(new Pair(enumeration, replacement)); + } + } + } + + for(Pair replacement : replacements) + graph.deny(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second); + + TransferableGraph1 tg = graph.syncRequest(new TransferableGraphRequest2(roots, component)); + Files.createFile(new File(path), Bindings.getBindingUnchecked(TransferableGraph1.class), tg); + + for(Pair replacement : replacements) + graph.claim(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second); + + } catch (RuntimeBindingConstructionException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + class ContainsDependenciesException extends DatabaseException { + private static final long serialVersionUID = -1533706136673146020L; + + private Collection dependencies; + + ContainsDependenciesException(Collection dependencies) { + this.dependencies = dependencies; + } + + public Collection getDependencies() { + return this.dependencies; + } + + } + + void validatePage() { + + if (previouslyBrowsedFile.isEmpty() || selectionMade == false){ + setPageComplete(false); + return; + } + + if (modelExplorer != null){ + final Resource selectedResource = getExplorerResource(modelExplorer, Resource.class); + + String root = null; + try { + root = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Resource model = graph.getPossibleObject(selectedResource, l0.PartOf); + String rootName = NameUtils.getSafeName(graph, model); + + return rootName; + } + + }); + if (root != null && root.equalsIgnoreCase("Development Project")){ + setPageComplete(false); + setMessage("Select Module under the Model."); + return; + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + setPageComplete(true); + + } + + + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesImportPage.java b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesImportPage.java new file mode 100644 index 00000000..65976791 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesImportPage.java @@ -0,0 +1,365 @@ +package org.simantics.sysdyn.ui.wizards.modules; + +import java.io.File; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.simantics.browsing.ui.swt.AdaptableHintContext; +import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.ArrayMap; + + +public class WizardModulesImportPage extends WizardPage{ + + public static String IMPORTMODULETPATH = "IMPORT_MODULE_PATH"; + + // dialog store id constants + + private Text filePathField; + + // Keep track of the archive that we browsed to last time + // the wizard was invoked. + private static String previouslyBrowsedFile = ""; + + private Button browseDirectoriesButton; + + private Shell shell; + + //private IStructuredSelection currentSelection; + + private Resource selectedModel; + + GraphExplorerComposite modelExplorer; + + private boolean selectionMade = false; + + /** + * Creates a new project creation wizard page. + * + */ + public WizardModulesImportPage() { + this("wizardModulesImportPage", null, null); //$NON-NLS-1$ + } + + /** + * Create a new instance of the receiver. + * + * @param pageName + */ + public WizardModulesImportPage(String pageName) { + this(pageName,null, null); + } + + /** + * More (many more) parameters. + * + * @param pageName + * @param initialPath + * @param currentSelection + * @since 3.5 + */ + public WizardModulesImportPage(String pageName,String initialPath, + IStructuredSelection currentSelection) { + super(pageName); + setPageComplete(false); + //this.currentSelection = currentSelection; + setTitle("Import Module"); + setDescription("Choose the Module file and the import location, then press Finish."); + } + + public void createControl(Composite parent) { + + initializeDialogUnits(parent); + + Composite workArea = new Composite(parent, SWT.NONE); + setControl(workArea); + + workArea.setLayout(new GridLayout()); + workArea.setLayoutData(new GridData(GridData.FILL_BOTH + | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); + + createProjectsRoot(workArea); + + createTree(workArea); + } + + private void createProjectsRoot(Composite workArea) { + + // set label for field + Label title = new Label(workArea, SWT.NONE); + title.setText("Select Module source:"); + + Composite projectGroup = new Composite(workArea, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 0; + + projectGroup.setLayout(layout); + projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // module location entry field + this.filePathField = new Text(projectGroup, SWT.BORDER); + + GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false); + directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25); + filePathField.setLayoutData(directoryPathData); + + filePathField.addModifyListener(new ModifyListener(){ + @Override + public void modifyText(ModifyEvent e) { + previouslyBrowsedFile = filePathField.getText(); + } + }); + if (previouslyBrowsedFile != null){ + filePathField.setText(previouslyBrowsedFile); + validatePage(); + } + + // browse button + browseDirectoriesButton = new Button(projectGroup, SWT.PUSH); + browseDirectoriesButton.setText("Browse"); + setButtonLayoutData(browseDirectoriesButton); + + browseDirectoriesButton.addSelectionListener(new SelectionAdapter() { + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.events.SelectionAdapter#widgetS + * elected(org.eclipse.swt.events.SelectionEvent) + */ + public void widgetSelected(SelectionEvent e) { + handleLocationDirectoryButtonPressed(); + } + }); + + } + + private void createTree(Composite workArea){ + + //set label for tree + Label title = new Label(workArea, SWT.NONE); + title.setText("Select import location:"); + + try { + Resource input = SimanticsUI.getSession().syncRequest(new Read() { + + @Override + public Resource perform(ReadGraph graph) + throws DatabaseException { + Resource model = SimanticsUI.getProject().get(); + return model; + } + + }); + + modelExplorer = new GraphExplorerComposite(ArrayMap.keys( + "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE); + + modelExplorer + .setBrowseContexts(SysdynResource.URIs.ImportModuleTree); + + modelExplorer.finish(); + + modelExplorer.setInput(null, input); + + GridDataFactory.fillDefaults().grab(true, true).applyTo( + modelExplorer); + + ((Tree)modelExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + selectionMade = true; + validatePage(); + } + @Override + public void widgetDefaultSelected(SelectionEvent e) { + selectionMade = true; + validatePage(); + } + }); + + + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + //Set filePathField active + public void setVisible(boolean visible) { + super.setVisible(visible); + this.filePathField.setFocus(); + } + + //Open dialog for choosing the file + protected void handleLocationDirectoryButtonPressed() { + + shell = filePathField.getShell(); + + FileDialog dialog = new FileDialog(shell, SWT.OPEN); + + String[] ext = {"*.tg"}; + dialog.setFilterExtensions(ext); + + dialog.setText("Import Module"); + + String dirName = filePathField.getText().trim(); + + File path = new File(dirName); + if (path.exists()) { + dialog.setFilterPath(new Path(dirName).toOSString()); + } + + String selectedFile = dialog.open(); + if (selectedFile != null) { + filePathField.setText(selectedFile); + validatePage(); + } + } + + //Get selection from the tree + @SuppressWarnings("unchecked") + public static T getExplorerResource(GraphExplorerComposite explorer, + Class clazz) { + + if(explorer == null) + return null; + ISelection selection = ((ISelectionProvider) explorer + .getAdapter(ISelectionProvider.class)).getSelection(); + if (selection == null) + return null; + IStructuredSelection iss = (IStructuredSelection) selection; + AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement(); + if (inc == null) + return null; + final T resource = (T) inc.getAdapter(clazz); + + return resource; + } + + //Create project after finish is pressed. + public boolean createProjects() { + + String selected = previouslyBrowsedFile; + if(selected == null){ + setErrorMessage("Error when retrieving resource"); + return false; + } + + selectedModel= getExplorerResource(modelExplorer, Resource.class); + if(selectedModel == null){ + setErrorMessage("No file selected"); + return false; + } + + IStatus status = ImportUtilsUI.importModuleFile(selectedModel, selected, null); + + /* + TransferableGraph1 tg = null; + try { + tg = (TransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class)); + } catch (RuntimeBindingConstructionException e) { + e.printStackTrace(); + } catch (IOException e) { + setErrorMessage("The imported file is not of type: Module Type"); + return false; + } + if(tg == null){ + setErrorMessage("The imported file is not of type: Module Type"); + return false; + } + + + DefaultPasteImportAdvisor ia = new DefaultPasteImportAdvisor(selectedModel); + try { + DefaultPasteHandler.defaultExecute(tg, selectedModel, ia); + } catch (MissingDependencyException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + + final Resource root = ia.getRoot(); + + try { + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + if(!graph.isInheritedFrom(root, SysdynResource.getInstance(graph).Module)) { + Resource instanceOf = graph.getPossibleObject(root, Layer0.getInstance(graph).InstanceOf); + String type = "..."; + if(instanceOf != null) + type = NameUtils.getSafeName(graph, instanceOf); + else { + Resource inheritedFrom = graph.getPossibleObject(root, Layer0.getInstance(graph).Inherits); + if(inheritedFrom != null) + type = NameUtils.getSafeName(graph, inheritedFrom); + } + graph.deny(root, Layer0.getInstance(graph).PartOf); + error = type; + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + if (!error.isEmpty()){ + setErrorMessage("The imported file is not of type: Module Type (" + error +")"); + error = ""; + return false; + } + */ + if(status == null || !status.equals(Status.OK_STATUS)) { + setErrorMessage(status.getMessage()); + return false; + } + + return true; + } + + void validatePage() { + + if (previouslyBrowsedFile.isEmpty() || selectionMade == false){ + setPageComplete(false); + return; + } + + setErrorMessage(null); + setPageComplete(true); + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn.ui/sysdyn.product b/dev-jkauttio/org.simantics.sysdyn.ui/sysdyn.product new file mode 100644 index 00000000..ebda30ea --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn.ui/sysdyn.product @@ -0,0 +1,122 @@ + + + + + + + + %about.text + + + + + + + + -fixerrors +--launcher.XXMaxPermSize 192m +-data @noDefault + -ea -Xmx768M -XX:MaxPermSize=192m -Xshare:off -Dorg.simantics.undo.enabled=false + -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts + + + + + + + + + + + + + + org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6 + + + + http://www.eclipse.org/legal/epl-v10.html + + Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: +i) changes to the Program, and +ii) additions to the Program; +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and +b) its license agreement: +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and +b) a copy of this Agreement must be included with each copy of the Program. +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn/.classpath b/dev-jkauttio/org.simantics.sysdyn/.classpath new file mode 100644 index 00000000..8a8f1668 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn/.hgignore b/dev-jkauttio/org.simantics.sysdyn/.hgignore new file mode 100644 index 00000000..73df90f6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/.hgignore @@ -0,0 +1,5 @@ +syntax: regexp +^bin/ + +syntax: glob +*.svn/* \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn/.project b/dev-jkauttio/org.simantics.sysdyn/.project new file mode 100644 index 00000000..05d44396 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/.project @@ -0,0 +1,28 @@ + + + org.simantics.sysdyn + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-jkauttio/org.simantics.sysdyn/.settings/org.eclipse.jdt.core.prefs b/dev-jkauttio/org.simantics.sysdyn/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..785aae6f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Nov 16 15:37:44 EET 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/dev-jkauttio/org.simantics.sysdyn/META-INF/MANIFEST.MF b/dev-jkauttio/org.simantics.sysdyn/META-INF/MANIFEST.MF new file mode 100644 index 00000000..6c9fef50 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/META-INF/MANIFEST.MF @@ -0,0 +1,61 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Simantics System Dynamics +Bundle-SymbolicName: org.simantics.sysdyn;singleton:=true +Bundle-Version: 1.7.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Require-Bundle: org.simantics.objmap;bundle-version="0.1.0", + org.simantics.db;bundle-version="0.6.2", + org.simantics.modelica;bundle-version="1.0.0", + org.simantics.db.common;bundle-version="0.8.0", + org.simantics.simulation;bundle-version="1.0.0", + org.eclipse.ui.console;bundle-version="3.4.0", + org.eclipse.core.runtime;bundle-version="3.5.0", + org.eclipse.jface;bundle-version="3.5.2", + org.simantics.project;bundle-version="1.0.0", + org.simantics.layer0.utils;bundle-version="0.8.0", + org.simantics.layer0;bundle-version="1.0.0", + org.simantics.structural.ontology;bundle-version="1.0.0", + org.simantics.sysdyn.ontology;bundle-version="1.0.0", + org.simantics.modeling;bundle-version="1.1.1", + org.simantics.diagram;bundle-version="1.1.1", + org.simantics.diagram.ontology;bundle-version="1.1.1", + org.simantics.scl.runtime;bundle-version="0.1.3", + org.simantics.db.layer0;bundle-version="1.1.0", + org.simantics.spreadsheet.common;bundle-version="1.1.0", + org.simantics.spreadsheet;bundle-version="1.1.0", + org.eclipse.jface.text;bundle-version="3.6.1", + org.simantics.spreadsheet.ontology;bundle-version="1.2.0", + org.simantics.fmu;bundle-version="1.0.0", + org.simantics.fmu.me.win32;bundle-version="1.0.0", + org.simantics.issues;bundle-version="1.1.0", + org.simantics.issues.common;bundle-version="1.1.0", + org.simantics.jfreechart;bundle-version="1.0.0", + org.jfree.jchart;bundle-version="1.0.13", + org.jfree.jcommon;bundle-version="1.0.16", + org.simantics.spreadsheet.graph;bundle-version="1.1.0", + fi.semantum.sysdyn.solver;bundle-version="0.1.0" +Export-Package: org.simantics.sysdyn, + org.simantics.sysdyn.adapter, + org.simantics.sysdyn.elementaryCycles, + org.simantics.sysdyn.expressionParser, + org.simantics.sysdyn.manager, + org.simantics.sysdyn.mdlImport, + org.simantics.sysdyn.mdlImport.mdlElements, + org.simantics.sysdyn.modelParser, + org.simantics.sysdyn.modelica, + org.simantics.sysdyn.representation, + org.simantics.sysdyn.representation.expressions, + org.simantics.sysdyn.representation.utils, + org.simantics.sysdyn.representation.visitors, + org.simantics.sysdyn.simulation, + org.simantics.sysdyn.solver, + org.simantics.sysdyn.tableParser, + org.simantics.sysdyn.utils, + org.simantics.sysdyn.utils.imports +Bundle-Activator: org.simantics.sysdyn.Activator +Bundle-ActivationPolicy: lazy +Import-Package: org.eclipse.ui, + org.simantics.sysdyn.utils, + org.simantics.ui +Bundle-Vendor: VTT Technical Reserarch Centre of Finland diff --git a/dev-jkauttio/org.simantics.sysdyn/ModelicaParser.html b/dev-jkauttio/org.simantics.sysdyn/ModelicaParser.html new file mode 100644 index 00000000..157b944c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/ModelicaParser.html @@ -0,0 +1,727 @@ + + + +BNF for ModelicaParser.jj + + +

BNF for ModelicaParser.jj

+

TOKENS

+ + + + + + + + + + + + + +
+
+/*** Lexer *********************************************************/
+
+
+<DEFAULT> SKIP : {
+<WHITESPACE: " " | "\n" | "\r" | "\t">
+| <COMMENT1: "/*" (~["*"] | "*" ~["/"])* "*/">
+| <COMMENT2: "//" (~["\n"])*>
+}
+
+   
+
+
+<DEFAULT> TOKEN : {
+"algorithm"
+| "discrete"
+| "false"
+| "model"
+| "redeclare"
+| "and"
+| "each"
+| "final"
+| "not"
+| "replaceable"
+| "annotation"
+| "else"
+| "flow"
+| "operator"
+| "return"
+| "assert"
+| "elseif"
+| "for"
+| "or"
+| "stream"
+| "block"
+| "elsewhen"
+| "function"
+| "outer"
+| "then"
+| "break"
+| "encapsulated"
+| "if"
+| "output"
+| "true"
+| "class"
+| "end"
+| "import"
+| "package"
+| "type"
+| "connect"
+| "enumeration"
+| "in"
+| "parameter"
+| "when"
+| "connector"
+| "equation"
+| "initial"
+| "partial"
+| "while"
+| "constant"
+| "expandable"
+| "inner"
+| "protected"
+| "within"
+| "constrainedby"
+| "extends"
+| "input"
+| "public"
+| "der"
+| "external"
+| "loop"
+| "record"
+| "("
+| ")"
+| "{"
+| "}"
+| "["
+| "]"
+| "."
+| ":"
+| ";"
+| ","
+| "<"
+| "<="
+| ">"
+| ">="
+| "=="
+| "<>"
+| "+"
+| "-"
+| ".+"
+| ".-"
+| "*"
+| "/"
+| ".*"
+| "./"
+| "^"
+| ".^"
+| "="
+| ":="
+| <IDENT: ["a"-"z","A"-"Z","_"] (["a"-"z","A"-"Z","_","0"-"9"])*>
+| <STRING: "\"" (~["\"","\\","\n"] | "\\" ~["\n"])* "\""> : {
+| <UNSIGNED_INTEGER: (["0"-"9"])+>
+| <UNSIGNED_NUMBER: <UNSIGNED_INTEGER> "." (<UNSIGNED_INTEGER>)? (["e","E"] <UNSIGNED_INTEGER>)? | "." <UNSIGNED_INTEGER> (["e","E"] <UNSIGNED_INTEGER>)? | <UNSIGNED_INTEGER> ["e","E"] <UNSIGNED_INTEGER>>
+}
+
+   
+
+

NON-TERMINALS

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+/*** Parser ********************************************************/
+
+// https://javacc.dev.java.net/doc/javaccgrm.html
+// add_op -> add_op()
+// [ add_op ] -> ( add_op() )?
+// { add_op term } -> ( add_op() term() )*
+
+
parse::=stored_definition <EOF>
+
+/*** Stored Definition - Within ************************************/
+
stored_definition::=( "within" ( name )? ";" )? ( ( "final" )? class_definition ";" )*
+
+/*** Class Definition **********************************************/
+
class_definition::=( "encapsulated" )? ( "partial" )? ( "class" | "model" | "record" | "block" | ( "expandable" )? "connector" | "type" | "package" | "function" | "operator" | "operator function" | "operator record" ) class_specifier
class_specifier::=<IDENT> string_comment composition "end" <IDENT>
|<IDENT> "=" base_prefix name ( array_subscripts )? ( class_modification )? comment
|<IDENT> "=" "enumeration" "(" ( ( enum_list )? | ":" ) ")" comment
|<IDENT> "=" "der" "(" name "," <IDENT> ( "," <IDENT> )* ")" comment
|"extends" <IDENT> ( class_modification )? string_comment composition "end" <IDENT>
base_prefix::=type_prefix
enum_list::=enumeration_literal ( "," enumeration_literal )*
enumeration_literal::=<IDENT> comment
parse_composition::=composition <EOF>
composition::=element_list ( "public" element_list | "protected" element_list | equation_section | algorithm_section )* ( "external" ( language_specification )? ( external_function_call )? ( annotation )? ";" )? ( annotation ";" )?
language_specification::=<STRING>
external_function_call::=( component_reference "=" )? <IDENT> "(" ( expression_list )? ")"
element_list::=( element ";" )*
element::=import_clause
|extends_clause
|( "redeclare" )? ( "final" )? ( "inner" )? ( "outer" )? ( ( class_definition | component_clause ) | "replaceable" ( class_definition | component_clause ) ( constraining_clause comment )? )
import_clause::="import" ( <IDENT> "=" name | name ( "." "*" )? ) comment
+
+/*** Extends *******************************************************/
+
extends_clause::="extends" name ( class_modification )? ( annotation )?
constraining_clause::="constrainedby" name ( class_modification )?
+
+/*** Component Clause **********************************************/
+
component_clause::=( type_prefix ) ( type_specifier ) ( array_subscripts )? ( component_list )
type_prefix::=( "flow" | "stream" )? ( "discrete" | "parameter" | "constant" )? ( "output" | "input" )?
type_specifier::=name
component_list::=component_declaration ( "," component_declaration )*
component_declaration::=declaration ( conditional_attribute )? comment
conditional_attribute::="if" expression
declaration::=<IDENT> ( array_subscripts )? ( modification )?
+
+/*** Modification **********************************************/
+
modification::=( class_modification ( "=" expression )? | "=" expression | ":=" expression )
class_modification::="(" ( argument_list )? ")"
argument_list::=argument ( "," argument )*
argument::=element_modification_or_replaceable
|element_redeclaration
element_modification_or_replaceable::=( "each" )? ( "final" )? ( element_modification | element_replaceable )
element_modification::=name ( modification )? string_comment
element_redeclaration::="redeclare" ( "each" )? ( "final" )? ( ( class_definition | component_clause1 ) | element_replaceable )
element_replaceable::="replaceable" ( class_definition | component_clause1 ) ( constraining_clause )?
component_clause1::=type_prefix type_specifier component_declaration1
component_declaration1::=declaration comment
+
+/*** Equations *************************************************/
+
equation_section::=( "initial" )? "equation" ( equation ";" )*
algorithm_section::=( "initial" )? "algorithm" ( statement ";" )*
equation::=( simple_expression "=" expression | if_equation | for_equation | connect_clause | when_equation | <IDENT> function_call_args ) comment
statement::=( component_reference ( ":=" expression | function_call_args ) | "(" output_expression_list ")" ":=" component_reference function_call_args | "break" | "return" | if_statement | for_statement | while_statement | when_statement ) comment
if_equation::="if" expression "then" ( equation ";" )* ( "elseif" expression "then" ( equation ";" )* )* ( "else" ( equation ";" )* )? "end" "if"
if_statement::="if" expression "then" ( statement ";" )* ( "elseif" expression "then" ( statement ";" )* )* ( "else" ( statement ";" )* )? "end" "if"
for_equation::="for" for_indices "loop" ( equation ";" )* "end" "for"
for_statement::="for" for_indices "loop" ( statement ";" )* "end" "for"
for_indices::=for_index ( "," for_index )*
for_index::=<IDENT> ( "in" expression )?
while_statement::="while" expression "loop" ( statement ";" )* "end" "while"
when_equation::="when" expression "then" ( equation ";" )* ( "elsewhen" expression "then" ( equation ";" )* )* "end" "when"
when_statement::="when" expression "then" ( statement ";" )* ( "elsewhen" expression "then" ( statement ";" )* )* "end" "when"
connect_clause::="connect" "(" component_reference "," component_reference ")"
+
+/*** Expressions ***************************************************/
+
expr::=simple_expression <EOF>
|"if" expression "then" expression ( "elseif" expression "then" expression )* "else" expression <EOF>
expression::=simple_expression
|"if" expression "then" expression ( "elseif" expression "then" expression )* "else" expression
simple_expression::=logical_expression ( ":" logical_expression ( ":" logical_expression )? )?
logical_expression::=logical_term ( "or" logical_term )*
logical_term::=logical_factor ( "and" logical_factor )*
logical_factor::=( "not" )? relation
relation::=arithmetic_expression ( rel_op arithmetic_expression )?
rel_op::="<"
|"<="
|">"
|">="
|"=="
|"<>"
arithmetic_expression::=( add_op )? term ( add_op term )*
add_op::="+"
|"-"
|".+"
|".-"
term::=factor ( mul_op factor )*
mul_op::="*"
|"/"
|".*"
|"./"
factor::=primary ( "^" | ".^" primary )?
primary::=<UNSIGNED_NUMBER>
|<UNSIGNED_INTEGER>
|<STRING>
|"false"
|"true"
|( name | "der" | "initial" ) function_call_args
|component_reference
|"(" expression ")"
|"[" expression_list ( ";" expression_list )* "]"
|"{" function_arguments "}"
|"end"
name::=( "." )? <IDENT> ( "." <IDENT> )*
component_reference::=( "." )? <IDENT> ( array_subscripts )? ( "." <IDENT> ( array_subscripts )? )*
function_call_args::="(" ( function_arguments )? ")"
function_arguments::=expression ( "," function_arguments | "for" for_indices )?
|named_arguments
named_arguments::=named_argument ( "," named_arguments )?
named_argument::=<IDENT> "=" expression
output_expression_list::=( expression )? ( "," ( expression )? )*
expression_list::=expression ( "," expression )*
array_subscripts::="[" subscript ( "," subscript )* "]"
subscript::=":"
|expression
comment::=string_comment ( annotation )?
string_comment::=( <STRING> ( "+" <STRING> )* )?
annotation::="annotation" class_modification
+ + diff --git a/dev-jkauttio/org.simantics.sysdyn/adapters.xml b/dev-jkauttio/org.simantics.sysdyn/adapters.xml new file mode 100644 index 00000000..509cd5ea --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/adapters.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn/build.properties b/dev-jkauttio/org.simantics.sysdyn/build.properties new file mode 100644 index 00000000..26e468c9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/build.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2010 Association for Decentralized Information Management in +# Industry THTH ry. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# VTT Technical Research Centre of Finland - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + adapters.xml,\ + plugin.xml,\ + scl/ diff --git a/dev-jkauttio/org.simantics.sysdyn/plugin.xml b/dev-jkauttio/org.simantics.sysdyn/plugin.xml new file mode 100644 index 00000000..e3c4447c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/plugin.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev-jkauttio/org.simantics.sysdyn/scl/Sysdyn.scl b/dev-jkauttio/org.simantics.sysdyn/scl/Sysdyn.scl new file mode 100644 index 00000000..21010c10 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/scl/Sysdyn.scl @@ -0,0 +1,91 @@ +include "Simantics/DB" +include "Simantics/Variables" + +importJava "org.simantics.sysdyn.utils.DocumentationUtils" where + + @JavaName getModules + getModules :: Variable -> [Resource] + + @JavaName getExperimentVariables + getExperimentVariables :: Variable -> [Variable] + + @JavaName getRoleVariables + getRoleVariables :: Variable -> [Variable] + + @JavaName getDocumentVariables + getDocumentVariables :: Variable -> [Variable] + + @JavaName getIndexDocuments + getIndexDocuments :: Variable -> [Variable] + + @JavaName getResultVariables + getResultVariables :: Variable -> [Variable] + + @JavaName getConfiguration + getConfiguration :: Resource -> Resource + + @JavaName getConfigurationVariables + getConfigurationVariables :: Resource -> [Resource] + + @JavaName getName + getName :: Resource -> String + + @JavaName getType + getType :: Resource -> String + + @JavaName getUnit + getUnit :: Resource -> String + + @JavaName getVariability + getVariability :: Resource -> String + + @JavaName getDescription + getDescription :: Resource -> String + + @JavaName getDocumentationDefinition + getDocumentationDefinition :: Resource -> String + + + + @JavaName numberOfVariables + numberOfVariables :: Resource -> Boolean -> Integer + + @JavaName totalNumberOfVariables + totalNumberOfVariables :: Resource -> Boolean -> Integer + + @JavaName numberOfStocks + numberOfStocks :: Resource -> Boolean -> Integer + + @JavaName numberOfValves + numberOfValves :: Resource -> Boolean -> Integer + + @JavaName numberOfInputs + numberOfInputs :: Resource -> Boolean -> Integer + + @JavaName numberOfShadows + numberOfShadows :: Resource -> Boolean -> Integer + + @JavaName numberOfAuxiliaries + numberOfAuxiliaries :: Resource -> Boolean -> Integer + + @JavaName numberOfModules + numberOfModules :: Resource -> Boolean -> Integer + + @JavaName numberOfSheets + numberOfSheets :: Resource -> Boolean -> Integer + + @JavaName numberOfModuleTypes + numberOfModuleTypes :: Variable -> Integer + + @JavaName base64Encode + base64Encode :: Variable -> String -> String + + @JavaName formatDate + formatDate :: Long -> String + + @JavaName importModel + importModel :: String -> () + + @JavaName isParameter + isParameter :: Variable -> Boolean + \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/Activator.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/Activator.java new file mode 100644 index 00000000..640c85fe --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/Activator.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn; + +import java.io.File; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext bundleContext; + + // The plug-in ID + public static final String PLUGIN_ID = "org.simantics.sysdyn"; + + // The shared instance + private static Activator plugin; + + @Override + public void start(BundleContext context) throws Exception { + bundleContext = context; + File modelsDir = Activator.getBundleContext().getDataFile("models"); + if (!modelsDir.exists()) { + modelsDir.mkdir(); + } + plugin = this; + } + + @Override + public void stop(BundleContext context) throws Exception { + File modelsDir = Activator.getBundleContext().getDataFile("models"); + if (modelsDir.exists()) { + recursiveDelete(modelsDir); + } + plugin = null; + + } + + public static Activator getDefault() { + return plugin; + } + + public static BundleContext getBundleContext() { + return bundleContext; + } + + private static boolean recursiveDelete(File fileOrDir) { + if(fileOrDir.isDirectory()) + for(File innerFile: fileOrDir.listFiles()) + if(!recursiveDelete(innerFile)) + return false; + return fileOrDir.delete(); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/Functions.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/Functions.java new file mode 100644 index 00000000..002925aa --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/Functions.java @@ -0,0 +1,197 @@ +package org.simantics.sysdyn; + +import java.util.HashMap; +import java.util.Map; + +import org.simantics.databoard.binding.Binding; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.common.uri.UnescapedChildMapOfResource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.function.All; +import org.simantics.db.layer0.variable.StandardGraphChildVariable; +import org.simantics.db.layer0.variable.ValueAccessor; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.VariableMap; +import org.simantics.db.layer0.variable.VariableMapImpl; +import org.simantics.layer0.Layer0; +import org.simantics.operation.Layer0X; +import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.adapter.ActiveDatasetsIndexVariable; +import org.simantics.sysdyn.adapter.NamesIndexVariable; +import org.simantics.sysdyn.adapter.TimeIndexVariable; +import org.simantics.sysdyn.adapter.TimesIndexVariable; +import org.simantics.sysdyn.adapter.ValueIndexVariable; +import org.simantics.sysdyn.adapter.ValuesIndexVariable; + +public class Functions { + + public static String VALUE = "value"; + public static String VALUES = "values"; + public static String TIME = "time"; + public static String TIMES = "times"; + public static String NAMES = "names"; + public static String ACTIVE_DATASETS = "activeDatasets"; + + @SCLValue(type = "ValueAccessor") + public static ValueAccessor valuePropertyValue = new ValueAccessor() { + + @Override + public Object getValue(ReadGraph graph, Variable context) + throws DatabaseException { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object getValue(ReadGraph graph, Variable context, + Binding binding) throws DatabaseException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setValue(WriteGraph graph, Variable context, Object value) + throws DatabaseException { + // TODO Auto-generated method stub + + } + + @Override + public void setValue(WriteGraph graph, Variable context, Object value, + Binding binding) throws DatabaseException { + // TODO Auto-generated method stub + + } + + }; + + + @SCLValue(type = "VariableMap") + public static VariableMap runProperties = new VariableMapImpl() { + + @Override + public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException { + + String property = context.getName(graph); + if(TIME.equals(property)) + return new TimeIndexVariable(graph, context, name); + else + return null; + } + + @Override + public Map getVariables(ReadGraph graph, Variable context, Map map) throws DatabaseException { + return map; + } + }; + + @SCLValue(type = "VariableMap") + public static VariableMap valuePropertyProperties = new VariableMapImpl() { + + @Override + public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException { + + String property = context.getName(graph); + if(VALUE.equals(property)) + return new ValueIndexVariable(graph, context, name); + else if(VALUES.equals(property)) + return new ValuesIndexVariable(graph, context, name); + else if(TIMES.equals(property)) + return new TimesIndexVariable(graph, context, name); + else if(TIME.equals(property)) + return new TimeIndexVariable(graph, context, name); + else if(NAMES.equals(property)) + return new NamesIndexVariable(graph, context, name); + else if(ACTIVE_DATASETS.equals(property)) + return new ActiveDatasetsIndexVariable(graph, context, name); + else + return null; + } + + @Override + public Map getVariables(ReadGraph graph, Variable context, Map map) throws DatabaseException { + return map; +// Collections.emptyList(); +// StandardGraphChildVariable variable = (StandardGraphChildVariable)context; +// collectPropertiesFromContext(graph, variable, variable.resource, map); + } + + }; + + + @SCLValue(type = "VariableMap") + public static VariableMap runChildren = new VariableMapImpl() { + + @Override + public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException { + StandardGraphChildVariable variable = (StandardGraphChildVariable)context; + Map children = graph.syncRequest(new StructuralChildMapOfResource(getConfiguration(graph, variable))); + Resource child = children.get(name); + if(child == null) return All.getStandardChildDomainChildVariable(graph, context, name); + return graph.getPossibleContextualAdapter(child, variable, Variable.class, Variable.class); + } + + @Override + public Map getVariables(ReadGraph graph, Variable context, Map map) throws DatabaseException { + + StandardGraphChildVariable variable = (StandardGraphChildVariable)context; + + map = All.getStandardChildDomainChildVariables(graph, context, map); + + for(Map.Entry entry : graph.syncRequest(new StructuralChildMapOfResource(getConfiguration(graph, variable))).entrySet()) { + String name = entry.getKey(); + Resource child = entry.getValue(); + Variable var = graph.getPossibleContextualAdapter(child, variable, Variable.class, Variable.class); + if(var != null) { + if(map == null) map = new HashMap(); + map.put(name, var); + } else { + System.err.println("No adapter for " + child + " in " + variable.getURI(graph)); + } + } + + return map; + + } + + Resource getConfiguration(ReadGraph graph, Variable run) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + Resource experiment = graph.getPossibleObject(run.getRepresents(graph), L0.PartOf); + Resource model = graph.getPossibleObject(experiment, L0.PartOf); + return graph.getPossibleObject(model, L0X.HasBaseRealization); + } + + }; + + + static class StructuralChildMapOfResource extends ResourceRead> { + + public StructuralChildMapOfResource(Resource resource) { + super(resource); + } + + @Override + public Map perform(ReadGraph graph) throws DatabaseException { + + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Map directChildren = graph.syncRequest(new UnescapedChildMapOfResource(resource)); + Resource type = graph.getPossibleType(resource, STR.Component); + if(type != null) { + Resource definition = graph.getPossibleObject(type, STR.IsDefinedBy); + if(definition != null) { + return graph.syncRequest(new UnescapedChildMapOfResource(definition)); + } + } + + return directChildren; + + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java new file mode 100644 index 00000000..86b3245c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn; + +import java.io.StringReader; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.ParseException; +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.UnitParser; +import org.simantics.sysdyn.unitParser.nodes.UnitResult; +import org.simantics.sysdyn.utils.Function; + +public class TestParser { + + /** + * @param args + */ + public static void main(String[] args) { + + HashMap units = new HashMap(); + boolean allowEquivalents = true; + + doScenario(scenario1(units), units, allowEquivalents); + doScenario(scenario2(units), units, allowEquivalents); + doScenario(scenario3(units), units, allowEquivalents); + doScenario(scenario4(units), units, allowEquivalents); + doScenario(scenario5(units), units, allowEquivalents); + doScenario(scenario6(units), units, allowEquivalents); + doScenario(scenario7(units), units, allowEquivalents); + doScenario(scenario8(units), units, allowEquivalents); + doScenario(scenario9(units), units, allowEquivalents); + doScenario(scenario10(units), units, allowEquivalents); + doScenario(scenario11(units), units, allowEquivalents); + doScenario(scenario12(units), units, allowEquivalents); + doScenario(scenario13(units), units, allowEquivalents); + + } + + private static void doScenario(String expression, HashMap units, boolean allowEquivalents) { + System.out.println("-----------------------------------"); + System.out.println("Expression: " + expression); + System.out.println("Units: "); + for(String key : units.keySet()) { + System.out.println(" " + key + " -> " + units.get(key)); + } + StringReader sr = new StringReader(expression); + UnitParser parser = new UnitParser(sr); + try { + UnitCheckingNode node = (UnitCheckingNode) parser.expr(); + + try { + UnitResult u = node.getUnits(units, Function.getAllBuiltInFunctions(), allowEquivalents); + System.out.println("Result: " + u.getCleanFullUnit()); + } catch (UnitCheckingException e) { + e.printStackTrace(); + } + +// node.dump(""); + } catch (ParseException e) { + e.printStackTrace(); + } + } + + private static String scenario1(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("a*b*c"); + return sb.toString(); + } + + private static String scenario2(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("a+b+c"); + return sb.toString(); + } + + private static String scenario3(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("a/b+b/c"); + return sb.toString(); + } + + private static String scenario4(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("if a == b then a+b else b + c + a"); + return sb.toString(); + } + + private static String scenario5(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "s"); + units.put("c", "m"); + units.put("d", "s"); + + StringBuilder sb = new StringBuilder(); +// sb.append("a / b + (c*a)/(b*a)"); + sb.append("c/(b*a)"); + + return sb.toString(); + } + + private static String scenario6(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "s"); + units.put("c", "m"); + units.put("d", "m/s"); + + StringBuilder sb = new StringBuilder(); + sb.append("if a > c then c*a/b else a*d"); + return sb.toString(); + } + + private static String scenario7(HashMap units) { + units.clear(); + + units.put("a", "m/s"); + units.put("b.e", "s"); + units.put("c", "m"); + units.put("d", "s"); + + StringBuilder sb = new StringBuilder(); + sb.append("a[1] + c[1] / b.e[1]"); + return sb.toString(); + } + + private static String scenario8(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "s"); + units.put("c", "s*m"); + + StringBuilder sb = new StringBuilder(); + sb.append("c + {a[i] * b[i] for i in 1:3}"); + return sb.toString(); + } + + private static String scenario9(HashMap units) { + units.clear(); + units.put("a", "m"); + units.put("b", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("1+a+1+b"); + return sb.toString(); + } + + private static String scenario10(HashMap units) { + units.clear(); + units.put("a", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("1*a*1*a"); + return sb.toString(); + } + + private static String scenario11(HashMap units) { + units.clear(); + units.put("a", "m"); + units.put("b", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("-a+b"); + return sb.toString(); + } + + private static String scenario12(HashMap units) { + units.clear(); + units.put("a", "m"); + units.put("b", "s"); + units.put("c", "m/s"); + + + StringBuilder sb = new StringBuilder(); + sb.append("1/a/b + 1/c"); + return sb.toString(); + } + + private static String scenario13(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + units.put("d", "s"); + + StringBuilder sb = new StringBuilder(); + sb.append("(a/b+b/c)/d"); + return sb.toString(); + } + +} + + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/ActiveDatasetsIndexVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/ActiveDatasetsIndexVariable.java new file mode 100644 index 00000000..24293812 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/ActiveDatasetsIndexVariable.java @@ -0,0 +1,70 @@ +package org.simantics.sysdyn.adapter; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.modelica.data.DataSet; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.manager.SysdynResult; + +public class ActiveDatasetsIndexVariable extends IndexVariable< ArrayList> { + + public ActiveDatasetsIndexVariable(ReadGraph graph, Variable parent, String indexes) + throws DatabaseException { + super(graph, parent, indexes); + } + + @Override + public ArrayList getValue() { + ArrayList datasets = new ArrayList(); + + if(experiment == null) + return datasets; + + Collection results = experiment.getActiveResults(); + ArrayList variableNamesWithIndexes = getVariableNamesWithIndexNumbers(); + ArrayList variableNames = getVariableNames(); + + for(int i = 0; i < variableNamesWithIndexes.size(); i++) { + for(SysdynResult result : results) { + SysdynDataSet ds = result.getDataSet(variableNamesWithIndexes.get(i)); + if(ds != null) { + + /* Change the name if necessary + Name needs to be changed if it contains indexes. Dataset names + contains indexes as numbers, asked names as index names. + + There are cases where dataset names could actually be different + from asked names. HistoryDatasets are one example. In that case, show the + datasetname. + */ + String askedName = variableNames.get(i); + if(askedName.contains("[")) + askedName = askedName.substring(0, askedName.indexOf("[")); + String datasetname = ds.name.replace("_", " "); + if(datasetname.contains("[")) + datasetname = datasetname.substring(0, datasetname.indexOf("[")); + + if(askedName.equals(datasetname.replace("_", " "))) + ds.name = askedName; + else + ds.name = datasetname; + + datasets.add(ds); + } + } + } + return datasets; + } + + @Override + public void setIndexedValue(WriteGraph graph, Object value) + throws DatabaseException { + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/IndexVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/IndexVariable.java new file mode 100644 index 00000000..3afc87f7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/IndexVariable.java @@ -0,0 +1,272 @@ +package org.simantics.sysdyn.adapter; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.type.Datatype; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ParametrizedPrimitiveRead; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.AbstractPropertyVariable; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.ExternalRead; +import org.simantics.modeling.ModelingResources; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynExperiment; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.manager.VariableSubscriptionManager; +import org.simantics.utils.datastructures.Pair; + +public abstract class IndexVariable extends AbstractPropertyVariable { + + protected Variable parent; + protected SysdynModel model; + protected SysdynExperiment experiment; + protected String rvi; + protected HashMap rvis; + protected String indexes; + protected VariableSubscriptionManager subscriptionManager; + + public IndexVariable(ReadGraph graph, Variable parent, String indexes) throws DatabaseException { + this.parent = parent; + this.indexes = indexes; + } + + + protected VariableSubscriptionManager getSubscriptionManager() { + return this.experiment; + } + + public String getIndexes() { + return this.indexes; + } + + /** + * Register a property subscription + * + * @param request PropertyRequest + * @param procedure + * @return + */ + protected VariableValueSubscription registerSubscription(ExternalRead request, Listener procedure) { + // Other properties are requested from model (they listen to new simulation results) + VariableValueSubscription subscription = new VariableValueSubscription(request, this, procedure); + if(subscriptionManager != null) { + subscriptionManager.addVariableValueSubscription(subscription); + } + subscription.update(); + return subscription; + } + + /** + * Unregisters a subscription + * @param subscription + */ + protected void unregisterSubscription(VariableValueSubscription subscription) { + subscription.setListener(null); + if(subscriptionManager != null) + subscriptionManager.removeVariableValueSubscription(subscription); + } + + + + /** + * Class for supporting requests with different property parameters. Equals-method has been modified + * from ParametrizedPrivimiteRead to check also the property value. + * + * @author Teemu Lempinen + * + */ + class PropertyRequest extends ParametrizedPrimitiveRead { + + + public PropertyRequest(Variable indexVariable) { + super(indexVariable); + } + + VariableValueSubscription subscription; + + @Override + public void register(ReadGraph graph, Listener procedure) { + subscription = registerSubscription(this, procedure); + } + @Override + public void unregistered() { + if(subscription != null) { + unregisterSubscription(subscription); + subscription = null; + } + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object object) { + if(object instanceof IndexVariable.PropertyRequest && super.equals(object)) { + return this.parameter.equals(((PropertyRequest)object).parameter); + } else { + return super.equals(object); + } + } + + } + + @Override + public Resource getPropertyResource(ReadGraph graph) throws DatabaseException { + return null; + } + + @Override + public Resource getContainerResource(ReadGraph graph) throws DatabaseException { + return null; + } + + @Override + public Datatype getDatatype(ReadGraph graph) throws DatabaseException { + return null; + } + + @Override + public Variable getPredicate(ReadGraph graph) throws DatabaseException { + return null; + } + + @SuppressWarnings("unchecked") + @Override + public U getValue(ReadGraph graph) throws DatabaseException { + return (U) getValue(graph, Bindings.DOUBLE); + } + + @SuppressWarnings("unchecked") + @Override + public U getValue(ReadGraph graph, Binding binding) throws DatabaseException { + ensureInformationAvailable(graph); + // Do something before request, e.g. calculate some variables used in the request + beforeRequest(graph); + + return (U) graph.syncRequest(new PropertyRequest(this)); + + } + + protected void beforeRequest(ReadGraph graph) throws DatabaseException { + + } + + private void ensureInformationAvailable(ReadGraph graph) throws DatabaseException { + SimulationResource SIMU = SimulationResource.getInstance(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + + if(model == null) { + Resource modelResource = Variables.getModel(graph, parent); + Resource configuration = graph.getPossibleObject(modelResource, SIMU.HasConfiguration); + model = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configuration); + } + + Variable var = parent.getParent(graph); + Resource represents = var.getRepresents(graph); + + Resource activeRun = null; + if(represents != null) { + do { + if(graph.isInstanceOf(represents, SIMU.Run)) { + activeRun = represents; + break; + } + var = var.getParent(graph); + represents = var.getRepresents(graph); + } while(represents != null && !graph.isInstanceOf(represents, MOD.StructuralModel)); + } + + IProject project = Simantics.peekProject(); + if(activeRun != null && project != null) { + IExperimentManager expMan = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment e = expMan.getExperiment(NameUtils.getSafeName(graph, activeRun)); + if(e instanceof SysdynExperiment) + this.experiment = (SysdynExperiment)e; + } + + this.subscriptionManager = getSubscriptionManager(); + rvi = Variables.getPossibleRVI(graph, this); + if(rvi != null) + rvis = VariableRVIUtils.getActiveRVIs(graph, parent.getParent(graph)); + } + + private Pair,ArrayList> getVariableNameArrays() { + Pair,ArrayList> result = new Pair,ArrayList>(new ArrayList(), new ArrayList()); + if(rvi == null || rvis == null) + return result; + + if(rvi.indexOf('#') > 0) + rvi = rvi.substring(0, rvi.indexOf('#')); + + String test = rvi; + if(indexes != null && !indexes.isEmpty()) { + String regexIndexes = indexes.trim().replaceAll("\\b_\\b", "[a-zA-Z0-9_]*"); // Why was there was ".replace('.', ',')" ? - Removed by Teemu 2.9.2012 + test = rvi + "\\[" + regexIndexes + "\\]"; + } else { + test = rvi + "(\\[.*\\])?"; + } + for(String k : rvis.keySet()) { + if(k.matches(test)) { + String value = rvis.get(k); + result.first.add(k.substring(1).replace("/", ".").replace("%20", "_")); + result.second.add(value.substring(1).replace("/", ".").replace("%20", " ")); + } + } + + return result; + + } + + protected ArrayList getVariableNames() { + return getVariableNameArrays().second; + } + + protected ArrayList getVariableNamesWithIndexNumbers() { + return getVariableNameArrays().first; + } + + abstract public T getValue(); + + @Override + public void setValue(WriteGraph graph, Object value, Binding binding) throws DatabaseException { + setValue(graph, value); + } + + @Override + public void setValue(WriteGraph graph, Object value) throws DatabaseException { + ensureInformationAvailable(graph); + setIndexedValue(graph, value); + } + + abstract protected void setIndexedValue(WriteGraph graph, Object value) throws DatabaseException; + + + + @Override + public String getName(ReadGraph graph) throws DatabaseException { + return indexes; + } + + @Override + public Object getSerialized(ReadGraph graph) throws DatabaseException { + return indexes; + } + + @Override + public Variable getParent(ReadGraph graph) throws DatabaseException { + return parent; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/NamesIndexVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/NamesIndexVariable.java new file mode 100644 index 00000000..7e32bbad --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/NamesIndexVariable.java @@ -0,0 +1,29 @@ +package org.simantics.sysdyn.adapter; + +import java.util.ArrayList; + +import org.simantics.db.ReadGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; + +public class NamesIndexVariable extends IndexVariable { + + public NamesIndexVariable(ReadGraph graph, Variable parent, String indexes) + throws DatabaseException { + super(graph, parent, indexes); + } + + @Override + public String[] getValue() { + ArrayList names = getVariableNames(); + return names.toArray(new String[names.size()]); + } + + @Override + public void setIndexedValue(WriteGraph graph, Object value) + throws DatabaseException { + // TODO Auto-generated method stub + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/SensitivityExperimentParameter.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/SensitivityExperimentParameter.java new file mode 100644 index 00000000..73098986 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/SensitivityExperimentParameter.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.adapter; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.adapter.distribution.IDistribution; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.Variable; +import org.simantics.sysdyn.representation.utils.IndexUtils; +import org.simantics.sysdyn.representation.utils.RepresentationUtils; + +public class SensitivityExperimentParameter { + + private String variableName; + private String[] indexes; + private String fullName; + private IDistribution distribution; + + public SensitivityExperimentParameter(ReadGraph graph, Resource parameter) { + + try { + SysdynResource SR = SysdynResource.getInstance(graph); + Resource distributionResource = graph.getPossibleObject(parameter, SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution); + distribution = graph.adapt(distributionResource, IDistribution.class); + variableName = graph.getPossibleRelatedValue(parameter, SR.SensitivityAnalysisExperiment_Parameter_variable, Bindings.STRING); + indexes = graph.getPossibleRelatedValue(parameter, SR.SensitivityAnalysisExperiment_Parameter_indexes, Bindings.STRING_ARRAY); + + Resource model = graph.syncRequest(new PossibleModel(parameter)); + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration)); + + Variable variable = RepresentationUtils.getVariable(sm.getConfiguration(), variableName); + + if (variable != null) { + if(indexes == null && (variable.getArrayIndexes() != null & variable.getArrayIndexes().size() > 0)) { + indexes = new String[variable.getArrayIndexes().size()]; + + for(int i = 0; i < variable.getArrayIndexes().size(); i++) { + Enumeration e = variable.getArrayIndexes().get(i); + indexes[i] = e.getEnumerationIndexes().get(0).getName(); + } + } + + if(indexes != null) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for(int i = 0; i < indexes.length; i++) { + if(i > 0) + sb.append(","); + + String index = indexes[i]; + sb.append(index); + } + sb.append("]"); + String result = IndexUtils.rangeToIndexes(variable, sb.toString()); + fullName = variableName + result; + } else { + fullName = variableName; + } + } + } catch (DatabaseException e) { + + } + } + + public String getVariableName() { + return variableName; + } + + public String[] getIndexes() { + return indexes; + } + + public String getFullName() { + return fullName; + } + + public IDistribution getDistribution() { + return distribution; + } + + public String getFullModelicaName() { + if (this.fullName == null) + return null; + return this.fullName.replace(' ', '_'); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/TimeIndexVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/TimeIndexVariable.java new file mode 100644 index 00000000..65c34770 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/TimeIndexVariable.java @@ -0,0 +1,32 @@ +package org.simantics.sysdyn.adapter; + +import org.simantics.db.ReadGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.sysdyn.manager.SysdynGameExperiment; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; + +public class TimeIndexVariable extends IndexVariable { + + public TimeIndexVariable(ReadGraph graph, Variable parent, String indexes) + throws DatabaseException { + super(graph, parent, indexes); + } + + @Override + public Double getValue() { + if(experiment != null && experiment instanceof SysdynPlaybackExperiment) + return ((SysdynPlaybackExperiment)experiment).getTime(); + if(experiment != null && experiment instanceof SysdynGameExperiment) + return ((SysdynGameExperiment)experiment).getTime(); + return null; + } + + @Override + public void setIndexedValue(WriteGraph graph, Object value) + throws DatabaseException { + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/TimesIndexVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/TimesIndexVariable.java new file mode 100644 index 00000000..329e4cd2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/TimesIndexVariable.java @@ -0,0 +1,52 @@ +package org.simantics.sysdyn.adapter; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.manager.SysdynResult; + +public class TimesIndexVariable extends IndexVariable { + + public TimesIndexVariable(ReadGraph graph, Variable parent, String indexes) + throws DatabaseException { + super(graph, parent, indexes); + // TODO Auto-generated constructor stub + } + + @Override + public double[][] getValue() { + if(experiment == null) + return new double[0][0]; + + Collection results = experiment.getActiveResults(); + ArrayList variableNames = getVariableNamesWithIndexNumbers(); + + double[][] result = new double[variableNames.size()][]; + for(int i = 0; i < variableNames.size(); i++) { + for(SysdynResult r : results) { + SysdynDataSet ds = r.getDataSet(variableNames.get(i)); + if(ds != null && ds.times != null) { + result[i] = new double[ds.times.length]; + for(int j = 0; j < ds.times.length; j++) { + result[i][j] = ds.times[j]; + } + break; // Show the first result found. (i.e. do not show history datasets) + } + } + if(result[i] == null) + result[i] = new double[0]; + } + return result; + } + + @Override + public void setIndexedValue(WriteGraph graph, Object value) + throws DatabaseException { + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/ValueIndexVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/ValueIndexVariable.java new file mode 100644 index 00000000..9834ff5d --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/ValueIndexVariable.java @@ -0,0 +1,109 @@ +package org.simantics.sysdyn.adapter; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.fmu.FMUControlJNI; +import org.simantics.fmu.FMUJNIException; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.manager.SysdynGameExperiment; +import org.simantics.sysdyn.manager.SysdynResult; + +public class ValueIndexVariable extends IndexVariable { + + public ValueIndexVariable(ReadGraph graph, Variable parent, String indexes) + throws DatabaseException { + super(graph, parent, indexes); + } + + @Override + public double[] getValue() { + if(experiment == null) + return new double[0]; + + Collection results = experiment.getActiveResults(); + ArrayList variableNames = getVariableNamesWithIndexNumbers(); + + double[] result = new double[variableNames.size()]; + for(int i = 0; i < variableNames.size(); i++) { + for(SysdynResult r : results) { + if(experiment instanceof SysdynGameExperiment) { + Double d = ((SysdynGameExperiment)experiment).getCurrentValue(variableNames.get(i)); + result[i] = d != null ? d : 0; + } else { + SysdynDataSet ds = r.getDataSet(variableNames.get(i)); + if(ds != null && ds.values != null && ds.values.length > 0) { + result[i] = ds.values[ds.values.length-1]; + } else { + result[i] = 0; + } + } + } + } + return result; + } + + @Override + public void setIndexedValue(WriteGraph graph, Object value) + throws DatabaseException { + Variable var = parent.getParent(graph); + Resource resource = var.getRepresents(graph); + + if(!(value instanceof double[]) || resource == null) + return; + + double[] values = (double[]) value; + + FMUControlJNI control = null; + if(experiment instanceof SysdynGameExperiment) { // Support only game experiments for now.. + + SysdynGameExperiment exp = (SysdynGameExperiment)experiment; + ExperimentState state = exp.getSysdynExperimentState(); + // Set value to control only if the simulation is running or stopped, not before initialization + if(!(ExperimentState.RUNNING.equals(state) || ExperimentState.STOPPED.equals(state))) + return; + + control = ((SysdynGameExperiment)this.experiment).getFMUControl(); + if(control == null) + return; + + + + ArrayList variableNames = getVariableNamesWithIndexNumbers(); + for(int i = 0; i < variableNames.size() && i < values.length; i++) { + if(values[i] == Double.NaN) + continue; + + try { + String name = variableNames.get(i); + control.setRealValue(name, values[i]); + + // Set value for all referred variables in modules + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource dependency : graph.getObjects(resource, sr.Variable_isTailOf)) { + Resource head = graph.getPossibleObject(dependency, sr.Variable_HasHead); + Resource ref = graph.getPossibleObject(dependency, sr.Dependency_refersTo); + if(ref != null && head != null) { + String module = ""; + if(name.indexOf(".") > 0) + module = name.substring(0, name.lastIndexOf(".") + 1); + String refName = module + NameUtils.getSafeName(graph, head) + "." + NameUtils.getSafeName(graph, ref); + control.setRealValue(refName, values[i]); + } + } + } catch (FMUJNIException e) { + } + } + exp.updateSubscriptions(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/ValuesIndexVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/ValuesIndexVariable.java new file mode 100644 index 00000000..17f31520 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/ValuesIndexVariable.java @@ -0,0 +1,62 @@ +package org.simantics.sysdyn.adapter; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.manager.SysdynGameExperiment; +import org.simantics.sysdyn.manager.SysdynResult; + +public class ValuesIndexVariable extends IndexVariable { + + public ValuesIndexVariable(ReadGraph graph, Variable parent, String indexes) + throws DatabaseException { + super(graph, parent, indexes); + } + + @Override + public double[][] getValue() { + ArrayList variableNames = getVariableNamesWithIndexNumbers(); + double[][] result = new double[variableNames.size()][]; + + if (experiment != null) { + Collection results = experiment.getActiveResults(); + for(int i = 0; i < variableNames.size(); i++) { + for(SysdynResult r : results) { + SysdynDataSet ds = r.getDataSet(variableNames.get(i)); + if(ds != null && ds.values != null) { + result[i] = new double[ds.values.length]; + for(int j = 0; j < ds.values.length; j++) { + result[i][j] = ds.values[j]; + } + + /* + * If this is the actual simulation result and experiment is game experiment, + * get the last value from experiment. It might be different from the result + * file, if it has been modified in current time step + */ + if(experiment instanceof SysdynGameExperiment && ds.result == null) { + double d = ((SysdynGameExperiment)experiment).getCurrentValue(variableNames.get(i)); + result[i][ds.values.length - 1] = d; + } + break; // Show the first result found. (i.e. do not show history datasets) + } + + if(result[i] == null) + result[i] = new double[0]; + } + } + } + return result; + } + + @Override + public void setIndexedValue(WriteGraph graph, Object value) + throws DatabaseException { + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableRVIUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableRVIUtils.java new file mode 100644 index 00000000..0f24cc58 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableRVIUtils.java @@ -0,0 +1,335 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.adapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynDataSet; + +/** + * Utils for finding all active rvis for a single variable. A variable can have multiple + * rvis, if it is an array variable. Active rvis can be limited using a boolean value sr.ShowEnumerationIndexInCharts + * + * Example rvis for a variable with two enumerations (/ModuleInstance1/ModuleInstance2/Variable[Enumeration, Enumeration2]): + * + * /ModuleInstance1/ModuleInstance2/Variable[index1, index1] + * /ModuleInstance1/ModuleInstance2/Variable[index1, index2] + * /ModuleInstance1/ModuleInstance2/Variable[index2, index1] + * /ModuleInstance1/ModuleInstance2/Variable[index2, index2] + * + * + * + * @author Teemu Lempinen + * + */ +public class VariableRVIUtils { + + /** + * Recursive function for finding number format and label for the set of rvis. (rvis.put("Variable[1]", "Variable[index1]"); + * At the end of the recursive calls, rvis contains all possible combinations of enumeration indexes that are + * set to be shown in charts + * + * @param g ReadGraph + * @param rvi RVI of the variable + * @param rvis RVI map containing the full rvi with enumerations. Key contains numerical + * value of the enumeration and value contains the name of the enumeration (e.g. ["Variable[1]", "Variable[index1]"]) + * @param arrayIndexes ArrayIndex resources, Enumerations. + * @throws DatabaseException + */ + private static void traverseIndexes(ReadGraph g, String rvi, HashMap rvis, List arrayIndexes) throws DatabaseException { + traverseIndexes(g, rvi, rvis, arrayIndexes, 0, "", ""); + } + + /** + * Recursive function for finding number format and label for the set of rvis. (rvis.put("Variable[1]", "Variable[index1]"); + * At the end of the recursive calls, rvis contains all possible combinations of enumeration indexes that are + * set to be shown in charts + * + * @param g ReadGraph + * @param rvi RVI of the variable + * @param rvis RVI map containing the full rvi with enumerations. Key contains numerical + * @param arrayIndexes ArrayIndex resources, Enumerations. + * @param currentEnumeration Currently evaluated enumeration index (in arrayIndexes list) + * @param indexesSoFar String representation of the indexes so far in numerical format + * @param indexNamesSoFar String representation of the indexes so far in name format + * @throws DatabaseException + */ + private static void traverseIndexes(ReadGraph g, String rvi, HashMap rvis, List arrayIndexes, int currentIndex, String indexesSoFar, String indexNamesSoFar) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(g); + // Enumeration indexes of the current enumeration (e.g. the first EnumIndexes in Var[EnumIndexes, EnumIndexes, EnumIndexes]) + Resource enumerationIndexes = g.getPossibleObject(arrayIndexes.get(currentIndex), sr.Enumeration_enumerationIndexList); + if(enumerationIndexes == null) + return; + List indexes = ListUtils.toList(g, enumerationIndexes); + for(int i = 0; i < indexes.size(); i++) { + Boolean b = g.getPossibleRelatedValue(indexes.get(i), sr.EnumerationIndex_showEnumerationIndexInCharts, Bindings.BOOLEAN); + // If this index is not wanted to be shown in charts, the recursion does not go any further and rvis.put() is not called for this enumeration + if(Boolean.TRUE.equals(b)) { + // Get the name of the index + String name = g.getRelatedValue(indexes.get(i), Layer0.getInstance(g).HasName); + if(currentIndex < arrayIndexes.size() - 1) + // If there are still more EnumIndexes, recursively call the function and add current index to indexesSoFar and indexNamesSoFar + traverseIndexes(g, rvi, rvis, arrayIndexes, currentIndex + 1, + indexesSoFar + (i + 1) +",", indexNamesSoFar + (name) +","); + else { + // The last enumeration. Add [rvi[1, 1, 1] = rvi[index1, index1, index1]}and so on to the rvis map + rvis.put( + rvi + "[" + indexesSoFar + (i + 1) + "]", + rvi + "[" + indexNamesSoFar + (name) + "]"); + } + } + } + } + + /** + * Resolves and replaces all overridden enumerations in enumerations -list + * + * @param graph ReadGraph + * @param variable Selected variable + * @param enumerations List of array indexes of the variable + * @return + */ + private static List resolveActiveArrayIndexes(ReadGraph graph, Variable variable, List enumerations) { + try { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + String uri = variable.getURI(graph); + uri = uri.substring(0, uri.lastIndexOf("/")); + // The parent configuration or module + Variable v = Variables.getPossibleVariable(graph, uri); + if(v != null) { + Resource module = v.getRepresents(graph); + if(module != null && graph.isInheritedFrom(graph.getSingleObject(module, l0.InstanceOf), sr.Module)) { + // If the variable is located in a module, it might have overridden (redeclared) enumerations + boolean somethingIsReplaced = false; + // Find all redeclarations + for(Resource redeclaration : graph.syncRequest(new ObjectsWithType(module, sr.Module_redeclaration, sr.Redeclaration))) { + Resource replaced = graph.getSingleObject(redeclaration, sr.Redeclaration_replacedEnumeration); + while(enumerations.contains(replaced)) { + // Replace the redelcared enumeration in enumerations -list with the replacing enumeration + enumerations.add(enumerations.indexOf(replaced), graph.getSingleObject(redeclaration, sr.Redeclaration_replacingEnumeration)); + enumerations.remove(replaced); + somethingIsReplaced = true; + } + } + + if(somethingIsReplaced) { + // If something was replaced, do the same again for the parent configuration. The + // enumerations may be replaced throughout the whole model hierarchy + resolveActiveArrayIndexes(graph, v, enumerations); + } + } + } + } catch (DatabaseException e) { + e.printStackTrace(); + + } + return enumerations; + } + + + /** + * Returns rvis in a map in format /ModuleInstance/Variable[1] = /ModuleInstance/Variable[index1] + * @param graph ReadGraph + * @param variable Variable for the rvis + * @return rvis in a map. Keys are numerical formatted array indexes and values are textual. + * @throws DatabaseException + */ + public static HashMap getActiveRVIs(ReadGraph graph, Variable variable) throws DatabaseException { + HashMap rvis = new LinkedHashMap(); + + SysdynResource sr = SysdynResource.getInstance(graph); + + String rvi = Variables.getRVI(graph, variable); + + Resource r = variable.getRepresents(graph); + + Resource arrayIndexes = graph.getPossibleObject(r, sr.Variable_arrayIndexesList); + if(arrayIndexes == null) { + // If variable is single-dimensional, use the same rvi + rvis.put(rvi, rvi); + } else { + // If variable is multidimensional, get all indexes that are active and add them to rvis-map + List arrayIndexList = ListUtils.toList(graph, arrayIndexes); + resolveActiveArrayIndexes(graph, variable, arrayIndexList); + + if(arrayIndexList.size() > 0) + traverseIndexes(graph, rvi, rvis, arrayIndexList); + else + rvis.put(rvi, rvi); + } + + return rvis; + } + + + /** + * Filters a list of datasets of a single variable with a given filter. Filter should contain + * as many entries as the variable has enumerations. If the variable is Var[Enum1, Enum2, Enum3] + * the filter length should be 3. + * + * Allowed filter entries are All, Sum and a name of an index. + * + * Example filtering for variable Var[Enum1, Enum2, Enum3] where all enumerations have indexes {1, 2} + * + * filter: {All, Sum, 1} + * + * Filters are applied from back to front + * + * 1 1 1 + * 1 1 2 + * 1 2 1 1 1 1 + * 1 2 2 => 1 2 1 => 1 SUM(1 1, 2 1) + * 2 1 1 2 1 1 2 SUM(1 1, 2 1) + * 2 1 2 2 2 1 + * 2 2 1 + * 2 2 2 + * + * @param datasets List of SysdynDatasets for a single multidimensional variable + * @param filter filter for the datasets + * @return filtered list of SysdynDatasets + */ + public static ArrayList getDataset(ArrayList datasets, String[] filter) { + // If all filters are "All", no filtering is required. + boolean doFiltering = false; + for(String f : filter) { + if(!f.equalsIgnoreCase("All")) { + // One of the filters is not All -> do filtering + doFiltering = true; + break; + } + } + + if(doFiltering == false) + return datasets; + + // Start filtering with the complete set of datasets + ArrayList result = datasets; + + // Go through the filter from end to start + for(int i = filter.length - 1; i >= 0; i--) { + // Get the current filter + String currentFilter = filter[i].trim(); + + ArrayList tempResult = new ArrayList(); + HashMap sums = new HashMap(); + for(SysdynDataSet dataset : result) { + String tempIndexes = dataset.name.substring(dataset.name.indexOf('[') + 1, dataset.name.indexOf(']')); + String[] indexes = tempIndexes.split(","); + if(currentFilter.equals("All")) { + /* + * If the filter is "All", all datasets + * are kept for the next filtering + */ + tempResult.add(dataset); + } else if(currentFilter.equals(indexes[i].trim())) { + /* + * If the filter equals the index of the dataset + * at the same location, the dataset is kept for the next filtering + * + * e.g. + * dataset = Var[index3, index1, index2] + * filter = {All, index1, ALL} + * i = 1 (from 0 to 2) + * + * dataset's index and filter match at location 1 (the middle index) + */ + tempResult.add(dataset); + } else if(currentFilter.equals("Sum")) { + /* + * Whenever Sum is used as the filter, all datasets having the + * same indexes before the sum filter location are summed. + * + * e.g. + * filter = {1, 1, SUM} + * 1, 1, 1 + * 1, 1, 2 => 1, 1, SUM(1, 1, 1; 1, 1, 2) + * 1, 2, 1 1, 2, SUM(1, 2, 1; 1, 2, 2) + * 1, 2, 2 + */ + + // Find the preceding range (e.g. index1index2index2) + String rangeBefore = ""; + for(int j = 0; j < i; j++) + rangeBefore += indexes[j].trim(); + + // Find if there are any datasets for that preceding range in sums + SysdynDataSet sum = sums.get(rangeBefore); + if(sum != null) { + // A sum dataset was found. Add values from this dataset to the sum dataset + for(int j = 0; j < sum.values.length; j++) + sum.values[j] = sum.values[j] + dataset.values[j]; + } else { + // The first occurence of this preceding range, create a new dataset for the sum + + // Copy times and values + double[] times = new double[dataset.times.length]; + for(int j = 0; j < dataset.times.length; j++) + times[j] = dataset.times[j]; + double[] values = new double[dataset.values.length]; + for(int j = 0; j < dataset.values.length; j++) + values[j] = dataset.values[j]; + + // Create the dataset and add it to both tempResult and sums map + SysdynDataSet newDataset = new SysdynDataSet(dataset.name, dataset.result, times, values); + tempResult.add(newDataset); + sums.put(rangeBefore, newDataset); + + // Modify the name of the dataset by adding "Sum" to the current index location. + String name = newDataset.name.substring(0, newDataset.name.indexOf('[') + 1); + for(int j = 0; j < indexes.length; j++) { + if(j < i) + // Indexes before "Sum" stay the same + name += indexes[j].trim(); + else if(j >= i) + // Current "Sum" index and indexes after "Sum" are copied from filter + name += filter[j].trim(); + + if(j < indexes.length - 1) + name += ", "; + } + name += "]"; + + // Replace the sum dataset's name + newDataset.name = name; + } + + } else { + // Discard the series + } + } + + /* + * Replace result list with the filtered results and move on to next + * filter index or return the list + */ + result.clear(); + for(SysdynDataSet dataset : tempResult) + result.add(dataset); + } + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableValueSubscription.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableValueSubscription.java new file mode 100644 index 00000000..716fd588 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableValueSubscription.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.adapter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.ExternalRead; +import org.simantics.db.service.QueryControl; +import org.simantics.utils.datastructures.Callback; + +public class VariableValueSubscription { + + public static final long SUBSCRIPTION_COLLECTION_INTERVAL = 2000L; + + protected ExternalRead request; + protected IndexVariable variable; + protected Listener listener; + + /** + * To protect against invoking listener.exception multiple times which is + * forbidden. + */ + protected AtomicBoolean excepted = new AtomicBoolean(false); + + public VariableValueSubscription(ExternalRead request, IndexVariable variable, Listener listener) { + this.request = request; + this.variable = variable; + this.listener = listener; + } + + public ExternalRead getRequest() { + return request; + } + + public void update() { + try { + T value = variable.getValue(); + fireValue(value); + } catch (Throwable e) { + fireException(e); + } + } + + void fireValue(T value) { + if (listener != null) + listener.execute(value); + } + + void fireException(Throwable t) { + if (listener != null && excepted.compareAndSet(false, true)) + listener.exception(t); + else + // Can't invoke listener.exception multiple times, but logging + // further exceptions anyway. + Logger.defaultLogError(t); + } + + public void setListener(Listener listener) { + this.listener = listener; + } + + /** + * This makes sure that subscriptions regarding performed DB external reads + * are abolished from DB client caches when no longer needed. + * + * @param session + * @param subscriptions + */ + @SuppressWarnings("rawtypes") + public static void collectSubscriptions(Session session, final VariableValueSubscription[] subscriptions, final ExternalRead... extraReads) { + if (subscriptions.length == 0 && extraReads.length == 0) + return; + + session.asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Collection> requests = new ArrayList>(subscriptions.length + extraReads.length); + for (VariableValueSubscription subscription : subscriptions) + requests.add(subscription.getRequest()); + for (ExternalRead read : extraReads) + requests.add(read); + graph.getService(QueryControl.class).gc(graph, requests); + } + }, new Callback() { + @Override + public void run(DatabaseException e) { + if (e != null) + e.printStackTrace(); + } + }); + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/IDistribution.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/IDistribution.java new file mode 100644 index 00000000..a0949854 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/IDistribution.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.adapter.distribution; + +public interface IDistribution { + + /** + * Map a probability to the random variable. + * When random numbers are used to generate the Monte Carlo simulation parameters, the probability + * is itself selected randomly (between (0,1); at the domain endpoints the value is undefined). + * + * @param probability + * @return Inverse cumulative distribution function at probability, i.e. the random variable at the + * point where the cumulative distribution function yields probability. + */ + public double inverseCDF(double probability); +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/Interval.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/Interval.java new file mode 100644 index 00000000..39fd8760 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/Interval.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.adapter.distribution; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; + +public class Interval implements IDistribution { + + private double min = 0; + private double max = 10; + private double intervalLength = 1; + private int numberOfValues = 10; + private int index = 0; + + public Interval(ReadGraph graph, Resource distribution) { + + try { + SysdynResource SR = SysdynResource.getInstance(graph); + + Double minValue = graph.getPossibleRelatedValue(distribution, SR.Interval_minValue, Bindings.DOUBLE); + if(minValue != null) + this.min = minValue; + + Double maxValue = graph.getPossibleRelatedValue(distribution, SR.Interval_maxValue, Bindings.DOUBLE); + if(maxValue != null) + this.max = maxValue; + + Resource parameter = graph.getPossibleObject(distribution, SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse); + + Resource experiment = graph.getPossibleObject(parameter, Layer0.getInstance(graph).PartOf); + + Integer numberOfValues = graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_numberOfValues, Bindings.INTEGER); + if(numberOfValues != null) + this.numberOfValues = numberOfValues; + + intervalLength = (maxValue - minValue) / (this.numberOfValues - 1); + + } catch (DatabaseException e) { + + } + } + + public double getMin() { + return min; + } + + public double getMax() { + return max; + } + + public int getNumberOfValues() { + return numberOfValues; + } + + public double getIntervalLength() { + return intervalLength; + } + + @Override + public double inverseCDF(double probability) { + // This is a bit awkward... + double value = min + (intervalLength * index); + index++; + if (index >= numberOfValues) + index = 0; + return value; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/NormalDistribution.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/NormalDistribution.java new file mode 100644 index 00000000..7887a62a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/NormalDistribution.java @@ -0,0 +1,404 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.adapter.distribution; + + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; + +public class NormalDistribution implements IDistribution { + + private Double min = null; + private Double max = null; + private double minProbability = 0; + private double maxProbability = 1; + private double mean; + private double stdDeviation; + + public NormalDistribution(ReadGraph graph, Resource distribution) { + + try { + + SysdynResource SR = SysdynResource.getInstance(graph); + + min = graph.getPossibleRelatedValue(distribution, SR.NormalDistribution_minValue, Bindings.DOUBLE); + max = graph.getPossibleRelatedValue(distribution, SR.NormalDistribution_maxValue, Bindings.DOUBLE); + stdDeviation = graph.getPossibleRelatedValue(distribution, SR.NormalDistribution_stdDeviation, Bindings.DOUBLE); + mean = graph.getPossibleRelatedValue(distribution, SR.NormalDistribution_mean, Bindings.DOUBLE); + + // Determine the max and min probabilities. + if (min != null) + minProbability = cdf(min, mean, stdDeviation, false); + if (max != null) + maxProbability = cdf(max, mean, stdDeviation, false); + + } catch (DatabaseException e) { + + } + } + + public double getMin() { + return min; + } + + public double getMax() { + return max; + } + + @Override + public double inverseCDF(double probability) { + // Map probability to [min,max] + double mappedProbability = minProbability + (maxProbability - minProbability) * probability; + // Calculate the inverse CDF + return quantile(mappedProbability, mean, stdDeviation); + } + + //The following is from BEAST-MCMC (https://code.google.com/p/beast-mcmc/) + + /* + * NormalDistribution.java + * + * Copyright (c) 2002-2011 Alexei Drummond, Andrew Rambaut and Marc Suchard + * + * This file is part of BEAST. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership and licensing. + * + * BEAST is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * BEAST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BEAST; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + + /** + * quantiles (=inverse cumulative density function) + * + * @param z argument + * @param m mean + * @param sd standard deviation + * @return icdf at z + */ + public static double quantile(double z, double m, double sd) { + return m + Math.sqrt(2.0) * sd * inverseErf(2.0 * z - 1.0); + } + + /** A more accurate and faster implementation of the cdf (taken from function pnorm in the R statistical language) + * This implementation has discrepancies depending on the programming language and system architecture + * In Java, returned values become zero once z reaches -37.5193 exactly on the machine tested + * In the other implementation, the returned value 0 at about z = -8 + * In C, this 0 value is reached approximately z = -37.51938 + * + * Will later need to be optimised for BEAST + * + * @param x argument + * @param mu mean + * @param sigma standard deviation + * @param log_p is p logged + * @return cdf at x + */ + public static double cdf(double x, double mu, double sigma, boolean log_p) { + boolean i_tail=false; + double p, cp = Double.NaN; + + if(Double.isNaN(x) || Double.isNaN(mu) || Double.isNaN(sigma)) { + return Double.NaN; + } + if(Double.isInfinite(x) && mu == x) { /* x-mu is NaN */ + return Double.NaN; + } + if (sigma <= 0) { + if(sigma < 0) { + return Double.NaN; + } + return (x < mu) ? 0.0 : 1.0; + } + p = (x - mu) / sigma; + if(Double.isInfinite(p)) { + return (x < mu) ? 0.0 : 1.0; + } + x = p; + if(Double.isNaN(x)) { + return Double.NaN; + } + + double xden, xnum, temp, del, eps, xsq, y; + int i; + boolean lower, upper; + eps = DBL_EPSILON * 0.5; + lower = !i_tail; + upper = i_tail; + + y = Math.abs(x); + if (y <= 0.67448975) { /* Normal.quantile(3/4, 1, 0) = 0.67448975 */ + if (y > eps) { + xsq = x * x; + xnum = a[4] * xsq; + xden = xsq; + for (i = 0; i < 3; i++) { + xnum = (xnum + a[i]) * xsq; + xden = (xden + b[i]) * xsq; + } + } + else { + xnum = xden = 0.0; + } + temp = x * (xnum + a[3]) / (xden + b[3]); + if(lower) { + p = 0.5 + temp; + } + if(upper) { + cp = 0.5 - temp; + } + if(log_p) { + if(lower) { + p = Math.log(p); + } + if(upper) { + cp = Math.log(cp); + } + } + } + + + else if (y <= M_SQRT_32) { + /* Evaluate pnorm for 0.67448975 = Normal.quantile(3/4, 1, 0) < |x| <= sqrt(32) ~= 5.657 */ + + xnum = c[8] * y; + xden = y; + for (i = 0; i < 7; i++) { + xnum = (xnum + c[i]) * y; + xden = (xden + d[i]) * y; + } + temp = (xnum + c[7]) / (xden + d[7]); + + //do_del(y); + //swap_tail; + //#define do_del(X) \ + xsq = ((int) (y * CUTOFF)) * 1.0 / CUTOFF; + del = (y - xsq) * (y + xsq); + if(log_p) { + p = (-xsq * xsq * 0.5) + (-del * 0.5) + Math.log(temp); + if((lower && x > 0.0) || (upper && x <= 0.0)) { + cp = Math.log(1.0-Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp); + } + } + else { + p = Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp; + cp = 1.0 - p; + } + //#define swap_tail \ + if (x > 0.0) { + temp = p; + if(lower) { + p = cp; + } + cp = temp; + } + } + /* else |x| > sqrt(32) = 5.657 : + * the next two case differentiations were really for lower=T, log=F + * Particularly *not* for log_p ! + * Cody had (-37.5193 < x && x < 8.2924) ; R originally had y < 50 + * Note that we do want symmetry(0), lower/upper -> hence use y + */ + else if(log_p || (lower && -37.5193 < x && x < 8.2924) + || (upper && -8.2924 < x && x < 37.5193)) { + + /* Evaluate pnorm for x in (-37.5, -5.657) union (5.657, 37.5) */ + xsq = 1.0 / (x * x); + xnum = p_[5] * xsq; + xden = xsq; + for (i = 0; i < 4; i++) { + xnum = (xnum + p_[i]) * xsq; + xden = (xden + q[i]) * xsq; + } + temp = xsq * (xnum + p_[4]) / (xden + q[4]); + temp = (M_1_SQRT_2PI - temp) / y; + + //do_del(x); + xsq = ((int) (x * CUTOFF)) * 1.0 / CUTOFF; + del = (x - xsq) * (x + xsq); + if(log_p) { + p = (-xsq * xsq * 0.5) + (-del * 0.5) + Math.log(temp); + if((lower && x > 0.0) || (upper && x <= 0.0)) { + cp = Math.log(1.0-Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp); + } + } + else { + p = Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp; + cp = 1.0 - p; + } + //swap_tail; + if (x > 0.0) { + temp = p; + if(lower) { + p = cp; + } + cp = temp; + } + } + else { /* no log_p , large x such that probs are 0 or 1 */ + if(x > 0) { + p = 1.0; + cp = 0.0; + } + else { + p = 0.0; + cp = 1.0; + } + } + return p; + + } + + // Private + + protected double m, sd; + + private static final double[] a = { + 2.2352520354606839287, + 161.02823106855587881, + 1067.6894854603709582, + 18154.981253343561249, + 0.065682337918207449113 + }; + private static final double[] b = { + 47.20258190468824187, + 976.09855173777669322, + 10260.932208618978205, + 45507.789335026729956 + }; + private static final double[] c = { + 0.39894151208813466764, + 8.8831497943883759412, + 93.506656132177855979, + 597.27027639480026226, + 2494.5375852903726711, + 6848.1904505362823326, + 11602.651437647350124, + 9842.7148383839780218, + 1.0765576773720192317e-8 + }; + private static final double[] d = { + 22.266688044328115691, + 235.38790178262499861, + 1519.377599407554805, + 6485.558298266760755, + 18615.571640885098091, + 34900.952721145977266, + 38912.003286093271411, + 19685.429676859990727 + }; + private static final double[] p_ = { + 0.21589853405795699, + 0.1274011611602473639, + 0.022235277870649807, + 0.001421619193227893466, + 2.9112874951168792e-5, + 0.02307344176494017303 + }; + private static final double[] q = { + 1.28426009614491121, + 0.468238212480865118, + 0.0659881378689285515, + 0.00378239633202758244, + 7.29751555083966205e-5 + }; + + private static final int CUTOFF = 16; /* Cutoff allowing exact "*" and "/" */ + + private static final double M_SQRT_32 = 5.656854249492380195206754896838; /* The square root of 32 */ + private static final double M_1_SQRT_2PI = 0.398942280401432677939946059934; + private static final double DBL_EPSILON = 2.2204460492503131e-016; + + /* + * ErrorFunction.java + * + * Copyright (C) 2002-2006 Alexei Drummond and Andrew Rambaut + * + * This file is part of BEAST. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership and licensing. + * + * BEAST is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * BEAST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BEAST; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + + /** + * inverse error function + * + * @param z argument + * + * @return function value + */ + public static double inverseErf(double z) + { + return pointNormal(0.5*z+0.5)/Math.sqrt(2.0); + } + + // Private + + // Returns z so that Prob{x primes; + + private void getPrimes() { + int newPrime = 2; + while (primes.size() < dimension) { + boolean isPrime = true; + for (int p : primes) { + if (newPrime % p == 0) { + ++newPrime; + isPrime = false; + break; + } + } + if (isPrime) { + primes.add(newPrime); + } + } + } + + public HaltonSequenceGenerator(ReadGraph graph, Resource method) { + + try { + SysdynResource SR = SysdynResource.getInstance(graph); + Resource experiment = graph.getPossibleObject(method, SR.SensitivityAnalysisExperiment_method_Inverse); + Resource parameterListResource = graph.getPossibleObject(experiment, SR.SensitivityAnalysisExperiment_parameterList); + dimension = ListUtils.getListNodes(graph, parameterListResource).size(); + + primes = new ArrayList(); + getPrimes(); + + initialize(); + } catch (DatabaseException e) { + + } + } + + public static double getHalton(int index, int base) { + ++index; // Map indexes to start from 1; + double result = 0; + double f = 1.0 / base; + while (index > 0) { + result = result + f * (index % base); + index = index / base; + f = f / base; + } + return result; + } + + public List next() { + ArrayList retval = new ArrayList(); + for (int i = 0; i < dimension; ++i) { + int base = primes.get(i); + double halton = getHalton(index, base); + retval.add(halton); + } + ++index; + return retval; + } + + public void initialize() { + index = 0; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/generator/IGenerator.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/generator/IGenerator.java new file mode 100644 index 00000000..59792648 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/generator/IGenerator.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.adapter.generator; + +import java.util.List; + +/** + * Interface for parameter value generators. + * + * @author Tuomas Miettinen + * + */ +public interface IGenerator { + + /** + * Get the next parameter combination. + * @return list of generated parameter values + */ + public List next(); + + /** + * Initialize the generator. + */ + public void initialize(); +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/generator/RandomGenerator.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/generator/RandomGenerator.java new file mode 100644 index 00000000..e4a920fe --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/generator/RandomGenerator.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.adapter.generator; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; + +/** + * Random generator that creates ArrayLists of random Doubles between 0 and 1. + * + * @author Tuomas Miettinen + */ + +public class RandomGenerator implements IGenerator { + + private int seed; + private int dimension; + private Random random; + + public RandomGenerator(ReadGraph graph, Resource method) { + + try { + SysdynResource SR = SysdynResource.getInstance(graph); + Resource experiment = graph.getPossibleObject(method, SR.SensitivityAnalysisExperiment_method_Inverse); + seed = graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_randomSeed, Bindings.INTEGER); + + Resource parameterListResource = graph.getPossibleObject(experiment, SR.SensitivityAnalysisExperiment_parameterList); + dimension = ListUtils.getListNodes(graph, parameterListResource).size(); + + initialize(); + } catch (DatabaseException e) { + + } + } + + public List next() { + ArrayList randoms = new ArrayList(); + for (int i = 0; i < dimension; ++i) + randoms.add(random.nextDouble()); + return randoms; + } + + public void initialize() { + random = new Random(this.seed); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/AdjacencyList.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/AdjacencyList.java new file mode 100644 index 00000000..47c784c2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/AdjacencyList.java @@ -0,0 +1,46 @@ +package org.simantics.sysdyn.elementaryCycles; + +import java.util.Vector; + + +/** + * Calculates the adjacency-list for a given adjacency-matrix. + * + * + * @author Frank Meyer, web@normalisiert.de + * @version 1.0, 26.08.2006 + * + */ +public class AdjacencyList { + /** + * Calculates a adjacency-list for a given array of an adjacency-matrix. + * + * @param adjacencyMatrix array with the adjacency-matrix that represents + * the graph + * @return int[][]-array of the adjacency-list of given nodes. The first + * dimension in the array represents the same node as in the given + * adjacency, the second dimension represents the indicies of those nodes, + * that are direct successornodes of the node. + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static int[][] getAdjacencyList(boolean[][] adjacencyMatrix) { + int[][] list = new int[adjacencyMatrix.length][]; + + for (int i = 0; i < adjacencyMatrix.length; i++) { + Vector v = new Vector(); + for (int j = 0; j < adjacencyMatrix[i].length; j++) { + if (adjacencyMatrix[i][j]) { + v.add(new Integer(j)); + } + } + + list[i] = new int[v.size()]; + for (int j = 0; j < v.size(); j++) { + Integer in = (Integer) v.get(j); + list[i][j] = in.intValue(); + } + } + + return list; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/ElementaryCyclesSearch.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/ElementaryCyclesSearch.java new file mode 100644 index 00000000..641682f4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/ElementaryCyclesSearch.java @@ -0,0 +1,167 @@ +package org.simantics.sysdyn.elementaryCycles; + +import java.util.List; +import java.util.Vector; + + + +/** + * Searchs all elementary cycles in a given directed graph. The implementation + * is independent from the concrete objects that represent the graphnodes, it + * just needs an array of the objects representing the nodes the graph + * and an adjacency-matrix of type boolean, representing the edges of the + * graph. It then calculates based on the adjacency-matrix the elementary + * cycles and returns a list, which contains lists itself with the objects of the + * concrete graphnodes-implementation. Each of these lists represents an + * elementary cycle.

+ * + * The implementation uses the algorithm of Donald B. Johnson for the search of + * the elementary cycles. For a description of the algorithm see:
+ * Donald B. Johnson: Finding All the Elementary Circuits of a Directed Graph. + * SIAM Journal on Computing. Volumne 4, Nr. 1 (1975), pp. 77-84.

+ * + * The algorithm of Johnson is based on the search for strong connected + * components in a graph. For a description of this part see:
+ * Robert Tarjan: Depth-first search and linear graph algorithms. In: SIAM + * Journal on Computing. Volume 1, Nr. 2 (1972), pp. 146-160.
+ * + * @author Frank Meyer, web_at_normalisiert_dot_de + * @version 1.2, 22.03.2009 + * + */ +@SuppressWarnings("rawtypes") +public class ElementaryCyclesSearch { + /** List of cycles */ + private List cycles = null; + + /** Adjacency-list of graph */ + private int[][] adjList = null; + + /** Graphnodes */ + private Object[] graphNodes = null; + + /** Blocked nodes, used by the algorithm of Johnson */ + private boolean[] blocked = null; + + /** B-Lists, used by the algorithm of Johnson */ + private Vector[] B = null; + + /** Stack for nodes, used by the algorithm of Johnson */ + private Vector stack = null; + + /** + * Constructor. + * + * @param matrix adjacency-matrix of the graph + * @param graphNodes array of the graphnodes of the graph; this is used to + * build sets of the elementary cycles containing the objects of the original + * graph-representation + */ + public ElementaryCyclesSearch(boolean[][] matrix, Object[] graphNodes) { + this.graphNodes = graphNodes; + this.adjList = AdjacencyList.getAdjacencyList(matrix); + } + + /** + * Returns List::List::Object with the Lists of nodes of all elementary + * cycles in the graph. + * + * @return List::List::Object with the Lists of the elementary cycles. + */ + public List getElementaryCycles() { + this.cycles = new Vector(); + this.blocked = new boolean[this.adjList.length]; + this.B = new Vector[this.adjList.length]; + this.stack = new Vector(); + StrongConnectedComponents sccs = new StrongConnectedComponents(this.adjList); + int s = 0; + + while (true) { + SCCResult sccResult = sccs.getAdjacencyList(s); + if (sccResult != null && sccResult.getAdjList() != null) { + Vector[] scc = sccResult.getAdjList(); + s = sccResult.getLowestNodeId(); + for (int j = 0; j < scc.length; j++) { + if ((scc[j] != null) && (scc[j].size() > 0)) { + this.blocked[j] = false; + this.B[j] = new Vector(); + } + } + + this.findCycles(s, s, scc); + s++; + } else { + break; + } + } + + return this.cycles; + } + + /** + * Calculates the cycles containing a given node in a strongly connected + * component. The method calls itself recursivly. + * + * @param v + * @param s + * @param adjList adjacency-list with the subgraph of the strongly + * connected component s is part of. + * @return true, if cycle found; false otherwise + */ + @SuppressWarnings("unchecked") + private boolean findCycles(int v, int s, Vector[] adjList) { + boolean f = false; + this.stack.add(new Integer(v)); + this.blocked[v] = true; + + for (int i = 0; i < adjList[v].size(); i++) { + int w = ((Integer) adjList[v].get(i)).intValue(); + // found cycle + if (w == s) { + Vector cycle = new Vector(); + for (int j = 0; j < this.stack.size(); j++) { + int index = ((Integer) this.stack.get(j)).intValue(); + cycle.add(this.graphNodes[index]); + } + this.cycles.add(cycle); + f = true; + } else if (!this.blocked[w]) { + if (this.findCycles(w, s, adjList)) { + f = true; + } + } + } + + if (f) { + this.unblock(v); + } else { + for (int i = 0; i < adjList[v].size(); i++) { + int w = ((Integer) adjList[v].get(i)).intValue(); + if (!this.B[w].contains(new Integer(v))) { + this.B[w].add(new Integer(v)); + } + } + } + + this.stack.remove(new Integer(v)); + return f; + } + + /** + * Unblocks recursivly all blocked nodes, starting with a given node. + * + * @param node node to unblock + */ + private void unblock(int node) { + this.blocked[node] = false; + Vector Bnode = this.B[node]; + while (Bnode.size() > 0) { + Integer w = (Integer) Bnode.get(0); + Bnode.remove(0); + if (this.blocked[w.intValue()]) { + this.unblock(w.intValue()); + } + } + } +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/SCCResult.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/SCCResult.java new file mode 100644 index 00000000..c8787cd4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/SCCResult.java @@ -0,0 +1,34 @@ +package org.simantics.sysdyn.elementaryCycles; + +import java.util.HashSet; +import java.util.Set; +import java.util.Vector; + +@SuppressWarnings("rawtypes") +public class SCCResult { + private Set nodeIDsOfSCC = null; + private Vector[] adjList = null; + private int lowestNodeId = -1; + + @SuppressWarnings("unchecked") + public SCCResult(Vector[] adjList, int lowestNodeId) { + this.adjList = adjList; + this.lowestNodeId = lowestNodeId; + this.nodeIDsOfSCC = new HashSet(); + if (this.adjList != null) { + for (int i = this.lowestNodeId; i < this.adjList.length; i++) { + if (this.adjList[i].size() > 0) { + this.nodeIDsOfSCC.add(new Integer(i)); + } + } + } + } + + public Vector[] getAdjList() { + return adjList; + } + + public int getLowestNodeId() { + return lowestNodeId; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/StrongConnectedComponents.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/StrongConnectedComponents.java new file mode 100644 index 00000000..8c966d31 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/StrongConnectedComponents.java @@ -0,0 +1,280 @@ +package org.simantics.sysdyn.elementaryCycles; + + +import java.util.Vector; + +/** + * This is a helpclass for the search of all elementary cycles in a graph + * with the algorithm of Johnson. For this it searches for strong connected + * components, using the algorithm of Tarjan. The constructor gets an + * adjacency-list of a graph. Based on this graph, it gets a nodenumber s, + * for which it calculates the subgraph, containing all nodes + * {s, s + 1, ..., n}, where n is the highest nodenumber in the original + * graph (e.g. it builds a subgraph with all nodes with higher or same + * nodenumbers like the given node s). It returns the strong connected + * component of this subgraph which contains the lowest nodenumber of all + * nodes in the subgraph.

+ * + * For a description of the algorithm for calculating the strong connected + * components see:
+ * Robert Tarjan: Depth-first search and linear graph algorithms. In: SIAM + * Journal on Computing. Volume 1, Nr. 2 (1972), pp. 146-160.
+ * For a description of the algorithm for searching all elementary cycles in + * a directed graph see:
+ * Donald B. Johnson: Finding All the Elementary Circuits of a Directed Graph. + * SIAM Journal on Computing. Volumne 4, Nr. 1 (1975), pp. 77-84.

+ * + * @author Frank Meyer, web_at_normalisiert_dot_de + * @version 1.1, 22.03.2009 + * + */ +@SuppressWarnings({"rawtypes", "unchecked"}) +public class StrongConnectedComponents { + /** Adjacency-list of original graph */ + private int[][] adjListOriginal = null; + + /** Adjacency-list of currently viewed subgraph */ + private int[][] adjList = null; + + /** Helpattribute for finding scc's */ + private boolean[] visited = null; + + /** Helpattribute for finding scc's */ + private Vector stack = null; + + /** Helpattribute for finding scc's */ + private int[] lowlink = null; + + /** Helpattribute for finding scc's */ + private int[] number = null; + + /** Helpattribute for finding scc's */ + private int sccCounter = 0; + + /** Helpattribute for finding scc's */ + private Vector currentSCCs = null; + + /** + * Constructor. + * + * @param adjList adjacency-list of the graph + */ + public StrongConnectedComponents(int[][] adjList) { + this.adjListOriginal = adjList; + } + + /** + * This method returns the adjacency-structure of the strong connected + * component with the least vertex in a subgraph of the original graph + * induced by the nodes {s, s + 1, ..., n}, where s is a given node. Note + * that trivial strong connected components with just one node will not + * be returned. + * + * @param node node s + * @return SCCResult with adjacency-structure of the strong + * connected component; null, if no such component exists + */ + public SCCResult getAdjacencyList(int node) { + this.visited = new boolean[this.adjListOriginal.length]; + this.lowlink = new int[this.adjListOriginal.length]; + this.number = new int[this.adjListOriginal.length]; + this.visited = new boolean[this.adjListOriginal.length]; + this.stack = new Vector(); + this.currentSCCs = new Vector(); + + this.makeAdjListSubgraph(node); + + for (int i = node; i < this.adjListOriginal.length; i++) { + if (!this.visited[i]) { + this.getStrongConnectedComponents(i); + Vector nodes = this.getLowestIdComponent(); + if (nodes != null && !nodes.contains(new Integer(node)) && !nodes.contains(new Integer(node + 1))) { + return this.getAdjacencyList(node + 1); + } else { + Vector[] adjacencyList = this.getAdjList(nodes); + if (adjacencyList != null) { + for (int j = 0; j < this.adjListOriginal.length; j++) { + if (adjacencyList[j].size() > 0) { + return new SCCResult(adjacencyList, j); + } + } + } + } + } + } + + return null; + } + + /** + * Builds the adjacency-list for a subgraph containing just nodes + * >= a given index. + * + * @param node Node with lowest index in the subgraph + */ + private void makeAdjListSubgraph(int node) { + this.adjList = new int[this.adjListOriginal.length][0]; + + for (int i = node; i < this.adjList.length; i++) { + Vector successors = new Vector(); + for (int j = 0; j < this.adjListOriginal[i].length; j++) { + if (this.adjListOriginal[i][j] >= node) { + successors.add(new Integer(this.adjListOriginal[i][j])); + } + } + if (successors.size() > 0) { + this.adjList[i] = new int[successors.size()]; + for (int j = 0; j < successors.size(); j++) { + Integer succ = (Integer) successors.get(j); + this.adjList[i][j] = succ.intValue(); + } + } + } + } + + /** + * Calculates the strong connected component out of a set of scc's, that + * contains the node with the lowest index. + * + * @return Vector::Integer of the scc containing the lowest nodenumber + */ + private Vector getLowestIdComponent() { + int min = this.adjList.length; + Vector currScc = null; + + for (int i = 0; i < this.currentSCCs.size(); i++) { + Vector scc = (Vector) this.currentSCCs.get(i); + for (int j = 0; j < scc.size(); j++) { + Integer node = (Integer) scc.get(j); + if (node.intValue() < min) { + currScc = scc; + min = node.intValue(); + } + } + } + + return currScc; + } + + /** + * @return Vector[]::Integer representing the adjacency-structure of the + * strong connected component with least vertex in the currently viewed + * subgraph + */ + private Vector[] getAdjList(Vector nodes) { + Vector[] lowestIdAdjacencyList = null; + + if (nodes != null) { + lowestIdAdjacencyList = new Vector[this.adjList.length]; + for (int i = 0; i < lowestIdAdjacencyList.length; i++) { + lowestIdAdjacencyList[i] = new Vector(); + } + for (int i = 0; i < nodes.size(); i++) { + int node = ((Integer) nodes.get(i)).intValue(); + for (int j = 0; j < this.adjList[node].length; j++) { + int succ = this.adjList[node][j]; + if (nodes.contains(new Integer(succ))) { + lowestIdAdjacencyList[node].add(new Integer(succ)); + } + } + } + } + + return lowestIdAdjacencyList; + } + + /** + * Searchs for strong connected components reachable from a given node. + * + * @param root node to start from. + */ + private void getStrongConnectedComponents(int root) { + this.sccCounter++; + this.lowlink[root] = this.sccCounter; + this.number[root] = this.sccCounter; + this.visited[root] = true; + this.stack.add(new Integer(root)); + + for (int i = 0; i < this.adjList[root].length; i++) { + int w = this.adjList[root][i]; + if (!this.visited[w]) { + this.getStrongConnectedComponents(w); + this.lowlink[root] = Math.min(lowlink[root], lowlink[w]); + } else if (this.number[w] < this.number[root]) { + if (this.stack.contains(new Integer(w))) { + lowlink[root] = Math.min(this.lowlink[root], this.number[w]); + } + } + } + + // found scc + if ((lowlink[root] == number[root]) && (stack.size() > 0)) { + int next = -1; + Vector scc = new Vector(); + + do { + next = ((Integer) this.stack.get(stack.size() - 1)).intValue(); + this.stack.remove(stack.size() - 1); + scc.add(new Integer(next)); + } while (this.number[next] > this.number[root]); + + // simple scc's with just one node will not be added + if (scc.size() > 1) { + this.currentSCCs.add(scc); + } + } + } + + public static void main(String[] args) { + boolean[][] adjMatrix = new boolean[10][]; + + for (int i = 0; i < 10; i++) { + adjMatrix[i] = new boolean[10]; + } + + /*adjMatrix[0][1] = true; + adjMatrix[1][2] = true; + adjMatrix[2][0] = true; + adjMatrix[2][4] = true; + adjMatrix[1][3] = true; + adjMatrix[3][6] = true; + adjMatrix[6][5] = true; + adjMatrix[5][3] = true; + adjMatrix[6][7] = true; + adjMatrix[7][8] = true; + adjMatrix[7][9] = true; + adjMatrix[9][6] = true;*/ + + adjMatrix[0][1] = true; + adjMatrix[1][2] = true; + adjMatrix[2][0] = true; adjMatrix[2][6] = true; + adjMatrix[3][4] = true; + adjMatrix[4][5] = true; adjMatrix[4][6] = true; + adjMatrix[5][3] = true; + adjMatrix[6][7] = true; + adjMatrix[7][8] = true; + adjMatrix[8][6] = true; + + adjMatrix[6][1] = true; + + int[][] adjList = AdjacencyList.getAdjacencyList(adjMatrix); + StrongConnectedComponents scc = new StrongConnectedComponents(adjList); + for (int i = 0; i < adjList.length; i++) { + System.out.print("i: " + i + "\n"); + SCCResult r = scc.getAdjacencyList(i); + if (r != null) { + Vector[] al = scc.getAdjacencyList(i).getAdjList(); + for (int j = i; j < al.length; j++) { + if (al[j].size() > 0) { + System.out.print("j: " + j); + for (int k = 0; k < al[j].size(); k++) { + System.out.print(" _" + al[j].get(k).toString()); + } + System.out.print("\n"); + } + } + System.out.print("\n"); + } + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/TestCycles.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/TestCycles.java new file mode 100644 index 00000000..e846272e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/TestCycles.java @@ -0,0 +1,68 @@ +package org.simantics.sysdyn.elementaryCycles; + + +import java.util.List; + + +/** + * Testfile for elementary cycle search. + * + * @author Frank Meyer + * + */ +public class TestCycles { + + /** + * @param args + */ + @SuppressWarnings("rawtypes") + public static void main(String[] args) { + String nodes[] = new String[10]; + boolean adjMatrix[][] = new boolean[10][10]; + + for (int i = 0; i < 10; i++) { + nodes[i] = "Node " + i; + } + + adjMatrix[0][1] = true; + adjMatrix[1][2] = true; + adjMatrix[2][0] = true; + adjMatrix[2][4] = true; + adjMatrix[1][3] = true; + adjMatrix[3][6] = true; + adjMatrix[6][5] = true; + adjMatrix[5][3] = true; + adjMatrix[6][7] = true; + adjMatrix[7][8] = true; + adjMatrix[7][9] = true; + adjMatrix[9][6] = true; + /* + adjMatrix[0][1] = true; + adjMatrix[1][2] = true; + adjMatrix[2][0] = true; adjMatrix[2][6] = true; + adjMatrix[3][4] = true; + adjMatrix[4][5] = true; adjMatrix[4][6] = true; + adjMatrix[5][3] = true; + adjMatrix[6][7] = true; + adjMatrix[7][8] = true; + adjMatrix[8][6] = true; + + adjMatrix[6][1] = true; +*/ + ElementaryCyclesSearch ecs = new ElementaryCyclesSearch(adjMatrix, nodes); + List cycles = ecs.getElementaryCycles(); + for (int i = 0; i < cycles.size(); i++) { + List cycle = (List) cycles.get(i); + for (int j = 0; j < cycle.size(); j++) { + String node = (String) cycle.get(j); + if (j < cycle.size() - 1) { + System.out.print(node + " -> "); + } else { + System.out.print(node); + } + } + System.out.print("\n"); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/license.txt b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/license.txt new file mode 100644 index 00000000..0ed76f9c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/elementaryCycles/license.txt @@ -0,0 +1,11 @@ +(BSD-2 license) + +Copyright (c) 2012, Frank Meyer +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.java new file mode 100644 index 00000000..bcb3d09e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.java @@ -0,0 +1,1830 @@ +/* Generated By:JavaCC: Do not edit this line. ExpressionParser.java */ +package org.simantics.sysdyn.expressionParser; + +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; + +@SuppressWarnings({"unused", "serial"}) +public class ExpressionParser implements ExpressionParserConstants { + + public class ForRange { + public Token start; + public Token end; + } + + boolean forIndex = false; + Token firstToken; + + public Token getFirstToken() { + return firstToken; + } + + List forRanges = new ArrayList(); + + public List getForRanges() { + return forRanges; + } + + HashMap> references = new HashMap>(); + + public HashMap> getReferences() { + return references; + } + + HashMap>> ranges = new HashMap>>(); + + public HashMap>> getRanges() { + return ranges; + } + + List currentRange = null; + + HashMap> forIndices = new HashMap>(); + + public HashMap> getForIndices() { + return forIndices; + } + + HashMap> enumerationReferences = new HashMap>(); + + public HashMap> getEnumerationReferences() { + return enumerationReferences; + } + +/* + Collect EACH function call and all references that are inside the call brackets. + These are later used to exclude spread sheet references out of the normal functions. +*/ + String functionCall = null; + HashMap> functionCallReferences = new HashMap>(); + + public HashMap> getFunctionCallReferences() { + return functionCallReferences; + } + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + final public void expr() throws ParseException { + jj_input_stream.setTabSize(1); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case QIDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + firstToken = token; + simple_expression(); + jj_consume_token(0); + break; + case 31: + firstToken = token; + jj_consume_token(31); + expression(); + jj_consume_token(28); + expression(); + label_1: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[0] = jj_gen; + break label_1; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + expression(); + } + jj_consume_token(15); + expression(); + jj_consume_token(0); + break; + default: + jj_la1[1] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void expression() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case QIDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + simple_expression(); + break; + case 31: + jj_consume_token(31); + expression(); + jj_consume_token(28); + expression(); + label_2: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[2] = jj_gen; + break label_2; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + expression(); + } + jj_consume_token(15); + expression(); + break; + default: + jj_la1[3] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void simple_expression() throws ParseException { + logical_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 67: + jj_consume_token(67); + logical_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 67: + jj_consume_token(67); + logical_expression(); + break; + default: + jj_la1[4] = jj_gen; + ; + } + break; + default: + jj_la1[5] = jj_gen; + ; + } + } + + final public void logical_expression() throws ParseException { + logical_term(); + label_3: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 22: + ; + break; + default: + jj_la1[6] = jj_gen; + break label_3; + } + jj_consume_token(22); + logical_term(); + } + } + + final public void logical_term() throws ParseException { + logical_factor(); + label_4: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 9: + ; + break; + default: + jj_la1[7] = jj_gen; + break label_4; + } + jj_consume_token(9); + logical_factor(); + } + } + + final public void logical_factor() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 12: + jj_consume_token(12); + break; + default: + jj_la1[8] = jj_gen; + ; + } + relation(); + } + + final public void relation() throws ParseException { + arithmetic_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + rel_op(); + arithmetic_expression(); + break; + default: + jj_la1[9] = jj_gen; + ; + } + } + + final public void rel_op() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 70: + jj_consume_token(70); + break; + case 71: + jj_consume_token(71); + break; + case 72: + jj_consume_token(72); + break; + case 73: + jj_consume_token(73); + break; + case 74: + jj_consume_token(74); + break; + case 75: + jj_consume_token(75); + break; + default: + jj_la1[10] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void arithmetic_expression() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 76: + case 77: + case 78: + case 79: + add_op(); + break; + default: + jj_la1[11] = jj_gen; + ; + } + term(); + label_5: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 76: + case 77: + case 78: + case 79: + ; + break; + default: + jj_la1[12] = jj_gen; + break label_5; + } + add_op(); + term(); + } + } + + final public void add_op() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 76: + jj_consume_token(76); + break; + case 77: + jj_consume_token(77); + break; + case 78: + jj_consume_token(78); + break; + case 79: + jj_consume_token(79); + break; + default: + jj_la1[13] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void term() throws ParseException { + factor(); + label_6: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 80: + case 81: + case 82: + case 83: + ; + break; + default: + jj_la1[14] = jj_gen; + break label_6; + } + mul_op(); + factor(); + } + } + + final public void factor() throws ParseException { + primary(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 84: + case 85: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 84: + jj_consume_token(84); + primary(); + break; + case 85: + jj_consume_token(85); + primary(); + break; + default: + jj_la1[15] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[16] = jj_gen; + ; + } + } + + final public void mul_op() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 80: + jj_consume_token(80); + break; + case 81: + jj_consume_token(81); + break; + case 82: + jj_consume_token(82); + break; + case 83: + jj_consume_token(83); + break; + default: + jj_la1[17] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void primary() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case UNSIGNED_NUMBER: + jj_consume_token(UNSIGNED_NUMBER); + break; + case UNSIGNED_INTEGER: + jj_consume_token(UNSIGNED_INTEGER); + break; + case STRING: + jj_consume_token(STRING); + break; + case 6: + jj_consume_token(6); + break; + case 33: + jj_consume_token(33); + break; + default: + jj_la1[19] = jj_gen; + if (jj_2_1(2147483647)) { + functionCall = null; + name(); + function_call_args(); + functionCall = null; + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + case QIDENT: + component_reference(null); + break; + case 60: + jj_consume_token(60); + expression(); + jj_consume_token(61); + break; + case 64: + jj_consume_token(64); + expression_list(); + label_7: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + ; + break; + default: + jj_la1[18] = jj_gen; + break label_7; + } + jj_consume_token(68); + expression_list(); + } + jj_consume_token(65); + break; + case 62: + jj_consume_token(62); + function_arguments(); + jj_consume_token(63); + break; + case 35: + jj_consume_token(35); + break; + default: + jj_la1[20] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } + + final public Token ident() throws ParseException { + Token concatToken = null; + Token continuationToken = null; + String fullStr = null; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + jj_consume_token(IDENT); + concatToken = token; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + case QIDENT: + continuationToken = ident(); + fullStr = new String(""); + // Replace whitespace sequence with a single space character. + fullStr += concatToken.image + " " + continuationToken.image; + + Token tempToken = new Token(concatToken.kind, fullStr); + tempToken.beginLine = concatToken.beginLine; + tempToken.beginColumn = concatToken.beginColumn; + tempToken.endLine = token.endLine; + tempToken.endColumn = token.endColumn; + concatToken = tempToken; + break; + default: + jj_la1[21] = jj_gen; + ; + } + {if (true) return concatToken;} + break; + case QIDENT: + jj_consume_token(QIDENT); + {if (true) return token;} + break; + default: + jj_la1[22] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + throw new Error("Missing return statement in function"); + } + + final public void name() throws ParseException { + Token identToken = null; + identToken = ident(); + if (functionCall == null) + functionCall = identToken.image; + else + functionCall += "." + identToken.image; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + jj_consume_token(66); + name(); + break; + default: + jj_la1[23] = jj_gen; + ; + } + } + + final public void component_reference(String prevToken) throws ParseException { + Token identToken = null; + //IDENT [ array_subscripts ] [ "." component_reference ] + identToken = ident(); + String name = identToken.image; + // forIndex == true and prevToken != null => this is the second part of an enumeration in for-index + if(forIndex == true) { + if(prevToken != null) { + if(enumerationReferences.get(prevToken) == null) { + enumerationReferences.put(prevToken, new ArrayList()); + } + List list = enumerationReferences.get(prevToken); + list.add(identToken); + + // forIndex == true and prevToken == null => this is the enumeration in for-index + } else { + if(enumerationReferences.get(name) == null) { + enumerationReferences.put(name, new ArrayList()); + } + List list = enumerationReferences.get(name); + list.add(identToken); + } + } else { + if(prevToken != null) + name = prevToken + "." + name; + if(references.get(name) == null) { + references.put(name, new ArrayList()); + } + List list = references.get(name); + list.add(identToken); + + if(functionCall != null) { + if(!functionCallReferences.containsKey(functionCall)) + functionCallReferences.put(functionCall, new ArrayList()); + List functionReferencelist = getFunctionCallReferences().get(functionCall); + functionReferencelist.add(identToken); + } + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 64: + array_subscripts(identToken); + break; + default: + jj_la1[24] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + jj_consume_token(66); + component_reference(name); + break; + default: + jj_la1[25] = jj_gen; + ; + } + } + + final public void function_call_args() throws ParseException { + jj_consume_token(60); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case QIDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + function_arguments(); + break; + default: + jj_la1[26] = jj_gen; + ; + } + jj_consume_token(61); + if(functionCall != null) { + if(!functionCallReferences.containsKey(functionCall)) + functionCallReferences.put(functionCall, new ArrayList()); + } + } + + final public void function_arguments() throws ParseException { + if (jj_2_2(2147483647)) { + named_argument(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + function_arguments(); + break; + default: + jj_la1[27] = jj_gen; + ; + } + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case QIDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 21: + case 69: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + function_arguments(); + break; + case 21: + jj_consume_token(21); + for_indices(); + break; + default: + jj_la1[28] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[29] = jj_gen; + ; + } + break; + default: + jj_la1[30] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + + final public void for_indices() throws ParseException { + for_index(); + label_8: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + ; + break; + default: + jj_la1[31] = jj_gen; + break label_8; + } + jj_consume_token(69); + for_index(); + } + } + + final public void for_index() throws ParseException { + Token identToken = null; + //IDENT [ in expression ] + identToken = ident(); + forIndices.put(identToken, currentRange); + forIndex = true; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 41: + jj_consume_token(41); + ForRange forRange = new ForRange(); + forRange.start = token; + expression(); + forRange.start = forRange.start.next; + forRange.end = token; + forRanges.add(forRange); + break; + default: + jj_la1[32] = jj_gen; + ; + } + forIndex = false; + } + +/* Removed by Teemu. Refactored in function_arguments) +void named_arguments() : { +} { + named_argument() ( "," named_arguments() )? +} +*/ + final public void named_argument() throws ParseException { + ident(); + jj_consume_token(86); + expression(); + } + + final public void output_expression_list() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case QIDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[33] = jj_gen; + ; + } + label_9: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + ; + break; + default: + jj_la1[34] = jj_gen; + break label_9; + } + jj_consume_token(69); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case QIDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[35] = jj_gen; + ; + } + } + } + + final public void expression_list() throws ParseException { + expression(); + label_10: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + ; + break; + default: + jj_la1[36] = jj_gen; + break label_10; + } + jj_consume_token(69); + expression(); + } + } + + final public void array_subscripts(Token prevToken) throws ParseException { + if(ranges.get(prevToken.image) == null) { + ranges.put(prevToken.image, new ArrayList>()); + } + List> rangesList = ranges.get(prevToken.image); + currentRange = new ArrayList(); + jj_consume_token(64); + subscript(currentRange); + label_11: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + ; + break; + default: + jj_la1[37] = jj_gen; + break label_11; + } + jj_consume_token(69); + subscript(currentRange); + } + jj_consume_token(65); + rangesList.add(currentRange); + } + + final public void subscript(List currentRange) throws ParseException { + Token rangeToken = new Token(token.kind, ""); + rangeToken.beginColumn = token.beginColumn + 1; + rangeToken.beginLine = token.beginLine; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 67: + jj_consume_token(67); + currentRange.add(token); + break; + default: + jj_la1[39] = jj_gen; + if (jj_2_3(2147483647)) { + functionCall = null; + name(); + function_call_args(); + functionCall = null; + rangeToken.image = ""; + rangeToken.endColumn = token.endColumn; + rangeToken.endLine = token.endLine; + currentRange.add(rangeToken); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + case QIDENT: + case UNSIGNED_INTEGER: + rangeIndex(rangeToken, true); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 67: + jj_consume_token(67); + rangeIndex(rangeToken, false); + break; + default: + jj_la1[38] = jj_gen; + ; + } + rangeToken.endColumn = token.endColumn; + rangeToken.endLine = token.endLine; + currentRange.add(rangeToken); + break; + default: + jj_la1[40] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } + + final public void rangeIndex(Token rangeToken, boolean first) throws ParseException { + Token identToken = null; + if(!first) + rangeToken.image = rangeToken.image + ":"; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case UNSIGNED_INTEGER: + jj_consume_token(UNSIGNED_INTEGER); + rangeToken.image = rangeToken.image + token.image; + break; + case IDENT: + case QIDENT: + identToken = ident(); + rangeToken.image = rangeToken.image + identToken; + break; + default: + jj_la1[41] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + private boolean jj_2_1(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_1(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(0, xla); } + } + + private boolean jj_2_2(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_2(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(1, xla); } + } + + private boolean jj_2_3(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_3(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(2, xla); } + } + + private boolean jj_3R_34() { + if (jj_3R_38()) return true; + return false; + } + + private boolean jj_3R_32() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_34()) jj_scanpos = xsp; + if (jj_3R_35()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_36()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_37() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(70)) { + jj_scanpos = xsp; + if (jj_scan_token(71)) { + jj_scanpos = xsp; + if (jj_scan_token(72)) { + jj_scanpos = xsp; + if (jj_scan_token(73)) { + jj_scanpos = xsp; + if (jj_scan_token(74)) { + jj_scanpos = xsp; + if (jj_scan_token(75)) return true; + } + } + } + } + } + return false; + } + + private boolean jj_3R_15() { + if (jj_scan_token(66)) return true; + if (jj_3R_12()) return true; + return false; + } + + private boolean jj_3R_74() { + if (jj_scan_token(67)) return true; + if (jj_3R_73()) return true; + return false; + } + + private boolean jj_3R_25() { + if (jj_scan_token(67)) return true; + if (jj_3R_24()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_28()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_27() { + if (jj_scan_token(22)) return true; + if (jj_3R_26()) return true; + return false; + } + + private boolean jj_3R_79() { + if (jj_scan_token(41)) return true; + if (jj_3R_16()) return true; + return false; + } + + private boolean jj_3R_31() { + if (jj_3R_32()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_33()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_29() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(12)) jj_scanpos = xsp; + if (jj_3R_31()) return true; + return false; + } + + private boolean jj_3R_12() { + if (jj_3R_14()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_15()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_76() { + if (jj_scan_token(69)) return true; + if (jj_3R_75()) return true; + return false; + } + + private boolean jj_3R_26() { + if (jj_3R_29()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_30()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_67() { + if (jj_scan_token(69)) return true; + if (jj_3R_55()) return true; + return false; + } + + private boolean jj_3R_64() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_67()) { + jj_scanpos = xsp; + if (jj_3R_68()) return true; + } + return false; + } + + private boolean jj_3R_58() { + if (jj_scan_token(66)) return true; + if (jj_3R_52()) return true; + return false; + } + + private boolean jj_3R_78() { + if (jj_3R_14()) return true; + return false; + } + + private boolean jj_3R_75() { + if (jj_3R_14()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_79()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_24() { + if (jj_3R_26()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_27()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_77() { + if (jj_scan_token(UNSIGNED_INTEGER)) return true; + return false; + } + + private boolean jj_3R_73() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_77()) { + jj_scanpos = xsp; + if (jj_3R_78()) return true; + } + return false; + } + + private boolean jj_3_2() { + if (jj_3R_13()) return true; + return false; + } + + private boolean jj_3R_22() { + if (jj_3R_24()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_25()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_18() { + if (jj_scan_token(QIDENT)) return true; + return false; + } + + private boolean jj_3R_72() { + if (jj_3R_75()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_76()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_54() { + if (jj_scan_token(68)) return true; + if (jj_3R_53()) return true; + return false; + } + + private boolean jj_3R_20() { + if (jj_scan_token(31)) return true; + if (jj_3R_16()) return true; + if (jj_scan_token(28)) return true; + if (jj_3R_16()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_23()) { jj_scanpos = xsp; break; } + } + if (jj_scan_token(15)) return true; + if (jj_3R_16()) return true; + return false; + } + + private boolean jj_3R_61() { + if (jj_3R_16()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_64()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_66() { + if (jj_scan_token(69)) return true; + if (jj_3R_65()) return true; + return false; + } + + private boolean jj_3R_19() { + if (jj_3R_22()) return true; + return false; + } + + private boolean jj_3R_16() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_19()) { + jj_scanpos = xsp; + if (jj_3R_20()) return true; + } + return false; + } + + private boolean jj_3_3() { + if (jj_3R_12()) return true; + if (jj_scan_token(60)) return true; + return false; + } + + private boolean jj_3R_71() { + if (jj_3R_73()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_74()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_60() { + if (jj_3R_13()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_63()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_55() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_60()) { + jj_scanpos = xsp; + if (jj_3R_61()) return true; + } + return false; + } + + private boolean jj_3R_56() { + if (jj_3R_55()) return true; + return false; + } + + private boolean jj_3R_21() { + if (jj_3R_14()) return true; + return false; + } + + private boolean jj_3R_70() { + if (jj_3R_12()) return true; + if (jj_3R_51()) return true; + return false; + } + + private boolean jj_3R_17() { + if (jj_scan_token(IDENT)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_21()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_14() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_17()) { + jj_scanpos = xsp; + if (jj_3R_18()) return true; + } + return false; + } + + private boolean jj_3R_51() { + if (jj_scan_token(60)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_56()) jj_scanpos = xsp; + if (jj_scan_token(61)) return true; + return false; + } + + private boolean jj_3R_50() { + if (jj_scan_token(85)) return true; + if (jj_3R_41()) return true; + return false; + } + + private boolean jj_3R_57() { + if (jj_3R_62()) return true; + return false; + } + + private boolean jj_3R_69() { + if (jj_scan_token(67)) return true; + return false; + } + + private boolean jj_3R_65() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_69()) { + jj_scanpos = xsp; + if (jj_3R_70()) { + jj_scanpos = xsp; + if (jj_3R_71()) return true; + } + } + return false; + } + + private boolean jj_3_1() { + if (jj_3R_12()) return true; + if (jj_scan_token(60)) return true; + return false; + } + + private boolean jj_3R_48() { + if (jj_scan_token(62)) return true; + if (jj_3R_55()) return true; + if (jj_scan_token(63)) return true; + return false; + } + + private boolean jj_3R_47() { + if (jj_scan_token(64)) return true; + if (jj_3R_53()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_54()) { jj_scanpos = xsp; break; } + } + if (jj_scan_token(65)) return true; + return false; + } + + private boolean jj_3R_46() { + if (jj_scan_token(60)) return true; + if (jj_3R_16()) return true; + if (jj_scan_token(61)) return true; + return false; + } + + private boolean jj_3R_45() { + if (jj_3R_52()) return true; + return false; + } + + private boolean jj_3R_59() { + if (jj_scan_token(69)) return true; + if (jj_3R_16()) return true; + return false; + } + + private boolean jj_3R_62() { + if (jj_scan_token(64)) return true; + if (jj_3R_65()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_66()) { jj_scanpos = xsp; break; } + } + if (jj_scan_token(65)) return true; + return false; + } + + private boolean jj_3R_44() { + if (jj_3R_12()) return true; + if (jj_3R_51()) return true; + return false; + } + + private boolean jj_3R_49() { + if (jj_scan_token(84)) return true; + if (jj_3R_41()) return true; + return false; + } + + private boolean jj_3R_42() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_49()) { + jj_scanpos = xsp; + if (jj_3R_50()) return true; + } + return false; + } + + private boolean jj_3R_41() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(92)) { + jj_scanpos = xsp; + if (jj_scan_token(91)) { + jj_scanpos = xsp; + if (jj_scan_token(90)) { + jj_scanpos = xsp; + if (jj_scan_token(6)) { + jj_scanpos = xsp; + if (jj_scan_token(33)) { + jj_scanpos = xsp; + if (jj_3R_44()) { + jj_scanpos = xsp; + if (jj_3R_45()) { + jj_scanpos = xsp; + if (jj_3R_46()) { + jj_scanpos = xsp; + if (jj_3R_47()) { + jj_scanpos = xsp; + if (jj_3R_48()) { + jj_scanpos = xsp; + if (jj_scan_token(35)) return true; + } + } + } + } + } + } + } + } + } + } + return false; + } + + private boolean jj_3R_28() { + if (jj_scan_token(67)) return true; + if (jj_3R_24()) return true; + return false; + } + + private boolean jj_3R_40() { + if (jj_3R_43()) return true; + if (jj_3R_39()) return true; + return false; + } + + private boolean jj_3R_33() { + if (jj_3R_37()) return true; + if (jj_3R_32()) return true; + return false; + } + + private boolean jj_3R_36() { + if (jj_3R_38()) return true; + if (jj_3R_35()) return true; + return false; + } + + private boolean jj_3R_43() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(80)) { + jj_scanpos = xsp; + if (jj_scan_token(81)) { + jj_scanpos = xsp; + if (jj_scan_token(82)) { + jj_scanpos = xsp; + if (jj_scan_token(83)) return true; + } + } + } + return false; + } + + private boolean jj_3R_39() { + if (jj_3R_41()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_42()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_53() { + if (jj_3R_16()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_59()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_63() { + if (jj_scan_token(69)) return true; + if (jj_3R_55()) return true; + return false; + } + + private boolean jj_3R_13() { + if (jj_3R_14()) return true; + if (jj_scan_token(86)) return true; + if (jj_3R_16()) return true; + return false; + } + + private boolean jj_3R_68() { + if (jj_scan_token(21)) return true; + if (jj_3R_72()) return true; + return false; + } + + private boolean jj_3R_23() { + if (jj_scan_token(20)) return true; + if (jj_3R_16()) return true; + if (jj_scan_token(28)) return true; + if (jj_3R_16()) return true; + return false; + } + + private boolean jj_3R_35() { + if (jj_3R_39()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_40()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_38() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(76)) { + jj_scanpos = xsp; + if (jj_scan_token(77)) { + jj_scanpos = xsp; + if (jj_scan_token(78)) { + jj_scanpos = xsp; + if (jj_scan_token(79)) return true; + } + } + } + return false; + } + + private boolean jj_3R_52() { + if (jj_3R_14()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_57()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_58()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_30() { + if (jj_scan_token(9)) return true; + if (jj_3R_29()) return true; + return false; + } + + /** Generated Token Manager. */ + public ExpressionParserTokenManager token_source; + SimpleCharStream jj_input_stream; + /** Current token. */ + public Token token; + /** Next token. */ + public Token jj_nt; + private int jj_ntk; + private Token jj_scanpos, jj_lastpos; + private int jj_la; + private int jj_gen; + final private int[] jj_la1 = new int[42]; + static private int[] jj_la1_0; + static private int[] jj_la1_1; + static private int[] jj_la1_2; + static { + jj_la1_init_0(); + jj_la1_init_1(); + jj_la1_init_2(); + } + private static void jj_la1_init_0() { + jj_la1_0 = new int[] {0x100000,0x80001040,0x100000,0x80001040,0x0,0x0,0x400000,0x200,0x1000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x80001040,0x0,0x200000,0x200000,0x80001040,0x0,0x0,0x80001040,0x0,0x80001040,0x0,0x0,0x0,0x0,0x0,0x0,}; + } + private static void jj_la1_init_1() { + jj_la1_1 = new int[] {0x0,0x5000000a,0x0,0x5000000a,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x50000008,0x0,0x0,0x0,0x0,0x0,0x5000000a,0x0,0x0,0x0,0x5000000a,0x0,0x200,0x5000000a,0x0,0x5000000a,0x0,0x0,0x0,0x0,0x0,0x0,}; + } + private static void jj_la1_init_2() { + jj_la1_2 = new int[] {0x0,0x1f00f001,0x0,0x1f00f001,0x8,0x8,0x0,0x0,0x0,0xfc0,0xfc0,0xf000,0xf000,0xf000,0xf0000,0x300000,0x300000,0xf0000,0x10,0x1c000000,0x3000001,0x3000000,0x3000000,0x4,0x1,0x4,0x1f00f001,0x20,0x20,0x20,0x1f00f001,0x20,0x0,0x1f00f001,0x20,0x1f00f001,0x20,0x20,0x8,0x8,0xb000000,0xb000000,}; + } + final private JJCalls[] jj_2_rtns = new JJCalls[3]; + private boolean jj_rescan = false; + private int jj_gc = 0; + + /** Constructor with InputStream. */ + public ExpressionParser(java.io.InputStream stream) { + this(stream, null); + } + /** Constructor with InputStream and supplied encoding */ + public ExpressionParser(java.io.InputStream stream, String encoding) { + try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source = new ExpressionParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 42; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream, String encoding) { + try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 42; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor. */ + public ExpressionParser(java.io.Reader stream) { + jj_input_stream = new SimpleCharStream(stream, 1, 1); + token_source = new ExpressionParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 42; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 42; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor with generated Token Manager. */ + public ExpressionParser(ExpressionParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 42; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(ExpressionParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 42; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + jj_gen++; + if (++jj_gc > 100) { + jj_gc = 0; + for (int i = 0; i < jj_2_rtns.length; i++) { + JJCalls c = jj_2_rtns[i]; + while (c != null) { + if (c.gen < jj_gen) c.first = null; + c = c.next; + } + } + } + return token; + } + token = oldToken; + jj_kind = kind; + throw generateParseException(); + } + + static private final class LookaheadSuccess extends java.lang.Error { } + final private LookaheadSuccess jj_ls = new LookaheadSuccess(); + private boolean jj_scan_token(int kind) { + if (jj_scanpos == jj_lastpos) { + jj_la--; + if (jj_scanpos.next == null) { + jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); + } else { + jj_lastpos = jj_scanpos = jj_scanpos.next; + } + } else { + jj_scanpos = jj_scanpos.next; + } + if (jj_rescan) { + int i = 0; Token tok = token; + while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; } + if (tok != null) jj_add_error_token(kind, i); + } + if (jj_scanpos.kind != kind) return true; + if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls; + return false; + } + + +/** Get the next Token. */ + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; + } + +/** Get the specific Token. */ + final public Token getToken(int index) { + Token t = token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + private int jj_ntk() { + if ((jj_nt=token.next) == null) + return (jj_ntk = (token.next=token_source.getNextToken()).kind); + else + return (jj_ntk = jj_nt.kind); + } + + private java.util.List jj_expentries = new java.util.ArrayList(); + private int[] jj_expentry; + private int jj_kind = -1; + private int[] jj_lasttokens = new int[100]; + private int jj_endpos; + + private void jj_add_error_token(int kind, int pos) { + if (pos >= 100) return; + if (pos == jj_endpos + 1) { + jj_lasttokens[jj_endpos++] = kind; + } else if (jj_endpos != 0) { + jj_expentry = new int[jj_endpos]; + for (int i = 0; i < jj_endpos; i++) { + jj_expentry[i] = jj_lasttokens[i]; + } + jj_entries_loop: for (java.util.Iterator it = jj_expentries.iterator(); it.hasNext();) { + int[] oldentry = (int[])(it.next()); + if (oldentry.length == jj_expentry.length) { + for (int i = 0; i < jj_expentry.length; i++) { + if (oldentry[i] != jj_expentry[i]) { + continue jj_entries_loop; + } + } + jj_expentries.add(jj_expentry); + break jj_entries_loop; + } + } + if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind; + } + } + + /** Generate ParseException. */ + public ParseException generateParseException() { + jj_expentries.clear(); + boolean[] la1tokens = new boolean[93]; + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int i = 0; i < 42; i++) { + if (jj_la1[i] == jj_gen) { + for (int j = 0; j < 32; j++) { + if ((jj_la1_0[i] & (1< jj_gen) { + jj_la = p.arg; jj_lastpos = jj_scanpos = p.first; + switch (i) { + case 0: jj_3_1(); break; + case 1: jj_3_2(); break; + case 2: jj_3_3(); break; + } + } + p = p.next; + } while (p != null); + } catch(LookaheadSuccess ls) { } + } + jj_rescan = false; + } + + private void jj_save(int index, int xla) { + JJCalls p = jj_2_rtns[index]; + while (p.gen > jj_gen) { + if (p.next == null) { p = p.next = new JJCalls(); break; } + p = p.next; + } + p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla; + } + + static final class JJCalls { + int gen; + Token first; + int arg; + JJCalls next; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.jj b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.jj new file mode 100644 index 00000000..5e8c3c2b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.jj @@ -0,0 +1,418 @@ +options { + JDK_VERSION = "1.6"; + STATIC = false; +} + +PARSER_BEGIN(ExpressionParser) +package org.simantics.sysdyn.expressionParser; + +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; + +@SuppressWarnings({"unused", "serial"}) +public class ExpressionParser { + + public class ForRange { public Token start; + public Token end; + } + + boolean forIndex = false; + Token firstToken; + + public Token getFirstToken() { return firstToken; + } + List forRanges = new ArrayList(); + + public List getForRanges() { + return forRanges; + } + + HashMap> references = new HashMap>(); + + public HashMap> getReferences() { + return references; + } + + HashMap>> ranges = new HashMap>>(); + + public HashMap>> getRanges() { + return ranges; + } + + List currentRange = null; + + HashMap> forIndices = new HashMap>(); + + public HashMap> getForIndices() { + return forIndices; + } + + HashMap> enumerationReferences = new HashMap>(); + + public HashMap> getEnumerationReferences() { + return enumerationReferences; + } + +/* + Collect EACH function call and all references that are inside the call brackets. + These are later used to exclude spread sheet references out of the normal functions. +*/ + String functionCall = null; + HashMap> functionCallReferences = new HashMap>(); + + public HashMap> getFunctionCallReferences() { + return functionCallReferences; + } + + +} +PARSER_END(ExpressionParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ +"algorithm" | "discrete" | "false" | "model" | "redeclare" +| "and" | "each" | "final" | "not" | "replaceable" +| "annotation" | "else" | "flow" | "operator" | "return" +|"assert" | "elseif" | "for" | "or" | "stream" +| "block" | "elsewhen" | "function" | "outer" | "then" +| "break" | "encapsulated" | "if" | "output" | "true" +| "class" | "end" | "import" | "package" | "type" +| "connect" | "enumeration" | "in" | "parameter" | "when" +| "connector" | "equation" | /*"initial" |*/ "partial" | "while" +| "constant" | "expandable" | "inner" | "protected" | "within" +| "constrainedby" | "extends" | "input" | "public" +| /*"der" |*/ "external" | "loop" | "record" +| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | "," +| "<" | "<=" | ">" | ">=" | "==" | "<>" +| "+" | "-" | ".+" | ".-" +| "*" | "/" | ".*" | "./" +| "^" | ".^" +| "=" | ":=" +| +| + /* Excluded "#","$","%","&","(",")","<",">","[","]","{","}","|", and "\"" because of Sysdyn */ + /* Excluded "\?", "\a", and "\v" because of JavaCC */ + /* Excluded "\n","\r", and "\t" just in case */ +| + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +| +| "." ()? (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +} + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + +void expr() : { + jj_input_stream.setTabSize(1); +} { + { + firstToken = token; + } + simple_expression() + | + { + firstToken = token; + } + "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* + "else" expression() +} + +void expression() : { +} { + simple_expression() + | "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* + "else" expression() +} + +void simple_expression() : { +} { + logical_expression() ( ":" logical_expression() ( ":" logical_expression() )? )? +} + +void logical_expression() : { +} { + logical_term() ( "or" logical_term() )* +} + +void logical_term() : { +} { + logical_factor() ( "and" logical_factor() )* +} + +void logical_factor() : { +} { + ( "not" )? relation() +} + +void relation() : { +} { + arithmetic_expression() ( rel_op() arithmetic_expression() )? +} + +void rel_op() : { +} { + "<" | "<=" | ">" | ">=" | "==" | "<>" +} + +void arithmetic_expression() : { +} { + (add_op())? term() (add_op() term())* +} + +void add_op() : { +} { + "+" | "-" | ".+" | ".-" +} + +void term() : { +} { + factor() ( mul_op() factor() )* +} + +void factor() : { +} { + primary() ( "^" primary() | ".^" primary() )? +} + +void mul_op() : { +} { + "*" | "/" | ".*" | "./" +} + +void primary() : { +} { + + | + | + | "false" + | "true" + | LOOKAHEAD( name() "(" ) { functionCall = null; + } + name() function_call_args() { functionCall = null; + } + | component_reference(null) + /*| "(" output_expression_list() ")"*/ // Not needed, replaced with following: + | "(" expression() ")" + | "[" expression_list() ( ";" expression_list() )* "]" + | "{" function_arguments() "}" + | "end" +} + +Token ident() : { + Token concatToken = null; + Token continuationToken = null; + String fullStr = null; +} { + + { concatToken = token; } + ( continuationToken = ident() + { + fullStr = new String(""); + // Replace whitespace sequence with a single space character. + fullStr += concatToken.image + " " + continuationToken.image; + + Token tempToken = new Token(concatToken.kind, fullStr); + tempToken.beginLine = concatToken.beginLine; + tempToken.beginColumn = concatToken.beginColumn; + tempToken.endLine = token.endLine; + tempToken.endColumn = token.endColumn; + concatToken = tempToken; + } + )? + { return concatToken; + } + | + + { + return token; + } +} +void name() : { + Token identToken = null; +} { + identToken = ident() + { if (functionCall == null) + functionCall = identToken.image; + else + functionCall += "." + identToken.image; + } + ( "." name() )? +} + +void component_reference(String prevToken) : { + Token identToken = null; +} { + //IDENT [ array_subscripts ] [ "." component_reference ] + identToken = ident() + { + String name = identToken.image; + // forIndex == true and prevToken != null => this is the second part of an enumeration in for-index + if(forIndex == true) { if(prevToken != null) { + if(enumerationReferences.get(prevToken) == null) { enumerationReferences.put(prevToken, new ArrayList()); + } + List list = enumerationReferences.get(prevToken); + list.add(identToken); + + // forIndex == true and prevToken == null => this is the enumeration in for-index + } else { + if(enumerationReferences.get(name) == null) { + enumerationReferences.put(name, new ArrayList()); + } + List list = enumerationReferences.get(name); + list.add(identToken); + } + } else { + if(prevToken != null) + name = prevToken + "." + name; if(references.get(name) == null) { + references.put(name, new ArrayList()); + } + List list = references.get(name); + list.add(identToken); + + if(functionCall != null) { + if(!functionCallReferences.containsKey(functionCall)) + functionCallReferences.put(functionCall, new ArrayList()); + List functionReferencelist = getFunctionCallReferences().get(functionCall); + functionReferencelist.add(identToken); } + } + + } + + ( array_subscripts(identToken) )? ( "." component_reference(name) )? +} + +void function_call_args() : { +} { + "(" ( function_arguments() )? ")" { if(functionCall != null) { + if(!functionCallReferences.containsKey(functionCall)) + functionCallReferences.put(functionCall, new ArrayList()); + } + } +} + +void function_arguments() : { +} { + //expression [ "," function_arguments | for for_indices ] + //| named_arguments + LOOKAHEAD(named_argument()) named_argument() ( "," function_arguments() )? + | expression() ( "," function_arguments() | "for" for_indices() )? + +} + +void for_indices() : { +} { + //for_index {"," for_index} + for_index() ("," for_index())* +} + +void for_index() : { + Token identToken = null; +} { + //IDENT [ in expression ] + identToken = ident() + { + forIndices.put(identToken, currentRange); + forIndex = true; } + ( "in" { + ForRange forRange = new ForRange(); + forRange.start = token; } + expression() { + forRange.start = forRange.start.next; + forRange.end = token; + forRanges.add(forRange); } + )? + { forIndex = false; + } +} + +/* Removed by Teemu. Refactored in function_arguments) +void named_arguments() : { +} { + named_argument() ( "," named_arguments() )? +} +*/ + +void named_argument() : { +} { + ident() "=" expression() +} + +void output_expression_list() : { +} { + ( expression() )? ( "," ( expression() )? )* +} + + +void expression_list() : { +} { + expression() ( "," expression() )* +} + +void array_subscripts(Token prevToken) : { if(ranges.get(prevToken.image) == null) { + ranges.put(prevToken.image, new ArrayList>()); + } + List> rangesList = ranges.get(prevToken.image); + currentRange = new ArrayList(); +} { + "[" subscript(currentRange) ( "," subscript(currentRange) )* "]" + { + rangesList.add(currentRange); + } +} + +void subscript(List currentRange) : { + Token rangeToken = new Token(token.kind, ""); + rangeToken.beginColumn = token.beginColumn + 1; + rangeToken.beginLine = token.beginLine; +} { ":" { currentRange.add(token); + } + | LOOKAHEAD( name() "(" ) + { + functionCall = null; + } + name() function_call_args() + { + functionCall = null; + rangeToken.image = ""; + rangeToken.endColumn = token.endColumn; + rangeToken.endLine = token.endLine; + currentRange.add(rangeToken); + } + | rangeIndex(rangeToken, true) ( ":" rangeIndex(rangeToken, false))? { + rangeToken.endColumn = token.endColumn; + rangeToken.endLine = token.endLine; + currentRange.add(rangeToken); + } +} + +void rangeIndex(Token rangeToken, boolean first) : { + Token identToken = null; + if(!first) + rangeToken.image = rangeToken.image + ":"; +} { { + rangeToken.image = rangeToken.image + token.image; } + | identToken = ident() + { rangeToken.image = rangeToken.image + identToken; + } +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParserConstants.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParserConstants.java new file mode 100644 index 00000000..62dfa364 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParserConstants.java @@ -0,0 +1,130 @@ +/* Generated By:JavaCC: Do not edit this line. ExpressionParserConstants.java */ +package org.simantics.sysdyn.expressionParser; + + +/** + * Token literal values and constants. + * Generated by org.javacc.parser.OtherFilesGen#start() + */ +public interface ExpressionParserConstants { + + /** End of File. */ + int EOF = 0; + /** RegularExpression Id. */ + int WHITESPACE = 1; + /** RegularExpression Id. */ + int COMMENT1 = 2; + /** RegularExpression Id. */ + int COMMENT2 = 3; + /** RegularExpression Id. */ + int IDENT = 88; + /** RegularExpression Id. */ + int QIDENT = 89; + /** RegularExpression Id. */ + int STRING = 90; + /** RegularExpression Id. */ + int UNSIGNED_INTEGER = 91; + /** RegularExpression Id. */ + int UNSIGNED_NUMBER = 92; + + /** Lexical state. */ + int DEFAULT = 0; + + /** Literal token values. */ + String[] tokenImage = { + "", + "", + "", + "", + "\"algorithm\"", + "\"discrete\"", + "\"false\"", + "\"model\"", + "\"redeclare\"", + "\"and\"", + "\"each\"", + "\"final\"", + "\"not\"", + "\"replaceable\"", + "\"annotation\"", + "\"else\"", + "\"flow\"", + "\"operator\"", + "\"return\"", + "\"assert\"", + "\"elseif\"", + "\"for\"", + "\"or\"", + "\"stream\"", + "\"block\"", + "\"elsewhen\"", + "\"function\"", + "\"outer\"", + "\"then\"", + "\"break\"", + "\"encapsulated\"", + "\"if\"", + "\"output\"", + "\"true\"", + "\"class\"", + "\"end\"", + "\"import\"", + "\"package\"", + "\"type\"", + "\"connect\"", + "\"enumeration\"", + "\"in\"", + "\"parameter\"", + "\"when\"", + "\"connector\"", + "\"equation\"", + "\"partial\"", + "\"while\"", + "\"constant\"", + "\"expandable\"", + "\"inner\"", + "\"protected\"", + "\"within\"", + "\"constrainedby\"", + "\"extends\"", + "\"input\"", + "\"public\"", + "\"external\"", + "\"loop\"", + "\"record\"", + "\"(\"", + "\")\"", + "\"{\"", + "\"}\"", + "\"[\"", + "\"]\"", + "\".\"", + "\":\"", + "\";\"", + "\",\"", + "\"<\"", + "\"<=\"", + "\">\"", + "\">=\"", + "\"==\"", + "\"<>\"", + "\"+\"", + "\"-\"", + "\".+\"", + "\".-\"", + "\"*\"", + "\"/\"", + "\".*\"", + "\"./\"", + "\"^\"", + "\".^\"", + "\"=\"", + "\":=\"", + "", + "", + "", + "", + "", + }; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParserTokenManager.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParserTokenManager.java new file mode 100644 index 00000000..011bc205 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParserTokenManager.java @@ -0,0 +1,1348 @@ +/* Generated By:JavaCC: Do not edit this line. ExpressionParserTokenManager.java */ +package org.simantics.sysdyn.expressionParser; +import java.util.Set; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; + +/** Token Manager. */ +public class ExpressionParserTokenManager implements ExpressionParserConstants +{ + + /** Debug output. */ + public java.io.PrintStream debugStream = System.out; + /** Set debug output. */ + public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } +private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1) +{ + switch (pos) + { + case 0: + if ((active1 & 0x2cc004L) != 0L) + return 12; + if ((active0 & 0xffffffffffffff0L) != 0L) + { + jjmatchedKind = 88; + return 2; + } + if ((active1 & 0x20000L) != 0L) + return 16; + return -1; + case 1: + if ((active0 & 0x84020080400000L) != 0L) + return 2; + if ((active0 & 0xf7bfdff7fbffff0L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 88; + jjmatchedPos = 1; + } + return 2; + } + return -1; + case 2: + if ((active0 & 0x800201200L) != 0L) + return 2; + if ((active0 & 0xffffdf77f9fedf0L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 2; + return 2; + } + return -1; + case 3: + if ((active0 & 0x400084212118400L) != 0L) + return 2; + if ((active0 & 0xbfff5b56d8e69f0L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 88; + jjmatchedPos = 3; + } + return 2; + } + return -1; + case 4: + if ((active0 & 0x848004290008c0L) != 0L) + return 2; + if ((active0 & 0xb7b75b1469e6130L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 4; + return 2; + } + return -1; + case 5: + if ((active0 & 0x9100011009c0000L) != 0L) + return 2; + if ((active0 & 0x26b75a046026130L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 5; + return 2; + } + return -1; + case 6: + if ((active0 & 0x4050a000000000L) != 0L) + return 2; + if ((active0 & 0x22b250046026130L) != 0L) + { + if (jjmatchedPos != 6) + { + jjmatchedKind = 88; + jjmatchedPos = 6; + } + return 2; + } + return -1; + case 7: + if ((active0 & 0x201200006020020L) != 0L) + return 2; + if ((active0 & 0x2a150040006110L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 7; + return 2; + } + return -1; + case 8: + if ((active0 & 0x22010040006000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 8; + return 2; + } + if ((active0 & 0x8140000000110L) != 0L) + return 2; + return -1; + case 9: + if ((active0 & 0x2000000004000L) != 0L) + return 2; + if ((active0 & 0x20010040002000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 9; + return 2; + } + return -1; + case 10: + if ((active0 & 0x10000002000L) != 0L) + return 2; + if ((active0 & 0x20000040000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 10; + return 2; + } + return -1; + case 11: + if ((active0 & 0x40000000L) != 0L) + return 2; + if ((active0 & 0x20000000000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 11; + return 2; + } + return -1; + default : + return -1; + } +} +private final int jjStartNfa_0(int pos, long active0, long active1) +{ + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1); +} +private int jjStopAtPos(int pos, int kind) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} +private int jjMoveStringLiteralDfa0_0() +{ + switch(curChar) + { + case 40: + return jjStopAtPos(0, 60); + case 41: + return jjStopAtPos(0, 61); + case 42: + return jjStopAtPos(0, 80); + case 43: + return jjStopAtPos(0, 76); + case 44: + return jjStopAtPos(0, 69); + case 45: + return jjStopAtPos(0, 77); + case 46: + jjmatchedKind = 66; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2cc000L); + case 47: + return jjStartNfaWithStates_0(0, 81, 16); + case 58: + jjmatchedKind = 67; + return jjMoveStringLiteralDfa1_0(0x0L, 0x800000L); + case 59: + return jjStopAtPos(0, 68); + case 60: + jjmatchedKind = 70; + return jjMoveStringLiteralDfa1_0(0x0L, 0x880L); + case 61: + jjmatchedKind = 86; + return jjMoveStringLiteralDfa1_0(0x0L, 0x400L); + case 62: + jjmatchedKind = 72; + return jjMoveStringLiteralDfa1_0(0x0L, 0x200L); + case 91: + return jjStopAtPos(0, 64); + case 93: + return jjStopAtPos(0, 65); + case 94: + return jjStopAtPos(0, 84); + case 97: + return jjMoveStringLiteralDfa1_0(0x84210L, 0x0L); + case 98: + return jjMoveStringLiteralDfa1_0(0x21000000L, 0x0L); + case 99: + return jjMoveStringLiteralDfa1_0(0x21108400000000L, 0x0L); + case 100: + return jjMoveStringLiteralDfa1_0(0x20L, 0x0L); + case 101: + return jjMoveStringLiteralDfa1_0(0x242210842108400L, 0x0L); + case 102: + return jjMoveStringLiteralDfa1_0(0x4210840L, 0x0L); + case 105: + return jjMoveStringLiteralDfa1_0(0x84021080000000L, 0x0L); + case 108: + return jjMoveStringLiteralDfa1_0(0x400000000000000L, 0x0L); + case 109: + return jjMoveStringLiteralDfa1_0(0x80L, 0x0L); + case 110: + return jjMoveStringLiteralDfa1_0(0x1000L, 0x0L); + case 111: + return jjMoveStringLiteralDfa1_0(0x108420000L, 0x0L); + case 112: + return jjMoveStringLiteralDfa1_0(0x108442000000000L, 0x0L); + case 114: + return jjMoveStringLiteralDfa1_0(0x800000000042100L, 0x0L); + case 115: + return jjMoveStringLiteralDfa1_0(0x800000L, 0x0L); + case 116: + return jjMoveStringLiteralDfa1_0(0x4210000000L, 0x0L); + case 119: + return jjMoveStringLiteralDfa1_0(0x10880000000000L, 0x0L); + case 123: + return jjStopAtPos(0, 62); + case 125: + return jjStopAtPos(0, 63); + default : + return jjMoveNfa_0(0, 0); + } +} +private int jjMoveStringLiteralDfa1_0(long active0, long active1) +{ + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(0, active0, active1); + return 1; + } + switch(curChar) + { + case 42: + if ((active1 & 0x40000L) != 0L) + return jjStopAtPos(1, 82); + break; + case 43: + if ((active1 & 0x4000L) != 0L) + return jjStopAtPos(1, 78); + break; + case 45: + if ((active1 & 0x8000L) != 0L) + return jjStopAtPos(1, 79); + break; + case 47: + if ((active1 & 0x80000L) != 0L) + return jjStopAtPos(1, 83); + break; + case 61: + if ((active1 & 0x80L) != 0L) + return jjStopAtPos(1, 71); + else if ((active1 & 0x200L) != 0L) + return jjStopAtPos(1, 73); + else if ((active1 & 0x400L) != 0L) + return jjStopAtPos(1, 74); + else if ((active1 & 0x800000L) != 0L) + return jjStopAtPos(1, 87); + break; + case 62: + if ((active1 & 0x800L) != 0L) + return jjStopAtPos(1, 75); + break; + case 94: + if ((active1 & 0x200000L) != 0L) + return jjStopAtPos(1, 85); + break; + case 97: + return jjMoveStringLiteralDfa2_0(active0, 0x442000000440L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa2_0(active0, 0x800000000042100L, active1, 0L); + case 102: + if ((active0 & 0x80000000L) != 0L) + return jjStartNfaWithStates_0(1, 31, 2); + break; + case 104: + return jjMoveStringLiteralDfa2_0(active0, 0x880010000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa2_0(active0, 0x10000000000820L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa2_0(active0, 0x403118010L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa2_0(active0, 0x1000000000L, active1, 0L); + case 110: + if ((active0 & 0x20000000000L) != 0L) + { + jjmatchedKind = 41; + jjmatchedPos = 1; + } + return jjMoveStringLiteralDfa2_0(active0, 0x84010840004200L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa2_0(active0, 0x421108000201080L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa2_0(active0, 0x20000L, active1, 0L); + case 113: + return jjMoveStringLiteralDfa2_0(active0, 0x200000000000L, active1, 0L); + case 114: + if ((active0 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(1, 22, 2); + return jjMoveStringLiteralDfa2_0(active0, 0x8000220000000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa2_0(active0, 0x80000L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa2_0(active0, 0x800000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa2_0(active0, 0x10000010c000000L, active1, 0L); + case 120: + return jjMoveStringLiteralDfa2_0(active0, 0x242000000000000L, active1, 0L); + case 121: + return jjMoveStringLiteralDfa2_0(active0, 0x4000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(0, active0, active1); +} +private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(0, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(1, active0, 0L); + return 2; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa3_0(active0, 0x400000000L); + case 98: + return jjMoveStringLiteralDfa3_0(active0, 0x100000000000000L); + case 99: + return jjMoveStringLiteralDfa3_0(active0, 0x800002040000400L); + case 100: + if ((active0 & 0x200L) != 0L) + return jjStartNfaWithStates_0(2, 9, 2); + else if ((active0 & 0x800000000L) != 0L) + return jjStartNfaWithStates_0(2, 35, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x180L); + case 101: + return jjMoveStringLiteralDfa3_0(active0, 0x80030020000L); + case 103: + return jjMoveStringLiteralDfa3_0(active0, 0x10L); + case 105: + return jjMoveStringLiteralDfa3_0(active0, 0x800000000000L); + case 108: + return jjMoveStringLiteralDfa3_0(active0, 0x40L); + case 110: + return jjMoveStringLiteralDfa3_0(active0, 0x25108004004800L); + case 111: + return jjMoveStringLiteralDfa3_0(active0, 0x408000001010000L); + case 112: + return jjMoveStringLiteralDfa3_0(active0, 0x82005000002000L); + case 114: + if ((active0 & 0x200000L) != 0L) + return jjStartNfaWithStates_0(2, 21, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x440000800000L); + case 115: + return jjMoveStringLiteralDfa3_0(active0, 0x2188020L); + case 116: + if ((active0 & 0x1000L) != 0L) + return jjStartNfaWithStates_0(2, 12, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x250000108040000L); + case 117: + return jjMoveStringLiteralDfa3_0(active0, 0x210200000000L); + default : + break; + } + return jjStartNfa_0(1, active0, 0L); +} +private int jjMoveStringLiteralDfa3_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(1, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(2, active0, 0L); + return 3; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa4_0(active0, 0x2240060000800L); + case 99: + return jjMoveStringLiteralDfa4_0(active0, 0x5000020L); + case 101: + if ((active0 & 0x8000L) != 0L) + { + jjmatchedKind = 15; + jjmatchedPos = 3; + } + else if ((active0 & 0x200000000L) != 0L) + return jjStartNfaWithStates_0(3, 33, 2); + else if ((active0 & 0x4000000000L) != 0L) + return jjStartNfaWithStates_0(3, 38, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x24400000a980180L); + case 104: + if ((active0 & 0x400L) != 0L) + return jjStartNfaWithStates_0(3, 10, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x10000000000000L); + case 107: + return jjMoveStringLiteralDfa4_0(active0, 0x2000000000L); + case 108: + return jjMoveStringLiteralDfa4_0(active0, 0x100800000002000L); + case 109: + return jjMoveStringLiteralDfa4_0(active0, 0x10000000000L); + case 110: + if ((active0 & 0x10000000L) != 0L) + return jjStartNfaWithStates_0(3, 28, 2); + else if ((active0 & 0x80000000000L) != 0L) + return jjStartNfaWithStates_0(3, 43, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x108000000000L); + case 111: + return jjMoveStringLiteralDfa4_0(active0, 0x800001000004010L); + case 112: + if ((active0 & 0x400000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 58, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x100000000L); + case 114: + return jjMoveStringLiteralDfa4_0(active0, 0x20000L); + case 115: + return jjMoveStringLiteralDfa4_0(active0, 0x21000400000040L); + case 116: + return jjMoveStringLiteralDfa4_0(active0, 0x8400000000000L); + case 117: + return jjMoveStringLiteralDfa4_0(active0, 0x80000000040000L); + case 119: + if ((active0 & 0x10000L) != 0L) + return jjStartNfaWithStates_0(3, 16, 2); + break; + default : + break; + } + return jjStartNfa_0(2, active0, 0L); +} +private int jjMoveStringLiteralDfa4_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(2, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(3, active0, 0L); + return 4; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa5_0(active0, 0x2000822000L); + case 99: + return jjMoveStringLiteralDfa5_0(active0, 0x100L); + case 101: + if ((active0 & 0x40L) != 0L) + return jjStartNfaWithStates_0(4, 6, 2); + else if ((active0 & 0x800000000000L) != 0L) + return jjStartNfaWithStates_0(4, 47, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x8118000000000L); + case 105: + return jjMoveStringLiteralDfa5_0(active0, 0x110400000100000L); + case 107: + if ((active0 & 0x1000000L) != 0L) + return jjStartNfaWithStates_0(4, 24, 2); + else if ((active0 & 0x20000000L) != 0L) + return jjStartNfaWithStates_0(4, 29, 2); + break; + case 108: + if ((active0 & 0x80L) != 0L) + return jjStartNfaWithStates_0(4, 7, 2); + else if ((active0 & 0x800L) != 0L) + return jjStartNfaWithStates_0(4, 11, 2); + break; + case 109: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L); + case 110: + return jjMoveStringLiteralDfa5_0(active0, 0x42000000000000L); + case 112: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000L); + case 114: + if ((active0 & 0x8000000L) != 0L) + return jjStartNfaWithStates_0(4, 27, 2); + else if ((active0 & 0x4000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 50, 2); + return jjMoveStringLiteralDfa5_0(active0, 0xa000010000c0030L); + case 115: + if ((active0 & 0x400000000L) != 0L) + return jjStartNfaWithStates_0(4, 34, 2); + break; + case 116: + if ((active0 & 0x80000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 55, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x21200004004000L); + case 117: + return jjMoveStringLiteralDfa5_0(active0, 0x100000000L); + case 119: + return jjMoveStringLiteralDfa5_0(active0, 0x2000000L); + default : + break; + } + return jjStartNfa_0(3, active0, 0L); +} +private int jjMoveStringLiteralDfa5_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(3, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(4, active0, 0L); + return 5; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa6_0(active0, 0x1400000004000L); + case 99: + if ((active0 & 0x100000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 56, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x8108000002000L); + case 100: + if ((active0 & 0x800000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 59, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x42000000000000L); + case 101: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000020L); + case 102: + if ((active0 & 0x100000L) != 0L) + return jjStartNfaWithStates_0(5, 20, 2); + break; + case 103: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000000L); + case 104: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000L); + case 105: + return jjMoveStringLiteralDfa6_0(active0, 0x200004000010L); + case 108: + return jjMoveStringLiteralDfa6_0(active0, 0x100L); + case 109: + if ((active0 & 0x800000L) != 0L) + return jjStartNfaWithStates_0(5, 23, 2); + break; + case 110: + if ((active0 & 0x40000L) != 0L) + return jjStartNfaWithStates_0(5, 18, 2); + else if ((active0 & 0x10000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 52, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x200000000000000L); + case 114: + return jjMoveStringLiteralDfa6_0(active0, 0x20010000000000L); + case 115: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000L); + case 116: + if ((active0 & 0x80000L) != 0L) + return jjStartNfaWithStates_0(5, 19, 2); + else if ((active0 & 0x100000000L) != 0L) + return jjStartNfaWithStates_0(5, 32, 2); + else if ((active0 & 0x1000000000L) != 0L) + return jjStartNfaWithStates_0(5, 36, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x20000L); + default : + break; + } + return jjStartNfa_0(4, active0, 0L); +} +private int jjMoveStringLiteralDfa6_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(4, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(5, active0, 0L); + return 6; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa7_0(active0, 0x222010000000100L); + case 101: + if ((active0 & 0x2000000000L) != 0L) + return jjStartNfaWithStates_0(6, 37, 2); + return jjMoveStringLiteralDfa7_0(active0, 0x2002000L); + case 108: + if ((active0 & 0x400000000000L) != 0L) + return jjStartNfaWithStates_0(6, 46, 2); + break; + case 110: + return jjMoveStringLiteralDfa7_0(active0, 0x1000000000000L); + case 111: + return jjMoveStringLiteralDfa7_0(active0, 0x200004020000L); + case 115: + if ((active0 & 0x40000000000000L) != 0L) + return jjStartNfaWithStates_0(6, 54, 2); + break; + case 116: + if ((active0 & 0x8000000000L) != 0L) + { + jjmatchedKind = 39; + jjmatchedPos = 6; + } + return jjMoveStringLiteralDfa7_0(active0, 0x8140000004030L); + case 117: + return jjMoveStringLiteralDfa7_0(active0, 0x40000000L); + default : + break; + } + return jjStartNfa_0(5, active0, 0L); +} +private int jjMoveStringLiteralDfa7_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(5, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(6, active0, 0L); + return 7; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa8_0(active0, 0x2000L); + case 98: + return jjMoveStringLiteralDfa8_0(active0, 0x2000000000000L); + case 101: + if ((active0 & 0x20L) != 0L) + return jjStartNfaWithStates_0(7, 5, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x8040000000000L); + case 104: + return jjMoveStringLiteralDfa8_0(active0, 0x10L); + case 105: + return jjMoveStringLiteralDfa8_0(active0, 0x20000000004000L); + case 108: + if ((active0 & 0x200000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 57, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x40000000L); + case 110: + if ((active0 & 0x2000000L) != 0L) + return jjStartNfaWithStates_0(7, 25, 2); + else if ((active0 & 0x4000000L) != 0L) + return jjStartNfaWithStates_0(7, 26, 2); + else if ((active0 & 0x200000000000L) != 0L) + return jjStartNfaWithStates_0(7, 45, 2); + break; + case 111: + return jjMoveStringLiteralDfa8_0(active0, 0x100000000000L); + case 114: + if ((active0 & 0x20000L) != 0L) + return jjStartNfaWithStates_0(7, 17, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x100L); + case 116: + if ((active0 & 0x1000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 48, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x10000000000L); + default : + break; + } + return jjStartNfa_0(6, active0, 0L); +} +private int jjMoveStringLiteralDfa8_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(6, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(7, active0, 0L); + return 8; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa9_0(active0, 0x40000000L); + case 98: + return jjMoveStringLiteralDfa9_0(active0, 0x2000L); + case 100: + if ((active0 & 0x8000000000000L) != 0L) + return jjStartNfaWithStates_0(8, 51, 2); + break; + case 101: + if ((active0 & 0x100L) != 0L) + return jjStartNfaWithStates_0(8, 8, 2); + break; + case 105: + return jjMoveStringLiteralDfa9_0(active0, 0x10000000000L); + case 108: + return jjMoveStringLiteralDfa9_0(active0, 0x2000000000000L); + case 109: + if ((active0 & 0x10L) != 0L) + return jjStartNfaWithStates_0(8, 4, 2); + break; + case 110: + return jjMoveStringLiteralDfa9_0(active0, 0x20000000000000L); + case 111: + return jjMoveStringLiteralDfa9_0(active0, 0x4000L); + case 114: + if ((active0 & 0x40000000000L) != 0L) + return jjStartNfaWithStates_0(8, 42, 2); + else if ((active0 & 0x100000000000L) != 0L) + return jjStartNfaWithStates_0(8, 44, 2); + break; + default : + break; + } + return jjStartNfa_0(7, active0, 0L); +} +private int jjMoveStringLiteralDfa9_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(7, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(8, active0, 0L); + return 9; + } + switch(curChar) + { + case 101: + if ((active0 & 0x2000000000000L) != 0L) + return jjStartNfaWithStates_0(9, 49, 2); + return jjMoveStringLiteralDfa10_0(active0, 0x20000000000000L); + case 108: + return jjMoveStringLiteralDfa10_0(active0, 0x2000L); + case 110: + if ((active0 & 0x4000L) != 0L) + return jjStartNfaWithStates_0(9, 14, 2); + break; + case 111: + return jjMoveStringLiteralDfa10_0(active0, 0x10000000000L); + case 116: + return jjMoveStringLiteralDfa10_0(active0, 0x40000000L); + default : + break; + } + return jjStartNfa_0(8, active0, 0L); +} +private int jjMoveStringLiteralDfa10_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(8, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(9, active0, 0L); + return 10; + } + switch(curChar) + { + case 100: + return jjMoveStringLiteralDfa11_0(active0, 0x20000000000000L); + case 101: + if ((active0 & 0x2000L) != 0L) + return jjStartNfaWithStates_0(10, 13, 2); + return jjMoveStringLiteralDfa11_0(active0, 0x40000000L); + case 110: + if ((active0 & 0x10000000000L) != 0L) + return jjStartNfaWithStates_0(10, 40, 2); + break; + default : + break; + } + return jjStartNfa_0(9, active0, 0L); +} +private int jjMoveStringLiteralDfa11_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(9, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(10, active0, 0L); + return 11; + } + switch(curChar) + { + case 98: + return jjMoveStringLiteralDfa12_0(active0, 0x20000000000000L); + case 100: + if ((active0 & 0x40000000L) != 0L) + return jjStartNfaWithStates_0(11, 30, 2); + break; + default : + break; + } + return jjStartNfa_0(10, active0, 0L); +} +private int jjMoveStringLiteralDfa12_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(10, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(11, active0, 0L); + return 12; + } + switch(curChar) + { + case 121: + if ((active0 & 0x20000000000000L) != 0L) + return jjStartNfaWithStates_0(12, 53, 2); + break; + default : + break; + } + return jjStartNfa_0(11, active0, 0L); +} +private int jjStartNfaWithStates_0(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_0(state, pos + 1); +} +static final long[] jjbitVec0 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +private int jjMoveNfa_0(int startState, int curPos) +{ + int startsAt = 0; + jjnewStateCnt = 34; + int i = 1; + jjstateSet[0] = startState; + int kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + do + { + switch(jjstateSet[--i]) + { + case 0: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 91) + kind = 91; + jjCheckNAddStates(0, 4); + } + else if ((0x100002600L & l) != 0L) + { + if (kind > 1) + kind = 1; + } + else if (curChar == 47) + jjAddStates(5, 6); + else if (curChar == 46) + jjCheckNAdd(12); + else if (curChar == 34) + jjCheckNAddStates(7, 9); + else if (curChar == 39) + jjCheckNAddTwoStates(4, 5); + break; + case 16: + if (curChar == 47) + { + if (kind > 3) + kind = 3; + jjCheckNAdd(23); + } + else if (curChar == 42) + jjCheckNAddStates(10, 12); + break; + case 2: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 88) + kind = 88; + jjstateSet[jjnewStateCnt++] = 2; + break; + case 3: + if (curChar == 39) + jjCheckNAddTwoStates(4, 5); + break; + case 4: + if ((0xaffffc8300001100L & l) != 0L) + jjCheckNAddTwoStates(4, 5); + break; + case 5: + if (curChar == 39 && kind > 89) + kind = 89; + break; + case 6: + if (curChar == 34) + jjCheckNAddStates(7, 9); + break; + case 7: + if ((0xfffffffbfffffbffL & l) != 0L) + jjCheckNAddStates(7, 9); + break; + case 9: + if ((0xfffffffffffffbffL & l) != 0L) + jjCheckNAddStates(7, 9); + break; + case 10: + if (curChar == 34 && kind > 90) + kind = 90; + break; + case 11: + if (curChar == 46) + jjCheckNAdd(12); + break; + case 12: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjCheckNAddTwoStates(12, 13); + break; + case 14: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjstateSet[jjnewStateCnt++] = 14; + break; + case 15: + if (curChar == 47) + jjAddStates(5, 6); + break; + case 17: + if ((0xfffffbffffffffffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 18: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 19; + break; + case 19: + if ((0xffff7fffffffffffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 20: + if (curChar == 47 && kind > 2) + kind = 2; + break; + case 21: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 20; + break; + case 22: + if (curChar != 47) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(23); + break; + case 23: + if ((0xfffffffffffffbffL & l) == 0L) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(23); + break; + case 24: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAddStates(0, 4); + break; + case 25: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAdd(25); + break; + case 26: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(26, 27); + break; + case 27: + if (curChar != 46) + break; + if (kind > 92) + kind = 92; + jjCheckNAddTwoStates(28, 29); + break; + case 28: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjCheckNAddTwoStates(28, 29); + break; + case 30: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjstateSet[jjnewStateCnt++] = 30; + break; + case 31: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(31, 32); + break; + case 33: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjstateSet[jjnewStateCnt++] = 33; + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 0: + case 2: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 88) + kind = 88; + jjCheckNAdd(2); + break; + case 4: + if ((0x47fffffed7ffffffL & l) != 0L) + jjAddStates(13, 14); + break; + case 7: + if ((0xffffffffefffffffL & l) != 0L) + jjCheckNAddStates(7, 9); + break; + case 8: + if (curChar == 92) + jjstateSet[jjnewStateCnt++] = 9; + break; + case 9: + jjCheckNAddStates(7, 9); + break; + case 13: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 14; + break; + case 17: + case 19: + jjCheckNAddStates(10, 12); + break; + case 23: + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 23; + break; + case 29: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 30; + break; + case 32: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 33; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 7: + case 9: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddStates(7, 9); + break; + case 17: + case 19: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddStates(10, 12); + break; + case 23: + if ((jjbitVec0[i2] & l2) == 0L) + break; + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 23; + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 34 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +static final int[] jjnextStates = { + 25, 26, 27, 31, 32, 16, 22, 7, 8, 10, 17, 18, 21, 4, 5, +}; + +/** Token literal values. */ +public static final String[] jjstrLiteralImages = { +"", null, null, null, "\141\154\147\157\162\151\164\150\155", +"\144\151\163\143\162\145\164\145", "\146\141\154\163\145", "\155\157\144\145\154", +"\162\145\144\145\143\154\141\162\145", "\141\156\144", "\145\141\143\150", "\146\151\156\141\154", "\156\157\164", +"\162\145\160\154\141\143\145\141\142\154\145", "\141\156\156\157\164\141\164\151\157\156", "\145\154\163\145", +"\146\154\157\167", "\157\160\145\162\141\164\157\162", "\162\145\164\165\162\156", +"\141\163\163\145\162\164", "\145\154\163\145\151\146", "\146\157\162", "\157\162", +"\163\164\162\145\141\155", "\142\154\157\143\153", "\145\154\163\145\167\150\145\156", +"\146\165\156\143\164\151\157\156", "\157\165\164\145\162", "\164\150\145\156", "\142\162\145\141\153", +"\145\156\143\141\160\163\165\154\141\164\145\144", "\151\146", "\157\165\164\160\165\164", "\164\162\165\145", +"\143\154\141\163\163", "\145\156\144", "\151\155\160\157\162\164", "\160\141\143\153\141\147\145", +"\164\171\160\145", "\143\157\156\156\145\143\164", +"\145\156\165\155\145\162\141\164\151\157\156", "\151\156", "\160\141\162\141\155\145\164\145\162", "\167\150\145\156", +"\143\157\156\156\145\143\164\157\162", "\145\161\165\141\164\151\157\156", "\160\141\162\164\151\141\154", +"\167\150\151\154\145", "\143\157\156\163\164\141\156\164", +"\145\170\160\141\156\144\141\142\154\145", "\151\156\156\145\162", "\160\162\157\164\145\143\164\145\144", +"\167\151\164\150\151\156", "\143\157\156\163\164\162\141\151\156\145\144\142\171", +"\145\170\164\145\156\144\163", "\151\156\160\165\164", "\160\165\142\154\151\143", +"\145\170\164\145\162\156\141\154", "\154\157\157\160", "\162\145\143\157\162\144", "\50", "\51", "\173", "\175", +"\133", "\135", "\56", "\72", "\73", "\54", "\74", "\74\75", "\76", "\76\75", +"\75\75", "\74\76", "\53", "\55", "\56\53", "\56\55", "\52", "\57", "\56\52", "\56\57", +"\136", "\56\136", "\75", "\72\75", null, null, null, null, null, }; + +/** Lexer state names. */ +public static final String[] lexStateNames = { + "DEFAULT", +}; +static final long[] jjtoToken = { + 0xfffffffffffffff1L, 0x1fffffffL, +}; +static final long[] jjtoSkip = { + 0xeL, 0x0L, +}; +protected SimpleCharStream input_stream; +private final int[] jjrounds = new int[34]; +private final int[] jjstateSet = new int[68]; +private final StringBuilder jjimage = new StringBuilder(); +private StringBuilder image = jjimage; +private int jjimageLen; +private int lengthOfMatch; +protected char curChar; +/** Constructor. */ +public ExpressionParserTokenManager(SimpleCharStream stream){ + if (SimpleCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + input_stream = stream; +} + +/** Constructor. */ +public ExpressionParserTokenManager(SimpleCharStream stream, int lexState){ + this(stream); + SwitchTo(lexState); +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream) +{ + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); +} +private void ReInitRounds() +{ + int i; + jjround = 0x80000001; + for (i = 34; i-- > 0;) + jjrounds[i] = 0x80000000; +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream, int lexState) +{ + ReInit(stream); + SwitchTo(lexState); +} + +/** Switch to specified lex state. */ +public void SwitchTo(int lexState) +{ + if (lexState >= 1 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); + else + curLexState = lexState; +} + +protected Token jjFillToken() +{ + final Token t; + final String curTokenImage; + final int beginLine; + final int endLine; + final int beginColumn; + final int endColumn; + String im = jjstrLiteralImages[jjmatchedKind]; + curTokenImage = (im == null) ? input_stream.GetImage() : im; + beginLine = input_stream.getBeginLine(); + beginColumn = input_stream.getBeginColumn(); + endLine = input_stream.getEndLine(); + endColumn = input_stream.getEndColumn(); + t = Token.newToken(jjmatchedKind); + t.kind = jjmatchedKind; + t.image = curTokenImage; + + t.beginLine = beginLine; + t.endLine = endLine; + t.beginColumn = beginColumn; + t.endColumn = endColumn; + + return t; +} + +int curLexState = 0; +int defaultLexState = 0; +int jjnewStateCnt; +int jjround; +int jjmatchedPos; +int jjmatchedKind; + +/** Get the next Token. */ +public Token getNextToken() +{ + Token matchedToken; + int curPos = 0; + + EOFLoop : + for (;;) + { + try + { + curChar = input_stream.BeginToken(); + } + catch(java.io.IOException e) + { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + } + image = jjimage; + image.setLength(0); + jjimageLen = 0; + + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + if (jjmatchedKind != 0x7fffffff) + { + if (jjmatchedPos + 1 < curPos) + input_stream.backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) + { + matchedToken = jjFillToken(); + TokenLexicalActions(matchedToken); + return matchedToken; + } + else + { + continue EOFLoop; + } + } + int error_line = input_stream.getEndLine(); + int error_column = input_stream.getEndColumn(); + String error_after = null; + boolean EOFSeen = false; + try { input_stream.readChar(); input_stream.backup(1); } + catch (java.io.IOException e1) { + EOFSeen = true; + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + if (curChar == '\n' || curChar == '\r') { + error_line++; + error_column = 0; + } + else + error_column++; + } + if (!EOFSeen) { + input_stream.backup(1); + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + } + throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); + } +} + +void TokenLexicalActions(Token matchedToken) +{ + switch(jjmatchedKind) + { + case 90 : + image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); + matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); + break; + default : + break; + } +} +private void jjCheckNAdd(int state) +{ + if (jjrounds[state] != jjround) + { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } +} +private void jjAddStates(int start, int end) +{ + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); +} +private void jjCheckNAddTwoStates(int state1, int state2) +{ + jjCheckNAdd(state1); + jjCheckNAdd(state2); +} + +private void jjCheckNAddStates(int start, int end) +{ + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); +} + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ParseException.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ParseException.java new file mode 100644 index 00000000..c5c3b5f2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ParseException.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.expressionParser; + +/** + * This exception is thrown when parse errors are encountered. + * You can explicitly create objects of this exception type by + * calling the method generateParseException in the generated + * parser. + * + * You can modify this class to customize your error reporting + * mechanisms so long as you retain the public fields. + */ +public class ParseException extends Exception { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * This constructor is used by the method "generateParseException" + * in the generated parser. Calling this constructor generates + * a new object of this type with the fields "currentToken", + * "expectedTokenSequences", and "tokenImage" set. + */ + public ParseException(Token currentTokenVal, + int[][] expectedTokenSequencesVal, + String[] tokenImageVal + ) + { + super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal)); + currentToken = currentTokenVal; + expectedTokenSequences = expectedTokenSequencesVal; + tokenImage = tokenImageVal; + } + + /** + * The following constructors are for use by you for whatever + * purpose you can think of. Constructing the exception in this + * manner makes the exception behave in the normal way - i.e., as + * documented in the class "Throwable". The fields "errorToken", + * "expectedTokenSequences", and "tokenImage" do not contain + * relevant information. The JavaCC generated code does not use + * these constructors. + */ + + public ParseException() { + super(); + } + + /** Constructor with message. */ + public ParseException(String message) { + super(message); + } + + + /** + * This is the last token that has been consumed successfully. If + * this object has been created due to a parse error, the token + * followng this token will (therefore) be the first error token. + */ + public Token currentToken; + + /** + * Each entry in this array is an array of integers. Each array + * of integers represents a sequence of tokens (by their ordinal + * values) that is expected at this point of the parse. + */ + public int[][] expectedTokenSequences; + + /** + * This is a reference to the "tokenImage" array of the generated + * parser within which the parse error occurred. This array is + * defined in the generated ...Constants interface. + */ + public String[] tokenImage; + + /** + * It uses "currentToken" and "expectedTokenSequences" to generate a parse + * error message and returns it. If this object has been created + * due to a parse error, and you do not catch it (it gets thrown + * from the parser) the correct error message + * gets displayed. + */ + private static String initialise(Token currentToken, + int[][] expectedTokenSequences, + String[] tokenImage) { + String eol = System.getProperty("line.separator", "\n"); + StringBuffer expected = new StringBuffer(); + int maxSize = 0; + for (int i = 0; i < expectedTokenSequences.length; i++) { + if (maxSize < expectedTokenSequences[i].length) { + maxSize = expectedTokenSequences[i].length; + } + for (int j = 0; j < expectedTokenSequences[i].length; j++) { + expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); + } + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + expected.append("..."); + } + expected.append(eol).append(" "); + } + String retval = "Encountered \""; + Token tok = currentToken.next; + for (int i = 0; i < maxSize; i++) { + if (i != 0) retval += " "; + if (tok.kind == 0) { + retval += tokenImage[0]; + break; + } + retval += " " + tokenImage[tok.kind]; + retval += " \""; + retval += add_escapes(tok.image); + retval += " \""; + tok = tok.next; + } + retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; + retval += "." + eol; + if (expectedTokenSequences.length == 1) { + retval += "Was expecting:" + eol + " "; + } else { + retval += "Was expecting one of:" + eol + " "; + } + retval += expected.toString(); + return retval; + } + + /** + * The end of line string for this machine. + */ + protected String eol = System.getProperty("line.separator", "\n"); + + /** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal. + */ + static String add_escapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + +} +/* JavaCC - OriginalChecksum=65dcbd31a9e7a053287ebf70e24f8b8f (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/SimpleCharStream.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/SimpleCharStream.java new file mode 100644 index 00000000..ae8e144a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/SimpleCharStream.java @@ -0,0 +1,480 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.expressionParser; + +/** + * An implementation of interface CharStream, where the stream is assumed to + * contain only ASCII characters (without unicode processing). + */ + +public class SimpleCharStream +{ +/** Whether parser is static. */ + public static final boolean staticFlag = false; + int bufsize; + int available; + int tokenBegin; +/** Position in buffer. */ + public int bufpos = -1; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int inBuf = 0; + protected int tabSize = 8; + + protected void setTabSize(int i) { tabSize = i; } + protected int getTabSize(int i) { return tabSize; } + + + protected void ExpandBuff(boolean wrapAround) + { + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try + { + if (wrapAround) + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos += (bufsize - tokenBegin)); + } + else + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos -= tokenBegin); + } + } + catch (Throwable t) + { + throw new Error(t.getMessage()); + } + + + bufsize += 2048; + available = bufsize; + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException + { + if (maxNextCharInd == available) + { + if (available == bufsize) + { + if (tokenBegin > 2048) + { + bufpos = maxNextCharInd = 0; + available = tokenBegin; + } + else if (tokenBegin < 0) + bufpos = maxNextCharInd = 0; + else + ExpandBuff(false); + } + else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + int i; + try { + if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1) + { + inputStream.close(); + throw new java.io.IOException(); + } + else + maxNextCharInd += i; + return; + } + catch(java.io.IOException e) { + --bufpos; + backup(0); + if (tokenBegin == -1) + tokenBegin = bufpos; + throw e; + } + } + +/** Start. */ + public char BeginToken() throws java.io.IOException + { + tokenBegin = -1; + char c = readChar(); + tokenBegin = bufpos; + + return c; + } + + protected void UpdateLineColumn(char c) + { + column++; + + if (prevCharIsLF) + { + prevCharIsLF = false; + line += (column = 1); + } + else if (prevCharIsCR) + { + prevCharIsCR = false; + if (c == '\n') + { + prevCharIsLF = true; + } + else + line += (column = 1); + } + + switch (c) + { + case '\r' : + prevCharIsCR = true; + break; + case '\n' : + prevCharIsLF = true; + break; + case '\t' : + column--; + column += (tabSize - (column % tabSize)); + break; + default : + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + +/** Read a character. */ + public char readChar() throws java.io.IOException + { + if (inBuf > 0) + { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + if (++bufpos >= maxNextCharInd) + FillBuff(); + + char c = buffer[bufpos]; + + UpdateLineColumn(c); + return c; + } + + @Deprecated + /** + * @deprecated + * @see #getEndColumn + */ + + public int getColumn() { + return bufcolumn[bufpos]; + } + + @Deprecated + /** + * @deprecated + * @see #getEndLine + */ + + public int getLine() { + return bufline[bufpos]; + } + + /** Get token end column number. */ + public int getEndColumn() { + return bufcolumn[bufpos]; + } + + /** Get token end line number. */ + public int getEndLine() { + return bufline[bufpos]; + } + + /** Get token beginning column number. */ + public int getBeginColumn() { + return bufcolumn[tokenBegin]; + } + + /** Get token beginning line number. */ + public int getBeginLine() { + return bufline[tokenBegin]; + } + +/** Backup a number of characters. */ + public void backup(int amount) { + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length) + { + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + bufpos = -1; + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, 1, 1, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, startline, startcolumn, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + /** Get token literal value. */ + public String GetImage() + { + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + else + return new String(buffer, tokenBegin, bufsize - tokenBegin) + + new String(buffer, 0, bufpos + 1); + } + + /** Get the suffix. */ + public char[] GetSuffix(int len) + { + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else + { + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, + len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + /** Reset buffer when finished. */ + public void Done() + { + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + */ + public void adjustBeginLineColumn(int newLine, int newCol) + { + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin) + { + len = bufpos - tokenBegin + inBuf + 1; + } + else + { + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k = 0; + int nextColDiff = 0, columnDiff = 0; + + while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) + { + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len) + { + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while (i++ < len) + { + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + +} +/* JavaCC - OriginalChecksum=c766a5138ab7879b8b98d46681a242b8 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/TestExpressionParser.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/TestExpressionParser.java new file mode 100644 index 00000000..35225c26 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/TestExpressionParser.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.expressionParser; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.List; + +public class TestExpressionParser { + + static private ExpressionParser parser; + + public static void parse(String string) { + parser.ReInit(new StringReader(string)); + try { + parser.expr(); + HashMap> references = parser.getReferences(); + for(String ref : references.keySet()) { + System.out.println(ref); + } + } catch (ParseException e) { + System.out.println("While parsing " + string + ":"); + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public static void main(String[] args) { + parser = new ExpressionParser( + new StringReader("") + ); + parse("1 + m2ma"); + System.out.println("##"); + parse("ter2e + moro"); + System.out.println("##"); + parse("moro * sqr(4.0) + min(m2ma, moi)"); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/Token.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/Token.java new file mode 100644 index 00000000..9cce5690 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/Token.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.expressionParser; + +/** + * Describes the input token stream. + */ + +public class Token implements java.io.Serializable, Comparable { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** The line number of the first character of this Token. */ + public int beginLine; + /** The column number of the first character of this Token. */ + public int beginColumn; + /** The line number of the last character of this Token. */ + public int endLine; + /** The column number of the last character of this Token. */ + public int endColumn; + + /** + * The string image of the token. + */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** + * An optional attribute value of the Token. + * Tokens which are not used as syntactic sugar will often contain + * meaningful values that will be used later on by the compiler or + * interpreter. This attribute value is often different from the image. + * Any subclass of Token that actually wants to return a non-null value can + * override this method as appropriate. + */ + public Object getValue() { + return null; + } + + /** + * No-argument constructor + */ + public Token() {} + + /** + * Constructs a new token for the specified Image. + */ + public Token(int kind) + { + this(kind, null); + } + + /** + * Constructs a new token for the specified Image and Kind. + */ + public Token(int kind, String image) + { + this.kind = kind; + this.image = image; + } + + /** + * Returns the image. + */ + public String toString() + { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simply add something like : + * + * case MyParserConstants.ID : return new IDToken(ofKind, image); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use sit in your lexical actions. + */ + public static Token newToken(int ofKind, String image) + { + switch(ofKind) + { + default : return new Token(ofKind, image); + } + } + + public static Token newToken(int ofKind) + { + return newToken(ofKind, null); + } + + @Override + public int compareTo(Token o) { + if (this.beginLine < o.beginLine) + return -1; + if (this.beginLine > o.beginLine) + return 1; + else { + if (this.beginColumn < o.beginColumn) + return -1; + if (this.beginColumn > o.beginColumn) + return 1; + return 0; + } + } + +} +/* JavaCC - OriginalChecksum=ed7a6d865f7fbc2c64e008e34bd824b0 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/TokenMgrError.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/TokenMgrError.java new file mode 100644 index 00000000..db380412 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/TokenMgrError.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.expressionParser; + +/** Token Manager Error. */ +public class TokenMgrError extends Error +{ + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** + * Lexical error occurred. + */ + static final int LEXICAL_ERROR = 0; + + /** + * An attempt was made to create a second instance of a static token manager. + */ + static final int STATIC_LEXER_ERROR = 1; + + /** + * Tried to change to an invalid lexical state. + */ + static final int INVALID_LEXICAL_STATE = 2; + + /** + * Detected (and bailed out of) an infinite loop in the token manager. + */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + + /** + * Replaces unprintable characters by their escaped (or unicode escaped) + * equivalents in the given string + */ + protected static final String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + + /** + * Returns a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + * Parameters : + * EOFSeen : indicates if EOF caused the lexical error + * curLexState : lexical state in which this error occurred + * errorLine : line number when the error occurred + * errorColumn : column number when the error occurred + * errorAfter : prefix that was seen before this error occurred + * curchar : the offending character + * Note: You can customize the lexical error message by modifying this method. + */ + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { + return("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * + * "Internal Error : Please file a bug report .... " + * + * from this method for such cases in the release version of your parser. + */ + public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + /** No arg constructor. */ + public TokenMgrError() { + } + + /** Constructor with message and reason. */ + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + /** Full Constructor. */ + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); + } +} +/* JavaCC - OriginalChecksum=24b6b4792f62099f85bde9ed73a49451 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/ActiveResults.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/ActiveResults.java new file mode 100644 index 00000000..6ae1b035 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/ActiveResults.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.util.ArrayList; +import java.util.Collection; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; + +public class ActiveResults implements Read>{ + + private Resource resource; + + public ActiveResults(Resource resource) { + this.resource = resource; + } + + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + ModelingResources MR = ModelingResources.getInstance(graph); + + Collection result = new ArrayList(); + + Collection experiments; + if(graph.isInstanceOf(resource, MR.StructuralModel)) + experiments = graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, SR.Experiment)); + else { + experiments = new ArrayList(); + experiments.add(resource); + } + + for(Resource experiment : experiments) { + Collection experimentResults = graph.getObjects(experiment, SR.Experiment_result); + for(Resource r : experimentResults) { + if(graph.hasStatement(r, SR.Result_showResult)) { + result.add(r); + } + } + Collection experimentResultSets = graph.getObjects(experiment, SR.Experiment_resultSet); + for(Resource resultSet : experimentResultSets) { + experimentResults = graph.getObjects(resultSet, SR.Experiment_result); + for(Resource r : experimentResults) { + if(graph.hasStatement(r, SR.Result_showResult)) { + result.add(r); + } + } + } + } + + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/FileResult.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/FileResult.java new file mode 100644 index 00000000..e685e8d4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/FileResult.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.io.File; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.simantics.databoard.Accessors; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.accessor.Accessor; +import org.simantics.databoard.accessor.MapAccessor; +import org.simantics.databoard.accessor.RecordAccessor; +import org.simantics.databoard.accessor.binary.BinaryRecord; +import org.simantics.databoard.accessor.binary.BinaryVariant; +import org.simantics.databoard.accessor.error.AccessorConstructionException; +import org.simantics.databoard.accessor.error.AccessorException; +import org.simantics.databoard.accessor.reference.ChildReference; +import org.simantics.databoard.accessor.reference.ComponentReference; +import org.simantics.databoard.accessor.reference.IndexReference; +import org.simantics.databoard.accessor.reference.KeyReference; +import org.simantics.databoard.accessor.reference.NameReference; +import org.simantics.databoard.binding.mutable.Variant; + +public class FileResult extends SysdynResult { + + private RecordAccessor accessor; + + /** + * Open result from a file + * + * @param result Name of the result (seen in visualization) + * @param path file path + */ + public FileResult(String resultName, String path) { + super(resultName); + File file = new File(path); + try { + BinaryVariant bv = (BinaryVariant)Accessors.openAccessor(file); + BinaryRecord br = bv.getContentAccessor(); + accessor = br; + } catch (AccessorConstructionException e) { + e.printStackTrace(); + } + } + + /** + * Get the {@link RecordAccessor} of this result + * @return {@link RecordAccessor} for this result + */ + public Accessor getAccessor() { + return accessor; + } + + + /** + * Get dataset for a named variable from accessor + * @param variable The name of the variable + * @return {@link SysdynDataSet} + */ + @Override + public SysdynDataSet getDataSet(String variable) { + if(accessor != null) { + synchronized(accessor) { + ChildReference ref = ChildReference.compile( + new NameReference("recordings"), + new KeyReference( Bindings.VARIANT, Variant.ofInstance(variable) ), + new ComponentReference(), + new NameReference("segments"), + new IndexReference(0) + ); + MapAccessor ma; + try { + ma = accessor.getComponent( ref ); + } catch (AccessorConstructionException e) { + return null; + } + + try { + int size = ma.size(); + Double[] times = new Double[size]; + Double[] values = new Double[size]; + + ma.getAll(Bindings.DOUBLE, Bindings.DOUBLE, times, values); + + double[] times_ = new double[size]; + double[] values_ = new double[size]; + for (int i=0; i getLibraryPathsForModelica(final SysdynExperiment experiment) { + try { + return Simantics.getSession().syncRequest(new Read>() { + @Override + public List perform(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + List paths = new ArrayList(); + for(Resource parent : getParents(graph, experiment.getModel(), true)) { + if(graph.isInstanceOf(parent, sr.SysdynModel)) { + String modelName = NameUtils.getSafeName(graph, parent); + paths.add(modelName + "_functions.mo"); + } else { + String libraryName = NameUtils.getSafeName(graph, parent); + paths.add("..\\\\\\\\..\\\\\\\\libraries\\\\\\\\functions\\\\\\\\" + libraryName + ".mo"); + } + } + return paths; + } + }); + } + catch (DatabaseException e) { + e.printStackTrace(); + return null; + } + } + + public static void updateFunctionFilesForExperiment(final SysdynExperiment experiment) { + try { + Simantics.getSession().syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + for (Resource parent : getParents(graph, experiment.getModel(), false)) { + if(graph.isInstanceOf(parent, sr.SysdynModel)) { + String parentName = NameUtils.getSafeName(graph, parent); + File scriptFile = new File(experiment.getExperimentDir(), parentName + "_functions.mo"); + updateFunctionFile(graph, parent, scriptFile, false); + } else { + updateFunctionFileForLibrary(graph, parent); + } + } + + } + }); + } + catch (DatabaseException e) { + e.printStackTrace(); + } + } + + private static Set getParents(ReadGraph graph, Resource model, boolean ignoreEmpty) + throws DatabaseException{ + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + Set parents = new HashSet(); + + if(model == null) { + return parents; + } + + parents.add(model); + + for(Resource r : graph.getObjects(model, l0.IsLinkedTo)) { + if(graph.isInstanceOf(r, sr.SharedFunctionOntology)) { + parents.add(r); + } else { + if(!graph.syncRequest(new ObjectsWithType(r, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary)).isEmpty()) { + parents.add(r); + } + } + } + + if(ignoreEmpty) { + Set nonEmptyParents = new HashSet(); + for(Resource parent : parents) { + if(isNonEmpty(graph, parent)) { + nonEmptyParents.add(parent); + } + } + parents = nonEmptyParents; + } + + return parents; + } + + private static boolean isNonEmpty(ReadGraph graph, Resource library) + throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + if(!graph.syncRequest(new ObjectsWithType(library, l0.ConsistsOf, sr.SysdynModelicaFunction)).isEmpty()) { + return true; + } else { + for(Resource l : graph.syncRequest(new ObjectsWithType(library, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))) { + if(isNonEmpty(graph, l)) { + return true; + } + } + } + + return false; + } + + private static void updateFunctionFile(ReadGraph graph, Resource library, File scriptFile, boolean builtIn) + throws DatabaseException { + PrintStream s; + try { + s = new PrintStream(scriptFile); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return; + } + + SysdynResource sr = SysdynResource.getInstance(graph); + + String name = NameUtils.getSafeName(graph, library); + + if(!builtIn && !graph.isInstanceOf(library, sr.SysdynModel)) { + s.println("package " + name); + } + writeLibrary(graph, library, scriptFile, s, builtIn); + if(!builtIn && !graph.isInstanceOf(library, sr.SysdynModel)) { + s.println("end " + name + ";\n"); + } + + s.close(); + } + + private static void updateFunctionFileForLibrary(ReadGraph graph, Resource library) + throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + + while(!graph.isInstanceOf(library, l0.Ontology)) { + library = graph.getSingleObject(library, l0.PartOf); + } + + File librariesDir = Activator.getBundleContext().getDataFile("libraries"); + if (!librariesDir.exists()) { + librariesDir.mkdir(); + } + File dir = new File(librariesDir, "functions"); + if (!dir.exists()) { + dir.mkdir(); + } + + String parentName = NameUtils.getSafeName(graph, library); + File scriptFile = new File(dir, parentName + ".mo"); + + Resource sysdyn = graph.getResource("http://www.simantics.org/Sysdyn-1.1"); + + if(library.equals(sysdyn)) { + updateFunctionFile(graph, library, scriptFile, true); + } else { + updateFunctionFile(graph, library, scriptFile, false); + } + + } + + private static void writeLibrary(ReadGraph graph, Resource library, File scriptFile, PrintStream stream, boolean builtIn) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + writeLibraryFunctions(graph, library, scriptFile, stream); + for(Resource sublibrary : graph.syncRequest(new ObjectsWithType(library, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))) { + String name = NameUtils.getSafeName(graph, sublibrary); + if(!builtIn) + stream.println("encapsulated package " + name); + writeLibrary(graph, sublibrary, scriptFile, stream, builtIn); + if(!builtIn) + stream.println("end " + name + ";\n"); + } + } + + private static void writeLibraryFunctions(ReadGraph graph, Resource library, File scriptFile, PrintStream stream) + throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + for(Resource function : graph.syncRequest(new ObjectsWithType(library, l0.ConsistsOf, sr.SysdynModelicaFunction))) { + String name = NameUtils.getSafeName(graph, function); + // Built-in Modelica (array) functions have no function code and they don't need to be added explicitly. + String functionCode = graph.getPossibleRelatedValue(function, sr.SysdynModelicaFunction_modelicaFunctionCode); + if (functionCode == null) { + continue; + } + stream.println("function " + name); + stream.println(functionCode); + stream.println("end " + name + ";\n"); + for(Resource externalFunction : graph.syncRequest(new ObjectsWithType(function, l0.ConsistsOf, sr.ExternalFunctionFile))) { + createExternalFunctionFile(graph, externalFunction, scriptFile); + } + } + } + + private static void createExternalFunctionFile(ReadGraph graph, Resource externalFunction, File scriptFile) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + File dir = scriptFile.getParentFile(); + + if(!dir.exists()) + dir.mkdir(); + + if(!dir.isDirectory()) + return; + + try { + String name = NameUtils.getSafeName(graph, externalFunction); + if(name.endsWith(".o") || name.endsWith(".a")) { + FileOutputStream fos = new FileOutputStream(dir + File.separator + name); + byte[] fileBArray = graph.getPossibleRelatedValue(externalFunction, sr.ExternalFunctionFile_externalFile, Bindings.BYTE_ARRAY); + fos.write(fileBArray); + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/HistoryDatasetResult.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/HistoryDatasetResult.java new file mode 100644 index 00000000..9805a7cb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/HistoryDatasetResult.java @@ -0,0 +1,324 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - Bug #4180 + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.io.File; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.modelica.data.DataSet; +import org.simantics.modelica.data.SimulationResult; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.spreadsheet.SheetVariables; +import org.simantics.spreadsheet.common.matrix.VariantMatrix; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.utils.IndexUtils; +import org.simantics.utils.datastructures.Pair; + +/** + * A result built from a spreadsheet table. Imitates a normal simulation result for + * easy display on charts and tables. + * + * @author Teemu Lempinen + * + */ +public class HistoryDatasetResult extends SimulationResult { + @Override + public void read(File file, int interval) {} // Do nothing + @Override + public void read(InputStream stream, int interval) {} // Do nothing + + private boolean disposed; + + /** + * Dispose listeners of this result. It is important to dispose all listeners + * when they are not needed anymore. + */ + public void disposeListeners() { + this.disposed = true; + } + + /** + * Reads history data to this result. Location of the data is described in historyData resource. + * + * @param sysdynResult MemoryResult to which this simulation result is read + * @param historyData Resource describing the history data to be read from a spreadsheet + */ + public void read(final MemoryResult sysdynResult, final Resource historyData) { + + Simantics.getSession().asyncRequest(new Read>>() { + + @Override + public Pair> perform(ReadGraph graph) throws DatabaseException { + ArrayList variables = new ArrayList(); + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + SimulationResource simu = SimulationResource.getInstance(graph); + + String datasetName = "History Dataset"; + VariantMatrix vm = null; + SysdynModel sdmodel = null; + String timeVariable = "time"; + boolean columns = true; + try { + Pair> emptyResult = new Pair>(sdmodel, variables); + + + // Find the SysdynModel of this historyData + Resource model = graph.getPossibleObject(historyData, l0.PartOf); + Resource config = graph.getPossibleObject(model, simu.HasConfiguration); + sdmodel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, config); + sdmodel.update(graph); + + // Find properties of the result: name, sheet, range, time variable, orientation + datasetName = NameUtils.getSafeLabel(graph, historyData); + + + Resource sheet = graph.getPossibleObject(historyData, sr.HistoryDataset_sheet); + if(sheet == null) + return emptyResult; + + String start = graph.getPossibleRelatedValue(historyData, sr.HistoryDataset_start); + String end = graph.getPossibleRelatedValue(historyData, sr.HistoryDataset_end); + if(start == null || start.isEmpty() || end == null || end.isEmpty()) + return emptyResult; + String r = start + ":" + end; + + String time = graph.getPossibleRelatedValue(historyData, sr.HistoryDataset_timeName); + if(time != null && !time.isEmpty()) + timeVariable = time; + + if(graph.hasStatement(historyData, sr.HistoryDataset_columns)) + columns = graph.getRelatedValue(historyData, sr.HistoryDataset_columns, Bindings.BOOLEAN); + + // Find the sheet variable + Variable v = graph.adapt(sheet, Variable.class); + Variable range = v.getChild(graph, r); + if(range == null) + return emptyResult; + + // Find the content of the range + Variant content = range.getPropertyValue(graph, SheetVariables.CONTENT, Bindings.VARIANT); + Object matrixValue = content.getValue(); + if(matrixValue instanceof VariantMatrix) { + vm = (VariantMatrix)matrixValue; + } + + } catch(DatabaseException e) { + return new Pair>(sdmodel, variables); + } catch(NegativeArraySizeException e) { + // Negative array size may be result of mofifying start and end variables + return new Pair>(sdmodel, variables); + } + + + // Orientation + int x = columns ? vm.getColumnCount() : vm.getRowCount(); + int y = columns ? vm.getRowCount() : vm.getColumnCount(); + + /* + * The table needs at least: + * + * headers for variables + one value + * two variables (of which one is time-variable) + * + * => minimum of 2x2 matrix + */ + if(vm == null || x < 2 || y < 2) + return new Pair>(sdmodel, variables); + + String[] names = new String[x]; + HashMap>> values = new HashMap>>(); + Integer timeIndex = null; + + // Find variable names + for(int i = 0; i < x ; i++) { + Variant cell = columns ? vm.get(0, i) : vm.get(i, 0); + if(cell != null && cell.getValue() != null) { + String name = cell.getValue().toString(); + if(!values.containsKey(name)) { + names[i] = name; + values.put(names[i], new ArrayList>()); + + // Time column index + if(names[i].equals(timeVariable)) + timeIndex = i; + } + } else { + names[i] = null; + } + } + + // If times were not found, return empty + if(timeIndex == null || names[timeIndex] == null) + return new Pair>(sdmodel, variables); + + // Get time column ready first + for(int i = 1; i < y; i++) { + Variant cell = columns ? vm.get(i, timeIndex) : vm.get(timeIndex, i); + Double value = null; + if(cell != null) + value = getDoubleValue(cell); + values.get(names[timeIndex]).add(new Pair(value, value)); // add also null-values + } + + // Get variable values column by column (or row by row + for(int i = 0; i < x; i++) { + if(i == timeIndex || names[i] == null) + continue; + + for(int j = 1; j < y; j++) { + Variant cell = columns ? vm.get(j, i) : vm.get(i, j); + if(cell != null && cell.getValue() != null) { + Double value = getDoubleValue(cell); + if(value != null) { + Pair time = values.get(names[timeIndex]).get(j - 1); + if(time != null && time.first != null) { + values.get(names[i]).add( + new Pair( + time.first, + value) + ); + } + } + } + } + + ArrayList> doubles = values.get(names[i]); + + String name = names[i]; + // If the variable has array indexes, they need to be converted to numbers + if(name.contains("[")) { + org.simantics.sysdyn.representation.Variable variable = getVariable(name, sdmodel.getConfiguration()); + if(variable != null) + name = IndexUtils.equationRangesToIndexes(variable, name); + } + + // Replace spaces with '_'. That is how they are stored elsewhere + name = name.replace(" ", "_"); + + // Read values to SysdynDataSet + SysdynDataSet ds = new SysdynDataSet(name, datasetName, new double[doubles.size()], new double[doubles.size()]); + variables.add(ds); + for(int d = 0; d < doubles.size(); d++) { + Pair pair = doubles.get(d); + ds.times[d] = pair.first; + ds.values[d] = pair.second; + } + } + return new Pair>(sdmodel, variables); + } + + }, new Listener>>() { + + @Override + public void execute(Pair> result) { + // Update result set and send message to model that results have been changed + HistoryDatasetResult.this.variables = result.second; + sysdynResult.setResult(HistoryDatasetResult.this); + if(result.first != null) + result.first.resultChanged(); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return disposed; + } + }); + + + } + + /** + * Finds a variable defined by path starting from configuration + * @param path Path of the variable + * @param configuration Configuration where to look for the variable + * @return Variable + */ + private org.simantics.sysdyn.representation.Variable getVariable(String path, Configuration configuration) { + String next = path; + int index = next.indexOf("."); + + // If path has commas, we are looking for a module + if(index > 0) { + path = path.substring(index + 1); + next = next.substring(0, index); + } else { + // No commas, we are looking for a variable + if(next.contains("[")) + // Variable has array indexes, remove the array indexes + next = next.substring(0, next.indexOf("[")); + } + + for(IElement e : configuration.getElements()) { + if(e instanceof org.simantics.sysdyn.representation.Variable) { + org.simantics.sysdyn.representation.Variable v = (org.simantics.sysdyn.representation.Variable) e; + if(v.getName().equals(next)) { + return v; // found the variable + } + } else if(e instanceof Module && ((Module)e).getName().equals(next)) { + return getVariable(path, ((Module)e).getType().getConfiguration()); // Recursive call with a shorter path + } + } + return null; + } + + /** + * Finds the double value from a spreadsheet cell. + * @param cell Cell where to look for + * @return Double value of the cell or null if not double or if empty + */ + private Double getDoubleValue(Variant cell) { + if(cell.getValue() == null) + return null; + + Double value = null; + try { + value = Double.parseDouble(cell.getValue().toString()); + } catch (NumberFormatException e) { + } + return value; + } + + @Override + public DataSet getDataSet(String name) { + DataSet ds = super.getDataSet(name); + if(ds == null && name.contains(".")) { + ds = super.getDataSet(name.substring(name.lastIndexOf(".") + 1)); + } + return ds; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/HistoryDatasetUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/HistoryDatasetUtils.java new file mode 100644 index 00000000..e164c81b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/HistoryDatasetUtils.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.util.ArrayList; +import java.util.List; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.spreadsheet.SheetVariables; +import org.simantics.spreadsheet.common.matrix.VariantMatrix; +import org.simantics.sysdyn.SysdynResource; + +public class HistoryDatasetUtils { + + public static List getVariableNamesInRange(ReadGraph graph, Resource historyData) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + + ArrayList values = new ArrayList(); + + + Resource sheet = graph.getPossibleObject(historyData, sr.HistoryDataset_sheet); + if(sheet == null) + return values; + + String start = graph.getPossibleRelatedValue(historyData, sr.HistoryDataset_start); + String end = graph.getPossibleRelatedValue(historyData, sr.HistoryDataset_end); + if(start == null || start.isEmpty() || end == null || end.isEmpty()) + return values; + String r = start + ":" + end; + + if(!graph.hasStatement(historyData, sr.HistoryDataset_columns)) + return values; + + boolean columns = graph.getRelatedValue(historyData, sr.HistoryDataset_columns, Bindings.BOOLEAN); + + Variable v = graph.adapt(sheet, Variable.class); + Variable range = v.getChild(graph, r); + if(range == null) + return values; + + Variant content = range.getPropertyValue(graph, SheetVariables.CONTENT, Bindings.VARIANT); + Object matrixValue = content.getValue(); + if(!(matrixValue instanceof VariantMatrix)) + return values; + + VariantMatrix vm = (VariantMatrix)matrixValue; + + /* + * The table needs at least: + * + * headers for variables + one value + * two variables (of which one is time-variable) + * + * => minimum of 2x2 matrix + */ + + int x = columns ? vm.getColumnCount() : vm.getRowCount(); + int y = columns ? vm.getRowCount() : vm.getColumnCount(); + + if(vm == null || x < 2 || y < 2) + return values; + + + // Names + for(int i = 0; i < x ; i++) { + Variant cell = columns ? vm.get(0, i) : vm.get(i, 0); + if(cell != null && cell.getValue() != null) { + String name = cell.getValue().toString(); + if(!values.contains(name)) { + values.add(name); + } + } + } + + return values; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/MemoryResult.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/MemoryResult.java new file mode 100644 index 00000000..ded4dd63 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/MemoryResult.java @@ -0,0 +1,249 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import gnu.trove.map.hash.THashMap; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.TreeMap; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.simantics.databoard.Accessors; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Datatypes; +import org.simantics.databoard.Files; +import org.simantics.databoard.accessor.MapAccessor; +import org.simantics.databoard.accessor.RecordAccessor; +import org.simantics.databoard.accessor.error.AccessorConstructionException; +import org.simantics.databoard.accessor.java.JavaRecord; +import org.simantics.databoard.annotations.Arguments; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.RecordBinding; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.databoard.type.Datatype; +import org.simantics.modelica.data.DataSet; +import org.simantics.modelica.data.SimulationResult; + +// TODO: rename to OpenModelicaResult or something as this is very specific? +public class MemoryResult extends SysdynResult { + + private THashMap results; + private File resultFile; + private Integer resultIndex = null; + private SimulationResult simulationResult; + + + /** + * Create a sysdynresult accessor using a {@link SimulationResult} + * @param result + */ + public MemoryResult(SimulationResult result, String resultName) { + super(resultName); + + results = new THashMap(); + + if(result != null) + setResult(result); + + } + + @Override + public SysdynDataSet getDataSet(String variable) { + // Try to get cached result + SysdynDataSet result = results.get(variable); + if(result != null) + return result; + + // if not found, try to read it + SimulationResult simulationResult = getSimulationResult(); + try { + if (simulationResult != null) { + DataSet ds = simulationResult.getDataSet(variable); + if(ds == null) + ds = simulationResult.readVariable(variable, resultFile); + + if(ds != null) { + SysdynDataSet sds = new SysdynDataSet(ds.name, getResultName(), ds.times, ds.values, resultIndex); + results.put(variable, sds); + return sds; + } + } + } catch (FileNotFoundException e1) { + // Unable to read data from OpenModelica result file + System.err.println("Variable " + variable + " not found in OpenModelica result file"); + return null; + } catch (IOException e1) { + // IoFail + e1.printStackTrace(); + } + + return null; + } + + public void setResultFile(File resFile) { + this.resultFile = resFile; + } + + public int numberOfVariables() { + return simulationResult.getVariableDataSets().size(); + } + + public void setResult(SimulationResult result) { + this.simulationResult = result; + this.results.clear(); + if(result != null) + addAllInitialValues(result); // For legacy reasons + } + + private SimulationResult getSimulationResult() { + return this.simulationResult; + } + + + + /** + * Read all results from their DataSets. --- Legacy init file support. Not needed with mat files. + */ + private void addAllInitialValues(SimulationResult result) { + // Add initial values + for(DataSet ds : result.getInitialValueDataSets()){ + SysdynDataSet sds = new SysdynDataSet(ds.name, getResultName(), ds.times, ds.values); + results.put(ds.name, sds); + } + } + + + /** + * Save current {@link RecordAccessor} to a {@link File} + * + * @param file {@link File} where the {@link RecordAccessor} is saved + */ + @Override + public void saveToFile(File file, IProgressMonitor progressMonitor) { + try { + // Create Memory Historian + Datatype recordingSessionType = Datatypes.getDatatype("RecordingSession"); + RecordBinding sessionBinding = (RecordBinding) Bindings.getBinding( recordingSessionType ); + Object session = sessionBinding.createDefault(); + JavaRecord accessor = (JavaRecord) Accessors.getAccessor( sessionBinding, session ); + + // Get binding and value from memory + JavaRecord jr = (JavaRecord) accessor; + Binding binding = jr.getBinding(); + Object value = jr.getObject(); + + // Read the missing variables one by one. + getSimulationResult().readMissingVariables(this.resultFile); + + addAllDataSetsToAccessor(accessor, progressMonitor); + // Write to file + if (progressMonitor != null) { + progressMonitor.subTask("Save results"); + } + Files.createFile(file, binding, value); + + // The division is made so that 1 unit per variable and their sum for saving them. + progressMonitor.worked(numberOfVariables()); + } catch (IOException e) { + e.printStackTrace(); + } catch (BindingException e) { + e.printStackTrace(); + } catch (AccessorConstructionException e) { + e.printStackTrace(); + } + + } + + + /** + * Read all results from their DataSets. + * @param progressMonitor + */ + private void addAllDataSetsToAccessor(JavaRecord accessor, IProgressMonitor progressMonitor) { + try { + MapAccessor recordings = accessor.getFieldAccessor("recordings"); + + // There is a recording for each variable + List datasets = getSimulationResult().getVariableDataSets(); + RecordBinding recordingBinding = (RecordBinding) Bindings.getBinding( Recording.class ); + if (progressMonitor != null) { + progressMonitor.subTask("Prepare saving"); + } + // Add variables + for(DataSet ds : datasets){ + if (progressMonitor != null) { + progressMonitor.worked(1); + } + // Add recording to session, if not already added + Variant dsNodeId = Variant.ofInstance( ds.name ); + if (recordings.containsKey(Bindings.VARIANT, dsNodeId)) + continue; + + Recording recording = createRecording(ds); + recordings.put(Bindings.VARIANT, recording.nodeId, Bindings.VARIANT, new Variant(recordingBinding, recording)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Create a recording for a variable to this result's {@link RecordAccessor} + * @param ds {@link DataSet} for the variable + * @return {@link Recording} + * @throws BindingException + */ + @SuppressWarnings("unchecked") + Recording createRecording(DataSet ds) throws BindingException { + RecordBinding recordingBinding = (RecordBinding) Bindings.getBindingUnchecked( Recording.class ); + Recording recording = (Recording) recordingBinding.createDefault(); + recording.nodeId = Variant.ofInstance( ds.name ); + recording.labels.put("en", ds.name); + + // Create one segment + TreeMap segment = new TreeMap(); + recording.segments = new TreeMap[] { segment }; + + int length = ds.values.length; + for (int i=0; i labels; + public @Arguments({TreeMap.class, Double.class, Double.class}) TreeMap[] segments; + } + + /** + * Set the index of the run; used when the individual time series of a variable are shown in + * the same JFreeChart. + * @param currentRun The index of the run + */ + public void setResultIndex(int resultIndex) { + this.resultIndex = resultIndex; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java new file mode 100644 index 00000000..87d62c8b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java @@ -0,0 +1,874 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - Bug #4180 + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import gnu.trove.set.hash.THashSet; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.locks.Lock; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.osgi.service.prefs.Preferences; +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.VirtualGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.layer0.Layer0; +import org.simantics.modelica.IModelicaMonitor; +import org.simantics.modelica.ModelicaException; +import org.simantics.modelica.ModelicaKeys; +import org.simantics.modelica.ModelicaManager; +import org.simantics.modelica.SimulationLocation; +import org.simantics.modelica.data.CSVSimulationResult; +import org.simantics.modelica.data.MatSimulationResult; +import org.simantics.modelica.data.SimulationResult; +import org.simantics.modelica.preferences.OpenModelicaPreferences; +import org.simantics.simulation.data.Datasource; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperimentListener; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.Activator; +import org.simantics.sysdyn.adapter.VariableValueSubscription; +import org.simantics.sysdyn.modelica.ModelicaWriter; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.Model; +import org.simantics.sysdyn.simulation.SimulationScheduler; + +public class OldSysdynExperiment extends SysdynExperiment { + + protected Session session; + protected Runnable modificationListener; + protected SysdynModel sysdynModel; + protected boolean toggled = false; + @SuppressWarnings("rawtypes") + protected THashSet variableValueSubscriptions = new THashSet(); + @SuppressWarnings("rawtypes") + protected volatile VariableValueSubscription[] variableValueSubscriptionsSnapshot = null; + + protected String previousModelStructure; + protected HashMap previousParameters; + protected Process process; + protected boolean canceled = false; + protected ExperimentState sysdynExperimentState; + + private SysdynResult result; + private File simulationDir; + + protected String experimentName; + protected static String omcVersion = null; + protected static String omcHome = null; + + public static OldSysdynExperiment INSTANCE; + + public OldSysdynExperiment(Resource experiment, Resource model) { + super(experiment, model); + INSTANCE = this; + } + + public static OldSysdynExperiment getInstance() { + return INSTANCE; + } + + public SysdynResult getCurrentResult() { + if(this.result == null) + this.result = new MemoryResult(null, null); + return this.result; + } + + public Collection getActiveResults() { + ArrayList result = new ArrayList(); + if(getCurrentResult() != null) + result.add(getCurrentResult()); + result.addAll(sysdynModel.getDisplayedResults()); + return result; + } + + /** + * Initialize this experiment + * @param g ReadGraph + */ + public void init(ReadGraph g) { + try { + this.experimentName = NameUtils.getSafeName(g, experiment); + } catch (DatabaseException e) { + this.experimentName = "Experiment"; + } + + this.session = g.getSession(); + state = ExperimentState.STOPPED; + for(IExperimentListener listener : listeners.getListeners()) + listener.stateChanged(state); + + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + final Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration); + sysdynModel = SysdynModelManager.getInstance(session).getModel(graph, configuration); + toggleActivation(graph, true); + } + }); + + setSysdynExperimentState(ExperimentState.INITIALIZING); + } + + @Override + public void saveState() { + if(result == null || !(result instanceof MemoryResult)) + return; + // TODO: temporary fix + SaveResultJob saveResultJob = new SaveResultJob(OldSysdynExperiment.this, session, (MemoryResult)result); + saveResultJob.schedule(); + } + + protected Thread getSaveThread(final SysdynResult result, final File file, final IProgressMonitor progressMonitor) { + return new Thread() { + @Override + public void run() { + if(!canceled) { + // Get and store results result.saveToFile(file, progressMonitor); + } } + }; + } + + /** + * Starts a simulation job. Use this method to start a simulation. + */ + @Override + public void simulate(boolean enabled) { + if(enabled && sysdynModel != null) { + if(!ExperimentState.RUNNING.equals(getState())) { + changeState(ExperimentState.RUNNING); + startSimulationJob(); + } + } else if (!toggled){ + changeState(ExperimentState.STOPPED); + } + } + + /** + * Starts a simulation job + */ + protected void startSimulationJob() { + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + SimulationScheduler.start(sysdynModel, OldSysdynExperiment.this); + } + }); + } + + + /** + * Write model configuration to a single Modelica code + * @param monitor + * @param isGame is the experiment a "game experiment". This is needed for modifying the code to work with FMU simulation + * @return Modelica code + */ + protected String getModelicaCode(IModelicaMonitor monitor, boolean isGame, String modelicaVersion) { + String modelText = null; + try { + // Write all configurations once + modelText = ModelicaWriter.write(sysdynModel.getModules(), isGame, modelicaVersion); + } catch (Exception e) { + // Stop experiment and show console + /*setExperimentStopped(experiment); =>*/ simulate(false); + monitor.showConsole(); + monitor.message("Error when writing Modelica code."); + } + return modelText; + } + + /** + * Get all inits and parameter values required for the inits -file + * @param monitor + * @return All inits in a map + */ + protected HashMap getExperimentParameters(IModelicaMonitor monitor) { + Configuration configuration = sysdynModel.getConfiguration(); +// HashMap inits = sysdynModel.getInits(configuration, ""); Not needed anymore, whole xml content is replaced + HashMap parameters = new HashMap(); + Model model = configuration.getModel(); + Double startTime = model.getStartTime(); + Double stopTime = model.getStopTime(); + parameters.put(ModelicaKeys.START_VALUE, startTime.toString()); + parameters.put(ModelicaKeys.STOP_VALUE, stopTime.toString()); + String outputFormat = "mat"; + parameters.put(ModelicaKeys.OUTPUT_FORMAT, outputFormat); + + Double simulationStepLength = model.getSimulationStepLength(); + if(simulationStepLength != null) { + parameters.put(ModelicaKeys.STEP_VALUE, simulationStepLength.toString()); + parameters.put(ModelicaKeys.NUMBER_OF_INTERVALS, "" + ((int)((stopTime - startTime) / simulationStepLength))); + } else { + parameters.put(ModelicaKeys.STEP_VALUE, "" + (stopTime - startTime) / 500); + } + + Double outputInterval = model.getOutputInterval(); + parameters.put(ModelicaKeys.OUTPUT_INTERVAL, outputInterval != null ? outputInterval.toString() : parameters.get(ModelicaKeys.STEP_VALUE)); + + String method = "\"" + model.getSolver() + "\""; + parameters.put(ModelicaKeys.METHOD, method); + if(model.getTolerance() != null) + parameters.put(ModelicaKeys.TOLERANCE, model.getTolerance().toString()); + String variableFilter = model.getVariableFilter(); + if(variableFilter != null && !variableFilter.isEmpty()) + parameters.put(ModelicaKeys.VARIABLE_FILTER, variableFilter); + return parameters; + } + + /** + * Builds a model + * @param simulationLocation + * @param inits + * @param modelText + * @param monitor + */ + protected void buildModel(SimulationLocation simulationLocation, IModelicaMonitor monitor) { + + try { + simulationLocation.executableFile.delete(); + ModelicaManager.buildModel(simulationLocation, monitor); + } catch (ModelicaException e) { + if(e.getMessage() != null) + monitor.message(e.getMessage()); + monitor.showConsole(); + canceled = true; + previousModelStructure = ""; + previousParameters = null; + } + } + + /** + * Run a built model + * @param structureChanged + * @throws IOException + */ + protected void runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, IProgressMonitor progressMonitor, HashMap experimentParameters, HashMap changes) throws IOException { + progressMonitor.subTask("Simulate model"); + process = ModelicaManager.runModelica( + simulationLocation, + monitor, + experimentParameters, + changes + ); + ModelicaManager.printProcessOutput(process, monitor); + + Thread resultThread = getResultThread(simulationLocation, experimentParameters, monitor, progressMonitor); + resultThread.run(); + + process = null; + } + + /** + * Get a thread for reading and saving reuslts from a normal simulation + * @param simulationLocation + * @param inits + * @param monitor + * @param progressMonitor + * @return + */ + protected Thread getResultThread(final SimulationLocation simulationLocation, final HashMap experimentParameters, final IModelicaMonitor monitor, final IProgressMonitor progressMonitor) { + return new Thread() { + @Override + public void run() { + try { + process.waitFor(); + + if(!canceled) { + // Get and store results + progressMonitor.worked(1); + progressMonitor.subTask("Read results"); + SimulationResult result; + if(simulationLocation.resultFile.getName().endsWith(".csv")) + result = new CSVSimulationResult(); + else if(simulationLocation.resultFile.getName().endsWith(".plt")) + result = new SimulationResult(); + else + result = new MatSimulationResult(); // The latest format + + // The interval of results saved. Every result? Every other result? etc... + int outIntervalInt = 1; + String outputInterval = experimentParameters.get(ModelicaKeys.OUTPUT_INTERVAL); + if(outputInterval != null) { + String stepTime = experimentParameters.get(ModelicaKeys.STEP_VALUE); + String stopTime = experimentParameters.get(ModelicaKeys.STOP_VALUE); + + Double step = Double.parseDouble(stepTime); + Double stop = Double.parseDouble(stopTime); + Double outInterval = Double.parseDouble(outputInterval); + + outIntervalInt = (int)getInterval(outInterval, step); + // Actually you might be able to use an outInterval one or two longer. + int maxIntervalInt = (int)Math.round(stop / step); + if (outIntervalInt > maxIntervalInt) + outIntervalInt = maxIntervalInt; + } + + result.initRead(simulationLocation.resultFile); + result.readTime(simulationLocation.resultFile, outIntervalInt); + //result.readInits(simulationLocation.initFile); // Parameter values are read from .mat + result.filter(); + ((MemoryResult)getCurrentResult()).setResult(result); + ((MemoryResult)getCurrentResult()).setResultFile(simulationLocation.resultFile); + progressMonitor.worked(1); + resultsChanged(); + + simulate(false); + + String errorString = result.getResultReadErrors(); + if(errorString != null && !errorString.isEmpty()) + monitor.message(errorString); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + } + + protected static long getInterval(double outputLength, double stepLength) { + double interval = outputLength / stepLength; + if (interval <= 1) + return 1; + return Math.round(interval); + } + + + /** + * + * @param sysdynModel + * @param modelText + * @param inits + * @param additionalScript + * @return + * @throws IOException + */ + protected SimulationLocation createSimulationFiles(SysdynModel sysdynModel, String modelText, HashMap inits, String additionalScript, boolean fmu) throws IOException { + File simulationDir = getExperimentDir(); + + // update all function files. both the model's and built-in + FunctionUtils.updateFunctionFilesForExperiment(this); + + + SimulationLocation location = ModelicaManager.createSimulationLocation(simulationDir, sysdynModel.getConfiguration().getLabel(), modelText); + if (fmu) { + ModelicaManager.createFMUSimulationScripts(location, inits, additionalScript); + } + else { + ModelicaManager.createSimulationScripts(location, inits, additionalScript); + } + return location; + } + + /** + * Get a simulation directory for this model + * @return File directory + */ + public File getExperimentDir() { + if(simulationDir == null) { + File modelsDir = Activator.getBundleContext().getDataFile("models"); + String experimentName = this.experimentName; + List files = Arrays.asList(modelsDir.list()); + if (files.contains(experimentName)) { + int i = 2; + while (files.contains(experimentName + "_" + i)){ + i++; + } + experimentName += "_" + i; + } + + simulationDir = Activator.getBundleContext().getDataFile("models/" + experimentName); + if (!simulationDir.exists()) { + simulationDir.mkdir(); + } + } + return simulationDir; + } + + /** + * + * @return + */ + protected String getAdditionalScripts() { + StringBuilder functionscript = new StringBuilder(); + for(String path : FunctionUtils.getLibraryPathsForModelica(this)) { + functionscript.append("loadFile(\"" + path + "\");\n"); + } + return functionscript.toString(); + } + + /** + * Starts simulating a model. Call only from inside simulation job! Start simulation using simulate(true). + * @param monitor + * @param progressMonitor + * @throws IOException + */ + public synchronized void simulate(final IModelicaMonitor monitor, final IProgressMonitor progressMonitor, String modelName) throws IOException { + canceled = false; + progressMonitor.subTask("Write modelica classes"); + + omcVersion = ModelicaManager.getDefaultOMVersion(); + + monitor.message("Simulate " + modelName + " using OpenModelica " + omcVersion); + + // Get Modelica code + String modelText = getModelicaCode(monitor, false, omcVersion); + if(modelText == null) + return; + progressMonitor.worked(1); + + // Write initial files and add init-parameters + progressMonitor.subTask("Write simulation files"); + HashMap experimentParameters = getExperimentParameters(monitor); + + // add loadFile script to load all related functions and function libraries + String additionalScript = getAdditionalScripts(); + + // Create simulation files + SimulationLocation simulationLocation = createSimulationFiles(sysdynModel, modelText, experimentParameters, additionalScript, false); + progressMonitor.worked(1); + + // Build the model and store previous model structure and inits that affect the building + // If there is no exe file OR the model structure has not changed, no need to build + String flatModelText = ModelicaManager.getFlatModelText(simulationLocation, monitor, FunctionUtils.getLibraryPathsForModelica(this)); + boolean structureChanged = sysdynModel.isStructureModified(); + + if (!simulationLocation.executableFile.isFile() || structureChanged) { + progressMonitor.subTask("Build model"); + previousModelStructure = flatModelText; + previousParameters = ModelicaManager.getModelParameters(previousModelStructure); + + buildModel(simulationLocation, monitor); + } + + // Add changed parameters in case that structure has not changed + HashMap changes = structureChanged ? null : new HashMap(); + if(!structureChanged && previousParameters != null && omcVersion.startsWith("1.9")) { + HashMap newParameters = ModelicaManager.getModelParameters(flatModelText); + for(String key : previousParameters.keySet()) { + if(!previousParameters.get(key).equals(newParameters.get(key))) { + changes.put(key, newParameters.get(key)); + } + } + previousParameters = newParameters; + } + progressMonitor.worked(1); + + if(simulationLocation != null && !canceled) { + // Simulate the model + runModelica(simulationLocation, monitor, progressMonitor, experimentParameters, changes); + } + + if(canceled) + simulate(false); + process = null; + } + + /** + * Get the version of the OpenModelica compiler that is defined to be used + * in Preferences + * @return OpenModelica version + */ + protected String getOpenModelicaVersion() { + String omVersion = null; + + IScopeContext context = DefaultScope.INSTANCE; + Preferences node = context.getNode(org.simantics.modelica.Activator.PLUGIN_ID); + String omHome = node.get(OpenModelicaPreferences.OM_HOME, null); + if(omHome != null) { + File omHomeDir = new File(omHome); + if(omHomeDir != null && omHomeDir.isDirectory()) + omVersion = ModelicaManager.getOMVersion(omHomeDir); + } + + if(omVersion == null) { + omVersion = ModelicaManager.getDefaultOMVersion(); + } + + return omVersion; + } + + + /** + * Method that compares given modelText and inits to previous model and inits + * @param modelText Textual representation of a model (Modelica code) + * @param inits map of init parameters + * @return true if the model has changed, false otherwise + */ +// protected boolean hasStructureChanged(String modelText) { +// +// if(previousModelStructure == null) +// return true; +// +// // Then compare the actual model structure +// BufferedReader current = new BufferedReader( +// new StringReader(modelText)); +// BufferedReader previous = new BufferedReader( +// new StringReader(previousModelStructure)); +// +// String c, p; +// try { +// // Read both current and previous model texts at the same time +// c = current.readLine(); +// p = previous.readLine(); +// +// while (c != null && p != null) { +// // if the lines are the same, no need for further examination +// if(!c.equals(p)) { +// if(c.contains("parameter") && p.contains("parameter")) { +// /* +// * The line is a parameter definition. +// * In this case only what is before '=' matters +// * +// * parameter Real Var = 1; +// * is structurally same as +// * parameter Real Var = 2; +// */ +// int i = c.indexOf("="); +// if(!c.substring(0, i).equals(p.substring(0, i))) { +// // different parameter definition +// return true; +// } +// } else { +// // other than a line containing parameters differs +// return true; +// } +// } +// c = current.readLine(); +// p = previous.readLine(); +// } +// +// if((c == null && p != null) || (c != null && p == null)) { +// // different lengths +// return true; +// } +// +// } catch(IOException e) { +// // Something went wrong in the comparison, it is safer to say that the structure has changed +// return true; +// } +// return false; +// } + + /** + * Destroy an ongoing simulation process + */ + public void cancelSimulation() { + canceled = true; + if(process != null) { + process.destroy(); + } + } + + /** + * Toggle simulation state + * @param enabled true == RUNNING, false == STOPPED + */ + public void toggleSimulation(boolean enabled) { + if(enabled) { + this.toggled = true; + changeState(ExperimentState.RUNNING); + if(modificationListener == null) { + + modificationListener = new Runnable() { + + @Override + public void run() { + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + if(getState() == ExperimentState.RUNNING) { + SimulationScheduler.start(sysdynModel, OldSysdynExperiment.this); + } + + } + }); + + }; + }; + sysdynModel.addModificationListener(modificationListener); + } + } + else { + changeState(ExperimentState.STOPPED); + this.toggled = false; + } + + } + + @Override + public void refresh(RequestProcessor session) { + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + init(graph); + } + + }); + } + + @Override + public void refresh(Session session) { + refresh((RequestProcessor)session); + } + + @Override + protected void localStateChange() { + setSysdynExperimentState(getState()); + switch(state) { + case DISPOSED: + onExperimentDisposed(); + break; + default: + break; + } + + } + + /** + * Returns sysdyn experiment state. It is usually the same as ordinary experiment state. + * Initializing phase takes longer than normally in game experiments. + * @return + */ + public ExperimentState getSysdynExperimentState() { + return sysdynExperimentState; + } + + protected void setSysdynExperimentState(final ExperimentState state) { + sysdynExperimentState = state; + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); + final Session session = graph.getSession(); + session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("experiments")) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + SimulationResource SR = SimulationResource.getInstance(graph); + graph.deny(model, SR.HasExperimentState); + graph.deny(experiment, SR.HasExperimentState); + + Resource st = graph.newResource(); + switch(state) { + case INITIALIZING: + graph.claim(st, L0.InstanceOf, SR.ExperimentState_Initializing); + break; + case RUNNING: + graph.claim(st, L0.InstanceOf, SR.ExperimentState_Running); + break; + case STOPPED: + graph.claim(st, L0.InstanceOf, SR.ExperimentState_Stopped); + break; + case DISPOSED: + graph.claim(st, L0.InstanceOf, SR.ExperimentState_Disposed); + break; + } + + graph.claim(model, SR.HasExperimentState, st); + graph.claim(experiment, SR.HasExperimentState, st); + }}); + } + }); + } + + /** + * Actions performed when experiment is disposed + * @param graph + */ + protected void onExperimentDisposed() { + cancelSimulation(); + sysdynModel.removeModificationListener(modificationListener); + modificationListener = null; + + session.asyncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + toggleActivation(graph, false); + } + }); + } + + + /** + * Toggles the active-state of this experiment on or off + * @param graph ReadGraph + * @param activate The active-state of this experiment + */ + protected void toggleActivation(ReadGraph graph, final boolean activate) { + VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); + final Session session = graph.getSession(); + session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("experiments")) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + VirtualGraph runtime = graph.getService(VirtualGraph.class); + + session.asyncRequest(new WriteRequest(runtime) { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SimulationResource SIMU = SimulationResource.getInstance(graph); + if(activate) + graph.claim(experiment, SIMU.IsActive, experiment); + else + graph.denyStatement(experiment, SIMU.IsActive, experiment); + } + + }); + } + }); + } + + + /* Result subscriptions */ + + @SuppressWarnings("rawtypes") + /** + * Copy from AprosExperiment + * @param subscription + */ + @Override + public void addVariableValueSubscription(VariableValueSubscription subscription) { + assert subscription != null; + synchronized (variableValueSubscriptions) { + //System.out.println("ADD listener " + subscription); + variableValueSubscriptions.add(subscription); + variableValueSubscriptionsSnapshot = null; + } + } + + @SuppressWarnings("rawtypes") + /** + * Copy from AprosExperiment + * @param subscription + */ + @Override + public void removeVariableValueSubscription(VariableValueSubscription subscription) { + assert subscription != null; + synchronized (variableValueSubscriptions) { + //System.out.println("REMOVE listener " + subscription); + variableValueSubscriptions.remove(subscription); + variableValueSubscriptionsSnapshot = null; + } + } + + @SuppressWarnings("rawtypes") + /** + * Copy from AprosExperiment + * @return + */ + @Override + public VariableValueSubscription[] getListenerSnapshot() { + VariableValueSubscription[] snapshot = variableValueSubscriptionsSnapshot; + if (snapshot == null) { + synchronized (variableValueSubscriptions) { + snapshot = variableValueSubscriptionsSnapshot; + if (snapshot == null) { + snapshot = variableValueSubscriptionsSnapshot = variableValueSubscriptions.toArray(new VariableValueSubscription[variableValueSubscriptions.size()]); + } + } + //System.out.println("listener count: " + snapshot.length); + } + return snapshot; + } + + volatile long previousVariableUpdateTime = 0; + volatile boolean skippedVariableUpdate = true; + + + /** + * Modified copy from AprosExperiment + */ + public void resultsChanged() { + long time = System.nanoTime(); + if(time - previousVariableUpdateTime > 100000000) { + updateSubscriptions(); + previousVariableUpdateTime = time; + } + else + skippedVariableUpdate = true; + } + + @SuppressWarnings("rawtypes") + /** + * Modified copy from AporsExperiment + */ + @Override + public void updateSubscriptions() { + for(VariableValueSubscription subscription : getListenerSnapshot()) + subscription.update(); + skippedVariableUpdate = false; + } + + public int numberOfSimulationRunSteps() { + /* + * 1. Write modelica files + * 2. Write other simulation files + * 3. Build model OR update parameters + * 4. Run modelica + * 5. Read results + */ + return 5; + } + + + /* Experiment methods that are not used in this experiment */ + + @Override + public Lock getDatasourceLock() { + return null; + } + + @Override + public Datasource getDatasource() { + return null; + } + + @Override + public void simulateDuration(double duration) { + System.out.println("simulateDuartion"); + } + + + @Override + public void rewindTo(double time) { + System.out.println("rewindTo"); + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultJob.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultJob.java new file mode 100644 index 00000000..38a87e6c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultJob.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - Bug #4180 + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.io.File; +import java.util.UUID; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; + +/** + * Class for saving simulation results. + * @author Tuomas Miettinen + * + */ +public class SaveResultJob extends Job { + + private final MemoryResult sysdynResult; + private final OldSysdynExperiment experiment; + private final Session session; + private IProgressMonitor monitor; + private File file; + + public SaveResultJob(final OldSysdynExperiment experiment, Session session, final MemoryResult result) { + super("Save Result"); + this.experiment = experiment; + this.sysdynResult = result; + this.session = session; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + this.monitor = monitor; + int resultItemsNumber = sysdynResult.numberOfVariables(); + monitor.beginTask("Save result", resultItemsNumber * 2 + 1); + try { + // Create result file + file = session.syncRequest(new Read() { + + @Override + public File perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Resource model = graph.getSingleObject(experiment.getResource(), l0.PartOf); + Resource project = graph.getSingleObject(model, l0.PartOf); + String projectName = graph.getPossibleRelatedValue(project, l0.HasName); + File root = new File(Platform.getLocation().toOSString(), "www.simantics.org"); + if(!root.isDirectory()) root.mkdir(); + File projectRoot = new File(root, projectName); + if(!projectRoot.isDirectory()) projectRoot.mkdir(); + File file = new File(projectRoot, UUID.randomUUID().toString() + ".dbb"); + return file; + } + }); + + // Start the saving operation + Thread saveThread = experiment.getSaveThread(sysdynResult, file, SaveResultJob.this.monitor); + saveThread.run(); + + // Add the result under the experiment within the model browser. + session.syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Resource model = graph.getSingleObject(experiment.getResource(), l0.PartOf); + String name = NameUtils.findFreshName(graph, "Result", model, l0.ConsistsOf, "%s%d"); + + SysdynResource sr = SysdynResource.getInstance(graph); + Resource res = GraphUtils.create2(graph, sr.Result, + l0.HasLabel, name, + l0.HasName, name, + l0.PartOf, model, + sr.Result_resultFile, file.getAbsolutePath(), + sr.Result_time, System.currentTimeMillis()); + graph.claim(experiment.getResource(), sr.Experiment_result, res); + } + }); + + } catch (DatabaseException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + return new Status( + Status.ERROR, + "org.simantics.sysdyn.ui", + "Save results failed: \n" + e.getMessage()); + } + monitor.done(); + return Status.OK_STATUS; + } + + @Override + public boolean belongsTo(Object family) { + return "SaveResultJob".equals(family); + } + + @Override + protected void canceling() { + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultSetJob.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultSetJob.java new file mode 100644 index 00000000..ea2f9e62 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SaveResultSetJob.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.io.File; +import java.util.ArrayList; +import java.util.UUID; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.request.WriteResultRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; + +/** + * Class for saving simulation result sets. + * @author Tuomas Miettinen + * + */ +public class SaveResultSetJob extends Job { + + private final ArrayList sysdynResults; + private final OldSysdynExperiment experiment; + private final Session session; + private IProgressMonitor monitor; + private File file; + + public SaveResultSetJob(final OldSysdynExperiment experiment, Session session, final ArrayList results) { + super("Save Results"); + this.experiment = experiment; + this.sysdynResults = results; + this.session = session; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + this.monitor = monitor; + if (sysdynResults == null || sysdynResults.size() == 0) + return Status.CANCEL_STATUS; + int resultItemsNumber = sysdynResults.get(0).numberOfVariables() * sysdynResults.size(); + monitor.beginTask("Save results", resultItemsNumber * 2 + 2); + + try { + // Create a ResultSet, under which the individual results are stored, and + // add it under the experiment within the model browser. + + final Resource resultSetResource = session.syncRequest(new WriteResultRequest() { + + @Override + public Resource perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Resource model = graph.getSingleObject(experiment.getResource(), l0.PartOf); + String name = NameUtils.findFreshName(graph, "ResultSet", model, l0.ConsistsOf, "%s%d"); + + SysdynResource sr = SysdynResource.getInstance(graph); + Resource res = GraphUtils.create2(graph, sr.ResultSet, + l0.HasLabel, name, + l0.HasName, name, + l0.PartOf, model, + sr.Result_time, System.currentTimeMillis()); + graph.claim(experiment.getResource(), sr.Experiment_resultSet, res); + return res; + } + }); + monitor.worked(1); + + // Save the individual results + for (int i = 0; i < sysdynResults.size(); ++i) { + MemoryResult result = sysdynResults.get(i); + final String name = new Integer(i+1).toString(); + // Create result file + file = session.syncRequest(new Read() { + + @Override + public File perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Resource model = graph.getSingleObject(experiment.getResource(), l0.PartOf); + Resource project = graph.getSingleObject(model, l0.PartOf); + String projectName = graph.getPossibleRelatedValue(project, l0.HasName); + File root = new File(Platform.getLocation().toOSString(), "www.simantics.org"); + if(!root.isDirectory()) root.mkdir(); + File projectRoot = new File(root, projectName); + if(!projectRoot.isDirectory()) projectRoot.mkdir(); + File file = new File( projectRoot, UUID.randomUUID().toString() + ".dbb"); + return file; + } + }); + + // Start the saving operation + Thread saveThread = experiment.getSaveThread(result, file, SaveResultSetJob.this.monitor); + saveThread.run(); + + // Add the result under the ResultSet within the model browser. + session.syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + String resultSetName = graph.getRelatedValue(resultSetResource, l0.HasName); + + SysdynResource sr = SysdynResource.getInstance(graph); + Resource res = GraphUtils.create2(graph, sr.Result, + l0.HasLabel, name, + l0.HasName, resultSetName + "#" + name, + sr.Result_resultFile, file.getAbsolutePath(), + sr.Result_time, System.currentTimeMillis()); + graph.claim(resultSetResource, sr.Experiment_result, res); + } + }); + + } + + } catch (DatabaseException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + monitor.done(); + return Status.OK_STATUS; + } + + @Override + public boolean belongsTo(Object family) { + return "SaveResultSetJob".equals(family); + } + + @Override + protected void canceling() { + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynConsole.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynConsole.java new file mode 100644 index 00000000..3d20128c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynConsole.java @@ -0,0 +1,205 @@ +package org.simantics.sysdyn.manager; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.console.ConsolePlugin; +import org.eclipse.ui.console.IConsole; +import org.eclipse.ui.console.IConsoleManager; +import org.eclipse.ui.console.IHyperlink; +import org.eclipse.ui.console.IPatternMatchListener; +import org.eclipse.ui.console.MessageConsole; +import org.eclipse.ui.console.MessageConsoleStream; +import org.eclipse.ui.console.PatternMatchEvent; +import org.eclipse.ui.console.TextConsole; +import org.simantics.sysdyn.solver.ISolverMonitor; + +public class SysdynConsole implements ISolverMonitor { + + private static String SYSDYN_CONSOLE = "Sysdyn modelica console"; + private MessageConsole console; + + public static SysdynConsole INSTANCE = new SysdynConsole(); + + public SysdynConsole() { + ConsolePlugin plugin = ConsolePlugin.getDefault(); + IConsoleManager conMan = plugin.getConsoleManager(); + IConsole[] existing = conMan.getConsoles(); + for (int i = 0; i < existing.length; i++) + if (existing[i].getName().equals(SYSDYN_CONSOLE)) + console = (MessageConsole) existing[i]; + if(console == null) { + MessageConsole myConsole = new MessageConsole(SYSDYN_CONSOLE, null); + conMan.addConsoles(new IConsole[]{myConsole}); + console = myConsole; + console.addPatternMatchListener(new IPatternMatchListener() { + + @Override + public void matchFound(PatternMatchEvent event) { + try { + console.addHyperlink(new IssueLink(), event.getOffset(), event.getLength()); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + + @Override + public void disconnect() { + } + + @Override + public void connect(TextConsole console) { + } + + @Override + public String getPattern() { + + return "Issues view"; + } + + @Override + public String getLineQualifier() { + return null; + } + + @Override + public int getCompilerFlags() { + return 0; + } + }); + + /* Link to the modelica document: to be opened to a modelica code viewer. + console.addPatternMatchListener(new IPatternMatchListener() { + + @Override + public void matchFound(PatternMatchEvent event) { + try { + if(event.getSource() instanceof MessageConsole) { + MessageConsole console = (MessageConsole) event.getSource(); + IDocument document = console.getDocument(); + String s = document.get(event.getOffset(), event.getLength()); + s = s.substring(s.indexOf(":") + 1, s.lastIndexOf(":")); + String[] split = s.split(":|-"); + + //TODO: Find the modelica document and its locations + int startOffset = modelicaDocument.getLineOffset(Integer.parseInt(split[0])) + Integer.parseInt(split[1]); + int endOffset = modelicaDocument.getLineOffset(Integer.parseInt(split[2])) + Integer.parseInt(split[3]); + System.out.println("Open modelica editor for model at: " + startOffset + ", " + (endOffset - startOffset)); + + } + + console.addHyperlink(new ModelicaLink(), event.getOffset(), event.getLength()); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + + @Override + public void disconnect() { + } + + @Override + public void connect(TextConsole console) { + } + + @Override + public String getPattern() { + return "\\[[^\\[]*:[\\d]*:[\\d]*\\-[\\d]*:[\\d]*:writable\\]"; + + } + + @Override + public String getLineQualifier() { + return null; + } + + @Override + public int getCompilerFlags() { + return 0; + } + }); + */ + + + } + } + + @Override + public void message(String message) { + message(message, "hh:mm:ss"); + } + + /** + * Print message to a console with a specified time stamp format + * + * @param message the message to be printed + * @param timeStampFormat simpledateformat timestamp format. null if no timestamp wanted + */ + public void message(String message, String timeStampFormat) { + Calendar cal = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat(timeStampFormat); + String time = sdf.format(cal.getTime()); + + MessageConsoleStream out = this.console.newMessageStream(); + if(message.length() > 1) + out.println("[" + time +"] " + message); + + + + if(message.contains("Error")) { + showConsole(); + out.println("See Issues view"); + } + } + + public void clearConsole() { + this.console.clearConsole(); + } + + public void showConsole() { + ConsolePlugin plugin = ConsolePlugin.getDefault(); + IConsoleManager conMan = plugin.getConsoleManager(); + conMan.showConsoleView(console); + } + + class IssueLink implements IHyperlink { + + @Override + public void linkEntered() { + } + + @Override + public void linkExited() { + } + + @Override + public void linkActivated() { + try { + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView("org.simantics.issues.ui.issueview2"); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + } + + class ModelicaLink implements IHyperlink { + + @Override + public void linkEntered() { + } + + @Override + public void linkExited() { + } + + @Override + public void linkActivated() { + System.err.println("MODELICA LINK"); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynDataSet.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynDataSet.java new file mode 100644 index 00000000..a98ad679 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynDataSet.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import org.simantics.modelica.data.DataSet; + +/** + * Extension for the basic Modelica result {@link DataSet} containing also an optional result name. + * + * @author Teemu Lempinen + * + */ +public class SysdynDataSet extends DataSet { + + public String result; // Name of the result file if this is not the result of the current simulation + public Integer resultIndex = null; + + public SysdynDataSet(String name, String result, double[] times, double[] values, Integer resultIndex) { + super(name, times, values); + this.result = result; + this.resultIndex = resultIndex; + } + + public SysdynDataSet(String name, String result, double[] times, double[] values) { + super(name, times, values); + this.result = result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java new file mode 100644 index 00000000..4fbae4f4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java @@ -0,0 +1,452 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - Bug #4180 + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import gnu.trove.set.hash.THashSet; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.locks.Lock; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.VirtualGraph; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.data.Datasource; +import org.simantics.simulation.experiment.Experiment; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IDynamicExperiment; +import org.simantics.simulation.experiment.IExperimentListener; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.Activator; +import org.simantics.sysdyn.adapter.VariableValueSubscription; +import org.simantics.sysdyn.solver.SysdynSimulationJob; +import org.simantics.sysdyn.solver.SolverSettings; +import org.simantics.sysdyn.solver.SolverSettings.SolverType; + +public class SysdynExperiment extends Experiment implements IDynamicExperiment, VariableSubscriptionManager { + + // TODO: change to protected as necessary when oldSysdynExperiment is removed + + private Session session; + private Runnable modificationListener; + public SysdynModel sysdynModel; + private boolean toggled = false; + + @SuppressWarnings("rawtypes") + private THashSet variableValueSubscriptions = new THashSet(); + @SuppressWarnings("rawtypes") + private VariableValueSubscription[] variableValueSubscriptionsSnapshot = null; + + private Process process; + private boolean canceled = false; + private ExperimentState sysdynExperimentState; + + private SysdynResult result; + + private String experimentName; + private File experimentDir; + + public SysdynExperiment(Resource experiment, Resource model) { + super(experiment, model); + this.experimentName = "Experiment"; + this.experimentDir = null; + } + + public SysdynResult getCurrentResult() { + if(this.result == null) + this.result = new MemoryResult(null, null); + return this.result; + } + + public void setCurrentResult(SysdynResult result) { + this.result = result; + } + + public Collection getActiveResults() { + ArrayList result = new ArrayList(); + if(getCurrentResult() != null) + result.add(getCurrentResult()); + result.addAll(sysdynModel.getDisplayedResults()); + return result; + } + + /** + * Initialize this experiment + * @param g ReadGraph + */ + public void init(ReadGraph g) { + try { + this.experimentName = NameUtils.getSafeName(g, experiment); + } catch (DatabaseException e) { + this.experimentName = "Experiment"; + } + + this.session = g.getSession(); + state = ExperimentState.STOPPED; + for(IExperimentListener listener : listeners.getListeners()) + listener.stateChanged(state); + + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + final Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration); + sysdynModel = SysdynModelManager.getInstance(session).getModel(graph, configuration); + toggleActivation(graph, true); + } + }); + + setSysdynExperimentState(ExperimentState.INITIALIZING); + } + + @Override + public void saveState() { + if(result == null || !(result instanceof MemoryResult)) + return; + // TODO: fix this + //SaveResultJob saveResultJob = new SaveResultJob(AltSysdynExperiment.this, session, result); + //saveResultJob.schedule(); + } + + protected Thread getSaveThread(final SysdynResult result, final File file, final IProgressMonitor progressMonitor) { + return new Thread() { + @Override + public void run() { + if(!canceled) { + // Get and store results result.saveToFile(file, progressMonitor); + } } + }; + } + + @Override + public void simulate(boolean enabled) { + // TODO: add state checks + if (enabled) { + SysdynSimulationJob job = new SysdynSimulationJob(sysdynModel.getConfiguration().getLabel(), this); + job.schedule(); + } + } + + /** + * Destroy an ongoing simulation process + */ + public void cancelSimulation() { + canceled = true; + if(process != null) { + process.destroy(); + } + } + + /** + * Toggle simulation state + * @param enabled true == RUNNING, false == STOPPED + */ + public void toggleSimulation(boolean enabled) { + if(enabled) { + this.toggled = true; + changeState(ExperimentState.RUNNING); + if(modificationListener == null) { + + modificationListener = new Runnable() { + + @Override + public void run() { + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + if(getState() == ExperimentState.RUNNING) { + // TODO: fix this + //SimulationScheduler.start(sysdynModel, this); + } + + } + }); + + }; + }; + sysdynModel.addModificationListener(modificationListener); + } + } + else { + changeState(ExperimentState.STOPPED); + this.toggled = false; + } + + } + + @Override + public void refresh(RequestProcessor session) { + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + init(graph); + } + + }); + } + + @Override + public void refresh(Session session) { + refresh((RequestProcessor)session); + } + + @Override + protected void localStateChange() { + setSysdynExperimentState(getState()); + switch(state) { + case DISPOSED: + onExperimentDisposed(); + break; + default: + break; + } + + } + + /** + * Returns sysdyn experiment state. It is usually the same as ordinary experiment state. + * Initializing phase takes longer than normally in game experiments. + * @return + */ + public ExperimentState getSysdynExperimentState() { + return sysdynExperimentState; + } + + protected void setSysdynExperimentState(final ExperimentState state) { + sysdynExperimentState = state; + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); + final Session session = graph.getSession(); + session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("experiments")) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + SimulationResource SR = SimulationResource.getInstance(graph); + graph.deny(model, SR.HasExperimentState); + graph.deny(experiment, SR.HasExperimentState); + + Resource st = graph.newResource(); + switch(state) { + case INITIALIZING: + graph.claim(st, L0.InstanceOf, SR.ExperimentState_Initializing); + break; + case RUNNING: + graph.claim(st, L0.InstanceOf, SR.ExperimentState_Running); + break; + case STOPPED: + graph.claim(st, L0.InstanceOf, SR.ExperimentState_Stopped); + break; + case DISPOSED: + graph.claim(st, L0.InstanceOf, SR.ExperimentState_Disposed); + break; + } + + graph.claim(model, SR.HasExperimentState, st); + graph.claim(experiment, SR.HasExperimentState, st); + }}); + } + }); + } + + /** + * Actions performed when experiment is disposed + * @param graph + */ + protected void onExperimentDisposed() { + cancelSimulation(); + sysdynModel.removeModificationListener(modificationListener); + modificationListener = null; + + session.asyncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + toggleActivation(graph, false); + } + }); + } + + + /** + * Toggles the active-state of this experiment on or off + * @param graph ReadGraph + * @param activate The active-state of this experiment + */ + protected void toggleActivation(ReadGraph graph, final boolean activate) { + // TODO: does not work correctly, the experiment can appear inactive even when it is actually active + VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class); + final Session session = graph.getSession(); + session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("experiments")) { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + VirtualGraph runtime = graph.getService(VirtualGraph.class); + + session.asyncRequest(new WriteRequest(runtime) { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SimulationResource SIMU = SimulationResource.getInstance(graph); + System.err.println("CHANGE ACTIVE STATE OF EXPERIMENT"); + if(activate) + graph.claim(experiment, SIMU.IsActive, experiment); + else + graph.denyStatement(experiment, SIMU.IsActive, experiment); + } + + }); + } + }); + } + + + /* Result subscriptions */ + + @SuppressWarnings("rawtypes") + /** + * Copy from AprosExperiment + * @param subscription + */ + @Override + public void addVariableValueSubscription(VariableValueSubscription subscription) { + assert subscription != null; + synchronized (variableValueSubscriptions) { + variableValueSubscriptions.add(subscription); + variableValueSubscriptionsSnapshot = null; + } + } + + @SuppressWarnings("rawtypes") + /** + * Copy from AprosExperiment + * @param subscription + */ + @Override + public void removeVariableValueSubscription(VariableValueSubscription subscription) { + assert subscription != null; + synchronized (variableValueSubscriptions) { + variableValueSubscriptions.remove(subscription); + variableValueSubscriptionsSnapshot = null; + } + } + + @SuppressWarnings("rawtypes") + /** + * Copy from AprosExperiment + * @return + */ + @Override + public VariableValueSubscription[] getListenerSnapshot() { + VariableValueSubscription[] snapshot = variableValueSubscriptionsSnapshot; + if (snapshot == null) { + synchronized (variableValueSubscriptions) { + snapshot = variableValueSubscriptionsSnapshot; + if (snapshot == null) { + snapshot = variableValueSubscriptionsSnapshot = + variableValueSubscriptions.toArray(new VariableValueSubscription[variableValueSubscriptions.size()]); + } + } + } + return snapshot; + } + + volatile long previousVariableUpdateTime = 0; + + /** + * Modified copy from AprosExperiment + */ + public void resultsChanged() { + long time = System.nanoTime(); + if (time - previousVariableUpdateTime > 10000000) { + updateSubscriptions(); + previousVariableUpdateTime = time; + } + } + + @SuppressWarnings("rawtypes") + /** + * Modified copy from AporsExperiment + */ + @Override + public void updateSubscriptions() { + for(VariableValueSubscription subscription : getListenerSnapshot()) + subscription.update(); + } + + /* Experiment methods that are not used in this experiment */ + + @Override + public Lock getDatasourceLock() { + throw new UnsupportedOperationException(); + } + + @Override + public Datasource getDatasource() { + throw new UnsupportedOperationException(); + } + + @Override + public void simulateDuration(double duration) { + throw new UnsupportedOperationException(); + } + + @Override + public void rewindTo(double time) { + throw new UnsupportedOperationException(); + } + + + + // TODO: clean this up a bit maybe? + public File getExperimentDir() { + if (experimentDir == null) { + File modelsDir = Activator.getBundleContext().getDataFile("models"); + String name = experimentName; + List files = Arrays.asList(modelsDir.list()); + if (files.contains(name)) { + int i = 2; + while (files.contains(name + "_" + i)){ + i++; + } + name += "_" + i; + } + experimentDir = new File(modelsDir, name); + experimentDir.mkdir(); + } + + return experimentDir; + } + + public SolverType getSolverType() { + // should be defined in experiment properties (similarly to other experiment types) + return SolverSettings.getSelectedSolverType(); + } + +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java new file mode 100644 index 00000000..a5a9d7bc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java @@ -0,0 +1,546 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.simantics.databoard.Bindings; +import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.AsyncListener; +import org.simantics.db.request.Read; +import org.simantics.fmu.FMUControlJNI; +import org.simantics.fmu.FMUJNIException; +import org.simantics.modelica.IModelicaMonitor; +import org.simantics.modelica.ModelicaManager; +import org.simantics.modelica.SimulationLocation; +import org.simantics.modelica.data.DataSet; +import org.simantics.modelica.data.SimulationResult; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.utils.datastructures.Triple; + +/** + * Game experiment + * @author Teemu Lempinen + * + */ +public class SysdynGameExperiment extends OldSysdynExperiment { + + private FMUControlJNI control; + private String[] subscription; + private HashMap subscriptionIndexes; + private HashMap> results; + private double stepLength = DEFAULT_STEP_LENGTH; + private double stepDuration = DEFAULT_STEP_DURATION; + private int savePer = 1; + + public static double DEFAULT_STEP_DURATION = 1.0; + public static double DEFAULT_STEP_LENGTH = 0.1; + public static int DEFAULT_OUTPUT_INTERVAL = 1; + + double[] currentValues; // Current values from FMU. Updated with updateSubscriptions + + public SysdynGameExperiment(Resource experiment, Resource model) { + super(experiment, model); + } + + public double getStepDuration() { + return stepDuration; + } + + public void setStepDuration(double duration) { + this.stepDuration = duration; + } + + public double getStepLength() { + return stepLength; + } + + public void setStepLength(double stepLength) { + this.stepLength = stepLength; + } + + public void setOutputInterval(int interval) { + this.savePer = interval; + } + + + public FMUControlJNI getFMUControl() { + return control; + } + + public double getTime() { + if(control != null) { + try { + return control.getTime(); + } catch (FMUJNIException e) { + } + } + return 0.0; + } + + + @Override + public void init(ReadGraph g) { + super.init(g); + + if(control == null) + control = new FMUControlJNI(); + + results = new HashMap>(); + + g.asyncRequest(new Read>() { + + @Override + public Triple perform(ReadGraph graph) + throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Double stepDuration = graph.getPossibleRelatedValue(experiment, sr.GameExperiment_stepDuration); + Double stepLength = graph.getPossibleRelatedValue(experiment, sr.GameExperiment_stepLength); + Double outputInterval = graph.getPossibleRelatedValue(model, sr.SysdynModel_outputInterval); + return new Triple(stepDuration, stepLength, outputInterval); + } + }, new AsyncListener>() { + + @Override + public void execute(AsyncReadGraph graph, + Triple result) { + setStepDuration(result.first != null ? result.first : DEFAULT_STEP_DURATION); + setStepLength(result.second != null ? result.second : DEFAULT_STEP_LENGTH); + + if(result.third == null) { + setOutputInterval(DEFAULT_OUTPUT_INTERVAL); + } else { + int interval = (int)getInterval(result.third, getStepLength()); + setOutputInterval(interval); + } + } + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + setStepDuration(DEFAULT_STEP_DURATION); + setStepLength(DEFAULT_STEP_LENGTH); + setOutputInterval(DEFAULT_OUTPUT_INTERVAL); + } + + @Override + public boolean isDisposed() { + return getState().equals(ExperimentState.DISPOSED); + } + }); + } + + @Override + protected void onExperimentDisposed() { + super.onExperimentDisposed(); + if(control!=null) { + try { + control.unloadFMU(); + } catch (FMUJNIException e) { + e.printStackTrace(); + } + } + } + + private boolean isValidFMU(File file) { + if(!file.exists()) return false; + if(!file.isFile()) return false; + if(file.length() == 0) return false; + return true; + } + + + @Override + public synchronized void simulate(final IModelicaMonitor monitor, final IProgressMonitor progressMonitor, String modelName) throws IOException { + canceled = false; + + progressMonitor.subTask("Write modelica classes"); + + // Write Modelica files + String modelText = getModelicaCode(monitor, true, getOpenModelicaVersion()); + if(modelText == null) + return; + + omcVersion = ModelicaManager.getDefaultOMVersion(); + + monitor.message("Simulate " + modelName + " using OpenModelica " + omcVersion); + + progressMonitor.worked(1); + + // Write initial files and add init-parameters + progressMonitor.subTask("Write simulation files"); + HashMap inits = getExperimentParameters(monitor); + + + // add loadFile script to load all related functions and function libraries + String additionalScript = getAdditionalScripts(); + + // Create simulation files + SimulationLocation simulationLocation = createSimulationFiles(sysdynModel, modelText, inits, additionalScript, true); + progressMonitor.worked(1); + + // Load precompiled fmu if structure has not changed and it has not yet been loaded + File fmu = null; + if(!sysdynModel.isStructureModified()) { + if(!simulationLocation.executableFile.isFile()) { + fmu = loadModelFmu(simulationLocation); + } else { + fmu = simulationLocation.executableFile; + } + } + // Build the model and store previous model structure and inits that affect the building + // If there is no exe file OR the model structure has not changed, no need to build + if (fmu == null && (!isValidFMU(simulationLocation.executableFile) || sysdynModel.isStructureModified())) { + progressMonitor.subTask("Build model"); + buildModel(simulationLocation, monitor); + previousModelStructure = modelText; + + saveModelFmu(simulationLocation); + } + + progressMonitor.worked(1); + + if(simulationLocation != null && !canceled) { + // Load fmu and initialize it for simulation + try { + control.loadFMUFile(simulationLocation.executableFile.getAbsolutePath()); // unzip and load fmu + control.setStepLength(stepLength); // FIXME: fixed step lenghth + instantiate(); + + } catch (FMUJNIException e) { + System.err.println("SysdynGameExperiment initialization failed:\n\t" + e.getMessage()); + } + + } + process = null; + simulate(false); + } + + /** + * Load fmu file from database, if it exists for the model of this experiment + * + * @param simulationLocation SimulationLocation indicating where the fmu should be loaded + * @return Loaded fmu or null if it was not loaded from database + */ + private File loadModelFmu(SimulationLocation simulationLocation) { + File fmu = null; + try { + final String fmuLocation = simulationLocation.executableFile.getAbsolutePath(); + fmu = session.syncRequest(new Read() { + @Override + public File perform(ReadGraph graph) throws DatabaseException { + File result = null; + FileOutputStream fos; + try { + fos = new FileOutputStream(fmuLocation); + byte[] fileBArray = graph.getPossibleRelatedValue( + getModel(), SysdynResource.getInstance(graph).SysdynModel_fmuFile, Bindings.BYTE_ARRAY); + + if(fileBArray != null) { + fos.write(fileBArray); + fos.close(); + result = new File(fmuLocation); + } else { + fos.close(); + return null; + } + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + return fmu; + } + + /** + * Save fmu file from simulationLocation to database + * @param simulationLocation Location for finding fmu + */ + private void saveModelFmu(SimulationLocation simulationLocation) { + final String fmuLocation = simulationLocation.executableFile.getAbsolutePath(); + session.asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + File file = new File(fmuLocation); + byte[] fileBArray = new byte[(int)file.length()]; + FileInputStream fis; + try { + fis = new FileInputStream(file); + + fis.read(fileBArray); + graph.claimLiteral( + getModel(), + SysdynResource.getInstance(graph).SysdynModel_fmuFile, + fileBArray, Bindings.BYTE_ARRAY); + fis.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + } + + + @Override + public void simulateDuration(double duration) { + Job job = new simulateDurationJob("Simulate steps", this, duration); + // Start the Job + job.schedule(); + } + + private class simulateDurationJob extends Job { + + private boolean canceled = false; + private double duration; + private final SysdynGameExperiment experiment; + public simulateDurationJob(String name, SysdynGameExperiment experiment, double duration) { + super(name); + this.duration = duration; + this.experiment = experiment; + } + + @Override + protected void canceling() { + canceled = true; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + if(experiment == null || experiment.getState() != ExperimentState.STOPPED) + return Status.OK_STATUS; + + changeState(ExperimentState.RUNNING); + int nSteps = (int)(duration / stepLength); + int work = 1 + nSteps * 3 + 2; // initialization + number of steps * number of phases per step + set result + call result listeners + + monitor.beginTask("Simulating " + duration + " time steps", work); + monitor.subTask("Initialize step simulation"); + + if(subscription == null || SysdynGameExperiment.this.results == null || control == null) + return Status.OK_STATUS; + + if(duration <= 0.0) + duration = stepDuration; + + + try { + + // initialize if not initialized + if(!control.isInitialized()) { + control.initializeSimulation(); + getInitialResultValues(); + } + + control.setStepLength(stepLength); // Set step length each time in case there has been changes + + double time = control.getTime(); + double eTime = time + duration; + + monitor.worked(1); + + int stepNumber = 1; + while(time < eTime && !canceled) { + if(eTime - time < stepLength) + control.setStepLength(eTime - time); + + monitor.subTask("Simulate step (time = " + time + ")"); + control.simulateStep(); + monitor.worked(1); + + if(stepNumber % savePer == 0) { + monitor.subTask("Get results (time = " + time + ")"); + currentValues = control.getSubscribedResults(currentValues); + monitor.worked(1); + + monitor.subTask("Save results (time = " + time + ")"); + for(int k = 0; k < subscription.length; k++) { + SysdynGameExperiment.this.results.get(subscription[k]).add(currentValues[k]); + } + } else { + monitor.worked(1); + } + stepNumber++; + monitor.worked(1); + + time = control.getTime(); + } + + monitor.subTask("Display results"); + ((MemoryResult)getCurrentResult()).setResult(new GameResult(SysdynGameExperiment.this.results, SysdynGameExperiment.this.subscription)); + monitor.worked(1); + + resultsChanged(); + monitor.worked(1); + changeState(ExperimentState.STOPPED); + + + } catch (FMUJNIException e) { + System.err.println("SysdynGameExperiment simulateDuration failed: \n\t" + e.getMessage()); + } + return Status.OK_STATUS; + } + } + + /** + * Game results + * @author Teemu Lempinen + * + */ + public class GameResult extends SimulationResult { + + public GameResult(HashMap> results, String[] subscription) { + + // Get times + ArrayList timeList = results.get("time"); + double[] times = new double[timeList.size()]; + for(int i = 0; i < timeList.size(); i++) { + times[i] = timeList.get(i); + } + + String name; + double[] values; + ArrayList valueList; + for(int k = 0; k < subscription.length; k++) { + name = subscription[k]; + values = new double[timeList.size()]; + valueList = results.get(name); + for(int i = 0; i < valueList.size(); i++) { + values[i] = valueList.get(i); + } + this.variables.add(new DataSet(name, times, values)); + } + } + } + + @Override + public void rewindTo(double time) { + if(control == null) + return; + + if(time >-0.001 && time < 0.001) { + instantiate(); + } else { + System.out.println("rewindTo"); + } + } + + @Override + public void refresh(Session session) { + try { + control.initializeSimulation(); + getInitialResultValues(); + + } catch (FMUJNIException e) { + System.err.println("SysdynGameExperiment instantiate failed: " + e.getMessage()); + } + } + + private synchronized void instantiate() { + try { + HashMap inits = getExperimentParameters(null); + + control.setStepLength(stepLength); // FIXME: fixed step lenghth + control.instantiateSimulation(); // instantiate simulation + if(inits.get("variableFilter") == null || inits.get("variableFilter").equals(".*")) + subscription = control.getAllVariables(); + else + subscription = control.filterVariables(inits.get("variableFilter")); + + // Initialize subscription indexes map for fast result reading in getValue() + if(subscriptionIndexes == null) + subscriptionIndexes = new HashMap(); + + subscriptionIndexes.clear(); + for(int i = 0; i < subscription.length; i++) { + subscriptionIndexes.put(subscription[i], i); + } + + // Initialize container for current simulation results + currentValues = new double[subscription.length]; + + // subscribe all variables + control.subscribe(subscription); + + getInitialResultValues(); + + } catch (FMUJNIException e) { + System.err.println("SysdynGameExperiment instantiate failed: " + e.getMessage()); + } + } + + private synchronized void getInitialResultValues() { + try { + // Initialize results + results.clear(); + + currentValues = control.getSubscribedResults(currentValues); + for(int k = 0; k < subscription.length; k++) { + results.put(subscription[k], new ArrayList()); + results.get(subscription[k]).add(currentValues[k]); + } + + ((MemoryResult)getCurrentResult()).setResult(new GameResult(this.results, this.subscription)); + resultsChanged(); + } catch (FMUJNIException e) { + System.err.println("SysdynGameExperiment getInitialResultValues failed: " + e.getMessage()); + } + } + + @Override + public void updateSubscriptions() { + try { + if(control.isInitialized()) + currentValues = control.getSubscribedResults(currentValues); + } catch (FMUJNIException e) { + e.printStackTrace(); + } + super.updateSubscriptions(); + } + + public Double getCurrentValue(String name) { + if(subscriptionIndexes != null && name != null) { + Integer index = subscriptionIndexes.get(name); + if(index != null) { + return currentValues[index]; + } + } + return null; + } + } diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java new file mode 100644 index 00000000..feb07341 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java @@ -0,0 +1,584 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - Bug #4180 + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import gnu.trove.set.hash.THashSet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.layer0.Layer0; +import org.simantics.objmap.IMapping; +import org.simantics.objmap.IMappingListener; +import org.simantics.objmap.MappingException; +import org.simantics.objmap.Mappings; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.model.IModel; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.simulation.project.ExperimentRuns; +import org.simantics.simulation.project.IExperimentActivationListener; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.adapter.VariableValueSubscription; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Model; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.ParameterOverride; +import org.simantics.sysdyn.representation.Sheet; +import org.simantics.sysdyn.representation.SysdynSchema; +import org.simantics.sysdyn.representation.Variability; +import org.simantics.sysdyn.representation.expressions.Expression; +import org.simantics.sysdyn.representation.expressions.IExpression; +import org.simantics.sysdyn.representation.expressions.ParameterExpression; +import org.simantics.sysdyn.representation.expressions.StockExpression; +import org.simantics.sysdyn.solver.SolverSettings; +import org.simantics.sysdyn.solver.SolverSettings.SolverType; + +/** + * Maintains a Java representation of system dynamic model. + * @author Hannu Niemistö, Teemu Lempinen + */ +public class SysdynModel implements IModel, IMappingListener, VariableSubscriptionManager { + + private Session session; + + private IMapping mapping; + + private Resource configurationResource; + private Resource modelResource; + + private Configuration configuration; + + private final Set modules = new HashSet(); + + private ArrayList displayedResults; + private final ArrayList listeningHistories = new ArrayList(); + + private final CopyOnWriteArrayList modificationListeners = + new CopyOnWriteArrayList(); + + @SuppressWarnings("rawtypes") + protected THashSet variableValueSubscriptions = new THashSet(); + @SuppressWarnings("rawtypes") + protected volatile VariableValueSubscription[] variableValueSubscriptionsSnapshot = null; + + @SuppressWarnings("rawtypes") + private final Map services = new HashMap(); + + private boolean structureModified = false; + + /** + * Recursively read all module configurations that are used in + * configResource and its components children + * + * @param graph ReadGraph + * @param configResource Configuration + * @param result set containing all encountered configurations + * @throws DatabaseException + */ + void readModules(ReadGraph graph, Resource configResource, Set result) throws DatabaseException { + + // if result does not contain this resource, add it to the result + if(!result.add(configResource)) return; + + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 str = StructuralResource2.getInstance(graph); + + for(Resource part : graph.getObjects(configResource, l0.ConsistsOf)) { + if(graph.isInstanceOf(part, sr.Module)) { + Resource type = graph.getPossibleType(part, sr.Module); + Resource config = graph.getPossibleObject(type, str.IsDefinedBy); + // Recursively readModules + readModules(graph, config, result); + } + } + + } + + /** + * Get all modules that have been used in configResource and its children + * @param graph ReadGraph + * @param configResource Configuration + * @return All modules (configuration resources) that have been used in configResource + * @throws DatabaseException + */ + Set readModules(ReadGraph graph, Resource configResource) throws DatabaseException { + HashSet result = new HashSet(); + readModules(graph, configResource, result); + return result; + } + + /** + * Create an ObjMapping + * @param g ReadGraph + * @throws DatabaseException + */ + private void createMapping(ReadGraph g) throws DatabaseException { + SysdynSchema schema = new SysdynSchema(g); + mapping = Mappings.createWithListening(schema); + mapping.addMappingListener(SysdynModel.this); + try { + configuration = (Configuration)mapping.map(g, configurationResource); + } catch (MappingException e) { + SysdynConsole.INSTANCE.message( + "Error: Mapping is broken! Find the problem, " + + "fix it and restart the program." + + "\nJava error message:\n" + + e.getMessage()); + throw e; + } + for(Resource config : readModules(g, configurationResource)) { + modules.add((Configuration)mapping.map(g, config)); + } + } + + /** + * New Sysdyn model + * @param g ReadGraph + * @param configurationResource Configration resource of the model + */ + public SysdynModel(ReadGraph g, Resource configurationResource) { + this.session = g.getSession(); + this.configurationResource = configurationResource; + + try { + createMapping(g); + } catch(DatabaseException e) { + e.printStackTrace(); + } + + g.asyncRequest(new Read> () { + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + ArrayList displayedResults = new ArrayList(); + // TODO: this can be done automatically with a listener + + for(HistoryDatasetResult hs : listeningHistories) + hs.disposeListeners(); // dispose old histories listening to spreadsheets + + try { + // Find all active saved results + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + Resource model = graph.getPossibleObject(getConfigurationResource(), SIMU.IsConfigurationOf); + if(model == null) + return null; + + Collection results = graph.syncRequest(new ActiveResults(model)); + for(Resource result : results) { + if(graph.hasStatement(result, sr.Result_showResult)) { + SysdynResult sysdynResult = null; + if(graph.isInstanceOf(result, sr.HistoryDataset)) { + HistoryDatasetResult r = new HistoryDatasetResult(); + listeningHistories.add(r); + sysdynResult = new MemoryResult(r, NameUtils.getSafeLabel(graph, result)); + r.read((MemoryResult)sysdynResult, result); + } else { + sysdynResult = new FileResult( + (String) graph.getPossibleRelatedValue(result, l0.HasLabel), + (String) graph.getPossibleRelatedValue(result, sr.Result_resultFile)); + } + + if(sysdynResult != null) + displayedResults.add(sysdynResult); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return displayedResults; + } + + }, new Listener> () { + + @Override + public void execute(ArrayList result) { + // Add the current result if there is one + displayedResults = result; + resultChanged(); + } + + @Override + public void exception(Throwable t) { + t.printStackTrace(); + } + + @Override + public boolean isDisposed() { + return false; + } + + }); + } + + // A dummy call for experiments + public SysdynModel(Resource modelResource) { + this.modelResource = modelResource; + } + + /** + * Get modules + * @return modules + */ + public Set getModules() { + return modules; + } + + /** + * Update mapping. + * + * Use this if inside a transaction. + * + * @param graph ReadGraph + * @return has the range been modified + * @throws DatabaseException + */ + public synchronized boolean update(ReadGraph graph) throws DatabaseException { + if(mapping.isDomainModified()) { + try { + Collection updated = mapping.updateRange(graph); + + for(Object o : updated) { + if(o instanceof Model) { + continue; + } else if(o instanceof Expression && !(o instanceof StockExpression)) { + IndependentVariable variable = ((Expression)o).getParent(); + Variability variability = Variability.getVariability(variable, false, configuration); + if(variability == Variability.PARAMETER) + continue; + } + + // if continue has not been called, the structure has changed + setStructureModified(true); + break; + + } + + } catch (MappingException e) { + SysdynConsole.INSTANCE.message( + "Error: Mapping is broken! Find the problem, " + + "fix it and restart the program." + + "\nJava error message:\n" + + e.getMessage()); + throw e; + } + + // Remove all unnecessary module configurations from modules + Set configs = readModules(graph, configurationResource); + for(Resource config : configs) { + if(!modules.contains(config)) + modules.add((Configuration)mapping.map(graph, config)); + } + + HashSet toBeRemoved = null; + for(Configuration module : modules) { + if(!configs.contains(mapping.inverseGet(module))) { + if(toBeRemoved == null) + toBeRemoved = new HashSet(); + toBeRemoved.add(module); + } + } + if(toBeRemoved != null) + modules.removeAll(toBeRemoved); + return true; + } + else + return false; + } + + /** + * Update mapping. + * + * Use only if not inside a transaction + * @return has range been updated + * @throws DatabaseException + */ + public boolean update() throws DatabaseException { + return session.syncRequest(new Read() { + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + return update(graph); + } + }); + } + + /** + * Fires an update to all result listeners and subscriptions + * after results have changed + */ + public void resultChanged() { + IProject project = Simantics.peekProject(); + IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment active = manager.getActiveExperiment(); + if(active != null && active instanceof SysdynExperiment) { + ((SysdynExperiment)active).resultsChanged(); + } + + updateSubscriptions(); + } + + public void addModificationListener(Runnable listener) { + synchronized(modificationListeners) { + modificationListeners.add(listener); + } + } + + public void removeModificationListener(Runnable listener) { + synchronized(modificationListeners) { + modificationListeners.remove(listener); + } + } + + /** + * Fires all modification listeners after a change in the domain + */ + @Override + public void domainModified() { + synchronized(modificationListeners) { + for(Runnable listener : modificationListeners) + listener.run(); + } + } + + @Override + public void rangeModified() { + } + + public Configuration getConfiguration() { + return configuration; + } + + public Resource getConfigurationResource() { + return configurationResource; + } + + public IMapping getMapping() { + return mapping; + } + + public synchronized IElement getElement(Resource resource) { + return (IElement)mapping.get(resource); + } + + public T getService(Class clazz) { + synchronized(services) { + return clazz.cast(services.get(clazz)); + } + } + + public void addService(Class clazz, T service) { + synchronized(services) { + services.put(clazz, service); + } + } + + @Override + public IExperiment loadExperiment(ReadGraph g, Resource experiment, IExperimentActivationListener listener) { + // Make sure that configurationResource exists + if(configurationResource == null && modelResource != null) { + SimulationResource simu = SimulationResource.getInstance(g); + try { + configurationResource = g.getPossibleObject(modelResource, simu.HasConfiguration); + } catch (ManyObjectsForFunctionalRelationException e) { + e.printStackTrace(); + } catch (ServiceException e) { + e.printStackTrace(); + } + } + + try { + // Create a new experiment based on the experiment resource type + SysdynResource sr = SysdynResource.getInstance(g); + SysdynExperiment exp; + + if(g.isInstanceOf(experiment, sr.PlaybackExperiment)) { + exp = new SysdynPlaybackExperiment(experiment, modelResource); + } else if(g.isInstanceOf(experiment, sr.GameExperiment)) { + exp = new SysdynGameExperiment(experiment, modelResource); + } else if(g.isInstanceOf(experiment, sr.SensitivityAnalysisExperiment)) { + exp = new SysdynSensitivityAnalysisExperiment(experiment, modelResource); + } else if(g.isInstanceOf(experiment, sr.BasicExperiment)) { + // TODO: this is a temporary hack to make sure at least one + // working implementation is available even if the new solver + // architecture is completely broken + if (SolverType.INTERNAL.equals(SolverSettings.getSelectedSolverType())) { + exp = new SysdynExperiment(experiment, modelResource); + } + else { + exp = new OldSysdynExperiment(experiment, modelResource); + } + } else { + return null; + } + + // TODO: should maybe get the model from model manager? + + exp.init(g); + + VirtualGraphSupport support = g.getSession().getService(VirtualGraphSupport.class); + ExperimentRuns.createRun(g.getSession(), support.getWorkspacePersistent("experiments"), experiment, exp, SysdynResource.URIs.Experiment_Run, listener, null); + if(listener != null) + listener.onExperimentActivated(exp); + return exp; + } catch(Exception e) { + if(listener != null) + listener.onFailure(e); + return null; + } + } + + + /** + * Get active results. To update the active results, use getAndUpdateActiveResults() + * + * @param graph ReadGraph + * @return all active SysdynResults (last update with getAndUpdateActiveResults()) + */ + public Collection getDisplayedResults() { + // TODO: displayedResults are always empty? + if(displayedResults == null) + return new ArrayList(); + else + return displayedResults; + } + + /** + * Get all parameters for Configuration + * + * @param configuration Configuration + * @param prefix String prefix of configuration in this model (Module1.Module2...) + * @return + */ + public HashMap getInits(Configuration configuration, String prefix) { + HashMap inits = new HashMap(); + for (IElement element : configuration.getElements()) { + if (element instanceof Module) { + Module module = (Module) element; + Configuration conf = module.getType().getConfiguration(); + String prfx = prefix + module.getName() + "."; + inits.putAll(getInits(conf, prfx)); + for(ParameterOverride po : module.getParameterOverrides()) { + inits.put(prfx + po.getVariable().getName(), po.getExpression()); + } + } else if (element instanceof IndependentVariable) { + IndependentVariable variable = (IndependentVariable) element; + //FIXME: more general solution for finding out if the variable is a parameter + if(variable != null && variable.getExpressions() != null && variable.getExpressions().get(0) != null) { + IExpression expression = variable.getExpressions().get(0); + if (expression instanceof ParameterExpression) { + Double value = ((ParameterExpression)expression).getValue(); + if(value != null) + inits.put(prefix + variable.getName(), "" + value); + } + } + } else if(element instanceof Sheet) { + Sheet sheet = (Sheet) element; + for(String cell : sheet.getCells().keySet()) { + inits.put(sheet.getName() + "." + cell, sheet.getCells().get(cell).toString()); + } + } + } + return inits; + } + + + @SuppressWarnings("rawtypes") + /** + * Copy from AprosExperiment + * @param subscription + */ + @Override + public void addVariableValueSubscription(VariableValueSubscription subscription) { + assert subscription != null; + synchronized (variableValueSubscriptions) { + variableValueSubscriptions.add(subscription); + variableValueSubscriptionsSnapshot = null; + } + } + + @SuppressWarnings("rawtypes") + /** + * Copy from AprosExperiment + * @param subscription + */ + @Override + public void removeVariableValueSubscription(VariableValueSubscription subscription) { + assert subscription != null; + synchronized (variableValueSubscriptions) { + variableValueSubscriptions.remove(subscription); + variableValueSubscriptionsSnapshot = null; + } + } + + @SuppressWarnings("rawtypes") + /** + * Copy from AprosExperiment + * @return + */ + @Override + public VariableValueSubscription[] getListenerSnapshot() { + VariableValueSubscription[] snapshot = variableValueSubscriptionsSnapshot; + if (snapshot == null) { + synchronized (variableValueSubscriptions) { + snapshot = variableValueSubscriptionsSnapshot; + if (snapshot == null) { + snapshot = variableValueSubscriptionsSnapshot = variableValueSubscriptions.toArray(new VariableValueSubscription[variableValueSubscriptions.size()]); + } + } + } + return snapshot; + } + + @SuppressWarnings("rawtypes") + /** + * Modified copy from AporsExperiment + */ + @Override + public void updateSubscriptions() { + VariableValueSubscription[] snapShot = getListenerSnapshot(); + for(VariableValueSubscription subscription : snapShot) + subscription.update(); + } + + + public boolean isStructureModified() { + return structureModified; + } + + public void setStructureModified(boolean structureModified) { + this.structureModified = structureModified; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModelManager.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModelManager.java new file mode 100644 index 00000000..c902f9cc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModelManager.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.util.WeakHashMap; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; + +/** + * Manages system dynamic models. + * @author Hannu Niemistö + */ +public class SysdynModelManager { + WeakHashMap models = + new WeakHashMap(); // FIXME: Resources are weak, there is no guarantee that model exists in this map as long as needed. + // HashTable with a disposal procedure could be better solution.. + Session session; + + public SysdynModelManager(Session session) { + this.session = session; + } + + /** + * Use only if not inside a transaction + */ + public SysdynModel getModel(final Resource resource) { + synchronized(models) { + SysdynModel model = models.get(resource); + if(model == null) { + try { + session.syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + SysdynModel model = new SysdynModel(graph, resource); + models.put(resource, model); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + model = models.get(resource); + } + return model; + } + } + + /** + * Should be used if called inside a transaction + */ + public SysdynModel getModel(ReadGraph g, Resource resource) { + synchronized(models) { + SysdynModel model = models.get(resource); + if(model == null) { + model = new SysdynModel(g, resource); + models.put(resource, model); + } + return model; + } + } + + public synchronized static SysdynModelManager getInstance(Session session) { + SysdynModelManager manager = + session.peekService(SysdynModelManager.class); + if(manager == null) { + manager = new SysdynModelManager(session); + session.registerService(SysdynModelManager.class, manager); + } + return manager; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java new file mode 100644 index 00000000..38ae0385 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java @@ -0,0 +1,285 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.Simantics; +import org.simantics.db.request.Read; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; + +public class SysdynPlaybackExperiment extends OldSysdynExperiment { + + public static long DURATION_SLOW = 20000; + public static long DURATION_NORMAL = 10000; + public static long DURATION_FAST = 5000; + + double time, startTime, endTime; + public static final long VARIABLE_UPDATE_INTERVAL = 500000000; + private static final double UPDATES_PER_TIME_UNIT = 0.015; + private long playbackDuration = DURATION_NORMAL; + private Collection timeListeners = new ArrayList(); + + ScheduledExecutorService playbackExecutionService; + PlaybackConfiguration playbackConfiguration; + + public SysdynPlaybackExperiment(Resource experiment, Resource model) { + super(experiment, model); + this.time = 0; + } + + + /** + * Interrupts a possible ongoing playback + * + * @param time + */ + public void setTimeInterrupting(double time) { + stopPlayback(); + setTime(time); + } + + /** + * Sets a new time and continues playback from that point if + * playback was running + * @param time + */ + public void setTimeAndContinue(double time) { + if(isPlaybackRunning()) { + stopPlayback(); + setTime(time); + startPlayback(500); + } else { + setTime(time); + } + } + + private void setTime(double time) { + this.time = time; + resultsChanged(); + } + + public double getTime() { + return this.time; + } + + public double getStartTime() { + return this.startTime; + } + + public double getEndTime() { + return this.endTime; + } + + public void setPlaybackDuration(long duration) { + this.playbackDuration = duration; + if(isPlaybackRunning()) { + //Restart playback with different time settings + startPlayback(); + } + } + + public long getPlaybackDuration() { + return this.playbackDuration; + } + + @Override + public void init(ReadGraph g) { + this.session = g.getSession(); + session.asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + changeState(ExperimentState.RUNNING); + final Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration); + sysdynModel = SysdynModelManager.getInstance(session).getModel(graph, configuration); + toggleActivation(graph, true); + getPlaybackConfiguration(graph); + startSimulationJob(); + } + }); + } + + + // PLAYBACK CONTROLS + public void startPlayback() { + startPlayback(0); + } + public void startPlayback(long initialDelay) { + if(isPlaybackRunning()) { + stopPlayback(); + } + playbackConfiguration = getPlaybackConfiguration(); + playbackExecutionService = Executors.newScheduledThreadPool(1); + + if(time >= playbackConfiguration.endTime) { + setTime(playbackConfiguration.startTime); + playbackConfiguration = getPlaybackConfiguration(); + } + + Runnable playbackSimulationTask = new PlaybackSimulationTask(time, playbackConfiguration.simulationStepLength); + + long delay = (long) (playbackConfiguration.playbackDuration / playbackConfiguration.intervals); + ScheduledFuture stepper = playbackExecutionService.scheduleWithFixedDelay( + playbackSimulationTask, initialDelay, delay, TimeUnit.MILLISECONDS + ); + + Runnable stopSimulationTask = new StopSimulationTask(stepper, playbackConfiguration.endTime); + playbackExecutionService.schedule(stopSimulationTask, playbackConfiguration.playbackDuration + initialDelay, TimeUnit.MILLISECONDS); + + changeState(ExperimentState.RUNNING); + } + + public boolean isPlaybackRunning() { + return playbackExecutionService != null && !playbackExecutionService.isShutdown(); + } + + public void resetPlayback() { + double startTime = 0.0; + if(isPlaybackRunning() && playbackConfiguration != null) { + startTime = playbackConfiguration.startTime; + } else { + startTime = getPlaybackConfiguration().startTime; + } + setTimeInterrupting(startTime); + } + + public void stopPlayback() { + if(isPlaybackRunning()) { + playbackExecutionService.shutdownNow(); + playbackExecutionService.shutdown(); + if(playbackConfiguration != null) + playbackConfiguration = null; + changeState(ExperimentState.STOPPED); + } + } + + + private class PlaybackSimulationTask implements Runnable { + private int stepCount; + private double startTime, stepLength; + + public PlaybackSimulationTask(double startTime, double stepLength) { + this.startTime = startTime; + this.stepLength = stepLength; + } + + public void run() { + ++stepCount; + setTime(startTime + stepCount * stepLength); +// System.out.println("Playback step at time: " + (startTime + stepCount * stepLength) + " (step: " + stepCount + ")"); + } + } + + private class StopSimulationTask implements Runnable { + + private ScheduledFuture scheduledFuture; + private double endTime; + + public StopSimulationTask(ScheduledFuture aSchedFuture, double endTime){ + scheduledFuture = aSchedFuture; + this.endTime = endTime; + } + public void run() { +// System.out.println("Stopping playback"); + scheduledFuture.cancel(false); + stopPlayback(); + setTime(endTime); + } + + } + + private PlaybackConfiguration getPlaybackConfiguration() { + PlaybackConfiguration config = null; + try { + config = Simantics.getSession().syncRequest(new Read() { + + @Override + public PlaybackConfiguration perform(ReadGraph graph) throws DatabaseException { + return getPlaybackConfiguration(graph); + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return config; + } + private PlaybackConfiguration getPlaybackConfiguration(ReadGraph graph) throws DatabaseException { + Double[] numbers = new Double[3]; + Resource model = getModel(); + SysdynResource sr = SysdynResource.getInstance(graph); + numbers[0] = graph.getRelatedValue(model, sr.SysdynModel_startTime); + numbers[1] = graph.getRelatedValue(model, sr.SysdynModel_stopTime); + + PlaybackConfiguration config = new PlaybackConfiguration(); + config.simulationDuration = numbers[1] - numbers[0] - time; + config.playbackDuration = (long) (config.simulationDuration / (config.simulationDuration + time) * playbackDuration); + config.intervals = config.playbackDuration * UPDATES_PER_TIME_UNIT; + config.simulationStepLength = config.simulationDuration / config.intervals; + config.endTime = numbers[1]; + config.startTime = numbers[0]; + + this.startTime = config.startTime; + this.endTime = config.endTime; + return config; + } + + private class PlaybackConfiguration { + public double simulationDuration, simulationStepLength, intervals, endTime, startTime; + public long playbackDuration; + } + + protected void localStateChange() { + super.localStateChange(); + + ExperimentState state = getState(); + if(ExperimentState.DISPOSED.equals(state)) { + stopPlayback(); + } + } + + // TIME LISTENERS + public void addTimeListener(Runnable timeListener) { + if(!this.timeListeners.contains(timeListener)) + this.timeListeners.add(timeListener); + } + + public Collection getTimeListeners() { + return this.timeListeners; + } + + public void removeTimeListener(Runnable timeListener) { + this.timeListeners.remove(timeListener); + } + + @Override + public void resultsChanged() { + for(Runnable listener : timeListeners) { + listener.run(); + } + super.resultsChanged(); + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynResult.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynResult.java new file mode 100644 index 00000000..e564d591 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynResult.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2010, 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - Bug #4180 + *******************************************************************************/ +package org.simantics.sysdyn.manager; + + +import java.io.File; + +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * + * @author Teemu Lempinen + * + */ +public abstract class SysdynResult { + + private String resultName; + + public SysdynResult(String resultName) { + this.resultName = resultName; + } + + public String getResultName() { + return this.resultName; + } + + public abstract SysdynDataSet getDataSet(String variable); + + public abstract void saveToFile(File file, IProgressMonitor progressMonitor); + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java new file mode 100644 index 00000000..063c3867 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java @@ -0,0 +1,378 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.manager; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modelica.IModelicaMonitor; +import org.simantics.modelica.ModelicaKeys; +import org.simantics.modelica.ModelicaManager; +import org.simantics.modelica.SimulationLocation; +import org.simantics.modelica.data.CSVSimulationResult; +import org.simantics.modelica.data.MatSimulationResult; +import org.simantics.modelica.data.SimulationResult; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.adapter.SensitivityExperimentParameter; +import org.simantics.sysdyn.adapter.generator.IGenerator; + +/** + * Sensitivity analysis experiment + * @author Tuomas Miettinen + * + */ +public class SysdynSensitivityAnalysisExperiment extends OldSysdynExperiment { + + private ArrayList results = null; + private int numberOfRuns = 0; + private IGenerator valueGenerator = null; + + public SysdynSensitivityAnalysisExperiment(Resource experiment, Resource model) { + super(experiment, model); + } + + private void findValuesAndRun(List parameters, HashMap values, HashMap experimentParameters) { + ArrayList> parameterMaps = new ArrayList>(); + int parametersSize = parameters.size(); + + // Get method and number of runs + try { + session.syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + numberOfRuns = graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_numberOfValues, Bindings.INTEGER); + Resource methodResource = graph.getPossibleObject(experiment, SR.SensitivityAnalysisExperiment_method); + if (methodResource == null) { + methodResource = GraphUtils.create2(graph, SR.RandomGenerator); + graph.claim(experiment, SR.SensitivityAnalysisExperiment_method, methodResource); + } + valueGenerator = graph.adapt(methodResource, IGenerator.class); + } + + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + // Refresh rate for charts + refreshRate = numberOfRuns / 20 + 1; + + // Initialize the random generator + valueGenerator.initialize(); + + // Determine the changed parameters and their values for each individual run + for (int i = 0; i < numberOfRuns; ++i) { + List randoms = valueGenerator.next();// multi-dimensional random + HashMap parameterMap = new HashMap(parametersSize); + for (int j = 0; j < parametersSize; ++j) { + SensitivityExperimentParameter p = parameters.get(j); + // Get the random value + double value = p.getDistribution().inverseCDF(randoms.get(j)); + // Add the new parameter-value-pair + parameterMap.put(p.getFullModelicaName(), Double.toString(value)); + } + // Add the complete list of one individual run parameter-value-pairs. + parameterMaps.add(parameterMap); + } + + // Set the parameters for each individual experiment and run them. + for (HashMap parameterSet : parameterMaps) { + values.putAll(parameterSet); + runSensitivityRun(values, experimentParameters); + } + } + + private void runSensitivityRun(HashMap values, HashMap experimentParameters) { + int indexOfDot = simulationLocation.resultFile.toString().lastIndexOf('.'); + if (indexOfDot > 1) { + String resFile = simulationLocation.resultFile.toString(); + String newResFile = resFile.substring(0, indexOfDot) + currentRun + resFile.substring(indexOfDot); + experimentParameters.put(ModelicaManager.RESULT_FILE_NAME, newResFile); + } + // Simulate the model for one parameter set + progressMonitor.subTask("Simulation iteration " + (currentRun+1) + "/" + numberOfRuns); + + + try { + process = ModelicaManager.runModelica( + simulationLocation, + monitor, + experimentParameters, + values + ); + } catch (IOException e) { + e.printStackTrace(); + } + + ModelicaManager.printProcessOutput(process, monitor); + + File resFile = new File(experimentParameters.get(ModelicaManager.RESULT_FILE_NAME)); + boolean updateMonitors = currentRun % refreshRate == 0 || currentRun == numberOfRuns - 1; + Thread resultThread = getResultThread(resFile, experimentParameters, monitor, progressMonitor, updateMonitors, currentRun); + resultThread.run(); + + process = null; + + progressMonitor.worked(1); + currentRun++; + + } + + private SimulationLocation simulationLocation; + private IModelicaMonitor monitor; + private IProgressMonitor progressMonitor; +// private HashMap experimentParameters; + private int currentRun = 0; + private int refreshRate = 1; + private List parameters = new ArrayList(); + + @Override + protected void runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, IProgressMonitor progressMonitor, HashMap experimentParameters, HashMap changes) throws IOException { + results = null; + + this.simulationLocation = simulationLocation; + this.monitor = monitor; + this.progressMonitor = progressMonitor; + + if (changes == null) { + changes = new HashMap(); + } + + String version = ModelicaManager.getOMVersion(simulationLocation.omHome); + experimentParameters.put(ModelicaManager.OMC_VERSION, version); + + + loadConfiguration(); + + currentRun = 0; + + + findValuesAndRun(parameters, changes, experimentParameters); + } + + private void loadConfiguration(){ + try { + session.syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + + SysdynResource SR = SysdynResource.getInstance(graph); + + Integer rRate = graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_resultRefreshRate, Bindings.INTEGER); + if(rRate != null) + refreshRate = rRate; + + Resource parameterListResource = graph.getPossibleObject(experiment, SR.SensitivityAnalysisExperiment_parameterList); + List parameterResources = ListUtils.toList(graph, parameterListResource); + + if(parameters != null) { + parameters.clear(); + for(Resource p : parameterResources) { + SensitivityExperimentParameter parameter = graph.adapt(p, SensitivityExperimentParameter.class); + if (parameter.getFullName() != null) + parameters.add(parameter); + } + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + /** + * Get a thread for reading and saving reuslts from a normal simulation + * @param simulationLocation + * @param inits + * @param monitor + * @param progressMonitor + * @param currentRun + * @return + */ + protected Thread getResultThread(final File resFile, + final HashMap experimentParameters, + final IModelicaMonitor monitor, + final IProgressMonitor progressMonitor, + final boolean updateMonitors, + final int currentRun) { + return new Thread() { + @Override + public void run() { + try { + process.waitFor(); + + if(!canceled) { + // Get and store results + SimulationResult result; + if(resFile.getName().endsWith(".csv")) + result = new CSVSimulationResult(); + else if(resFile.getName().endsWith(".plt")) + result = new SimulationResult(); + else + result = new MatSimulationResult(); // The latest format + + // The interval of results saved. Every result? Every other result? etc... + int outIntervalInt = 1; + String outputInterval = experimentParameters.get(ModelicaKeys.OUTPUT_INTERVAL); + if(outputInterval != null) { + String stepTime = experimentParameters.get(ModelicaKeys.STEP_VALUE); + String stopTime = experimentParameters.get(ModelicaKeys.STOP_VALUE); + + Double step = Double.parseDouble(stepTime); + Double stop = Double.parseDouble(stopTime); + Double outInterval = Double.parseDouble(outputInterval); + + outIntervalInt = (int)getInterval(outInterval, step); + // Actually you might be able to use an outInterval one or two longer. + int maxIntervalInt = (int)Math.round(stop / step); + if (outIntervalInt > maxIntervalInt) + outIntervalInt = maxIntervalInt; + } + + result.initRead(resFile); + result.readTime(resFile, outIntervalInt); + //result.readInits(simulationLocation.initFile); // Parameter values are read from .mat + result.filter(); + + MemoryResult currentResult = new MemoryResult(null, null); + getCurrentResults().add(currentResult); + currentResult.setResult(result); + currentResult.setResultFile(resFile); + currentResult.setResultIndex(currentRun); + + if(updateMonitors) + resultsChanged(); + + simulate(false); + + String errorString = result.getResultReadErrors(); + if(errorString != null && !errorString.isEmpty()) + monitor.message(errorString); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + } + + public ArrayList getCurrentResults() { + if(this.results == null) { + this.results = new ArrayList(); + } + return this.results; + } + + @Override + public Collection getActiveResults() { + ArrayList result = new ArrayList(); + result.addAll(getCurrentResults()); + result.addAll(sysdynModel.getDisplayedResults()); + return result; + } + + @Override + public MemoryResult getCurrentResult() { + if (this.results == null || this.results.size() < 1) + return null; + /* There should be a better alternative solution for this. Currently + * the return value is next to nonsense. + */ + return this.results.get(0); + } + + @Override + public void resultsChanged() { + long time = System.nanoTime(); + updateSubscriptions(); + previousVariableUpdateTime = time; + } + + @Override + public void saveState() { + if(results == null || !(results instanceof ArrayList)) + return; + SaveResultSetJob saveResultSetJob = new SaveResultSetJob((OldSysdynExperiment)this, session, results); + saveResultSetJob.schedule(); + } + + @Override + public int numberOfSimulationRunSteps() { + try { + Integer numberOfIterations = session.syncRequest(new Read() { + @Override + public Integer perform(ReadGraph graph) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + Integer numberOfIterations = graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_numberOfValues, Bindings.INTEGER); + + return numberOfIterations; + } + }); + + if(numberOfIterations == null) + numberOfIterations = 0; + + // 3 steps before sensitivity iterations + return 3 + numberOfIterations; + } catch (DatabaseException e) { + e.printStackTrace(); + } + + return super.numberOfSimulationRunSteps(); + + } + + + @Override + public synchronized void simulate(IModelicaMonitor monitor, IProgressMonitor progressMonitor, String modelName) throws IOException { + + omcVersion = ModelicaManager.getDefaultOMVersion(); + + // Make sure that omc version is 1.9 or higher. + // Builtin version during this change is 1.9 beta 4 + if(omcVersion != null) { + try { + double v = Double.parseDouble(omcVersion.substring(0, 3)); + if(v < 1.9) { + monitor.message("Error: Sensitivity analysis requires OMC version >= 1.9 \n" + + "Current version is " + omcVersion +"\n" + + "Change version from Window->Preferences->Modelica"); + simulate(false); + return; + } + } catch (NumberFormatException e) {} + } + + super.simulate(monitor, progressMonitor, modelName); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/VariableSubscriptionManager.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/VariableSubscriptionManager.java new file mode 100644 index 00000000..d55010c9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/VariableSubscriptionManager.java @@ -0,0 +1,16 @@ +package org.simantics.sysdyn.manager; + +import org.simantics.sysdyn.adapter.VariableValueSubscription; + +@SuppressWarnings("rawtypes") +public interface VariableSubscriptionManager { + + public void addVariableValueSubscription(VariableValueSubscription subscription); + + public void removeVariableValueSubscription(VariableValueSubscription subscription); + + public VariableValueSubscription[] getListenerSnapshot(); + + public void updateSubscriptions(); + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/ImportUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/ImportUtils.java new file mode 100644 index 00000000..761663cc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/ImportUtils.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ImportUtils { + + public static String escapeExpression(String string) { + string = string.replace("Ä", "A"); + string = string.replace("ä", "a"); + string = string.replace("ö", "o"); + string = string.replace("Ö", "O"); + string = string.replace("\\", "\n"); + + StringBuilder sb = new StringBuilder(); + + if(string.contains("\"")) { + boolean startedQuote = false; + StringBuilder var = new StringBuilder(); + for(char c : string.toCharArray()) { + if(c == '"') { + if(!startedQuote) { + startedQuote = true; + var = new StringBuilder(); + continue; + } else { + startedQuote = false; + sb.append(var.toString().replaceAll("[^a-zA-Z 0-9]+", "")); + continue; + } + } + if(startedQuote) { + var.append(c); + } else { + sb.append(c); + } + } + + string = sb.toString(); + } + + return string; + + } + + public static String escapeName(String string) { + string = string.replace("Ä", "A"); + string = string.replace("ä", "a"); + string = string.replace("ö", "o"); + string = string.replace("Ö", "O"); + string = string.replaceAll("[^a-zA-Z 0-9]+", ""); + return string; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlFile.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlFile.java new file mode 100644 index 00000000..5711a759 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlFile.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport; + +import java.util.ArrayList; + +public class MdlFile { + + private ArrayList variables = new ArrayList(); + private ArrayList controls = new ArrayList(); + private ArrayList sketchData = new ArrayList(); + private ArrayList otherData = new ArrayList(); + + + + public void addVariable(String variable) { + variables.add(variable); + } + + public ArrayList getVariables() { + return variables; + } + + public void addControl(String control) { + controls.add(control); + } + + public ArrayList getControls() { + return controls; + } + + public void addSketchData(String sketchRow) { + sketchData.add(sketchRow); + } + + public ArrayList getSketchData() { + return sketchData; + } + + public void addOtherData(String dataRow) { + otherData.add(dataRow); + } + + public ArrayList getOtherData() { + return otherData; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlParser.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlParser.java new file mode 100644 index 00000000..2f68f086 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlParser.java @@ -0,0 +1,622 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport; + +import java.awt.geom.Point2D; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.mdlImport.mdlElements.Auxiliary; +import org.simantics.sysdyn.mdlImport.mdlElements.Cloud; +import org.simantics.sysdyn.mdlImport.mdlElements.Connection; +import org.simantics.sysdyn.mdlImport.mdlElements.Dependency; +import org.simantics.sysdyn.mdlImport.mdlElements.Element; +import org.simantics.sysdyn.mdlImport.mdlElements.EquivalenceSubscript; +import org.simantics.sysdyn.mdlImport.mdlElements.Expression; +import org.simantics.sysdyn.mdlImport.mdlElements.Flow; +import org.simantics.sysdyn.mdlImport.mdlElements.Function; +import org.simantics.sysdyn.mdlImport.mdlElements.Model; +import org.simantics.sysdyn.mdlImport.mdlElements.Stock; +import org.simantics.sysdyn.mdlImport.mdlElements.Subscript; +import org.simantics.sysdyn.mdlImport.mdlElements.Valve; +import org.simantics.sysdyn.mdlImport.mdlElements.Variable; +import org.simantics.sysdyn.mdlImport.mdlElements.View; + +public class MdlParser { + + public static Model parse(File file) { + + Model model = new Model(); + + String[] name = file.getName().split("\\.mdl"); + model.setName(name[0]); + + MdlFile mdlFile = getMdlContents(file); + + getVariableData(model, mdlFile.getVariables()); + + getSketchData(model, mdlFile.getSketchData()); + + getControlData(model, mdlFile.getControls()); + +// getOthertData(model, mdlFile.getOtherData()); + + setAllSubscripts(model); + + return model; + } + + + private static MdlFile getMdlContents(File aFile) { + MdlFile mdlFile = new MdlFile(); + + try { + BufferedReader input = new BufferedReader(new FileReader(aFile)); + + try { + String line = null; //not declared within while loop + + // See if the document is encoded with UTF-8. It will be marked with {UTF-8} on the first line + input.mark(30); + if (( line = input.readLine()) != null && + line.contains("{UTF-8}")){ + Reader in = new InputStreamReader(new FileInputStream(aFile), "UTF-8"); + input = new BufferedReader(in); + line = input.readLine(); + } else { + input.reset(); + } + + + boolean isControl = false; + + while (( line = input.readLine()) != null){ + // Build an element (combine the lines to one string) + StringBuilder elementBuilder = new StringBuilder(); + while(line != null && !line.contains("\\\\\\---///")) { + // Add a new line for the element + elementBuilder.append(line); + if(line.endsWith("|") && !line.endsWith("~~|")) { + //Element definition has ended + break; + } + line = input.readLine(); + } + + if(line.contains("\\\\\\---///")) + break; + + String variable = elementBuilder.toString(); + + if(variable.trim().matches("[\\*]{46}.+[\\*]{46}.+")) { + if(variable.contains(".Control")) { + isControl = true; + } else { + isControl = false; + } + continue; + } + + // Add element string to model + if(isControl) { + mdlFile.addControl(variable); + } else { + mdlFile.addVariable(variable); + } + } + + while (( line = input.readLine()) != null && !line.contains("///---\\\\\\")){ + mdlFile.addSketchData(line); + } + + while (( line = input.readLine()) != null){ + mdlFile.addOtherData(line); + } + } + finally { + input.close(); + } + } + catch (IOException ex){ + ex.printStackTrace(); + } + + return mdlFile; + } + + private static void getVariableData(Model model, ArrayList elements) { + ArrayList equivalenceSubscripts = new ArrayList(); + for(String elementString : elements) { + Variable v = createVariable(model, elementString); + if(v instanceof EquivalenceSubscript){ + equivalenceSubscripts.add((EquivalenceSubscript) v); + } + } + + // All variables are ready, determine subscript equivalences + for(EquivalenceSubscript es : equivalenceSubscripts) { + Element e = model.getElement(es.getEquivalentToName()); + if(e != null && e instanceof Subscript) { + es.setEquivalentTo((Subscript)e); + } + } + } + + + private static void getControlData(Model model, ArrayList controls) { + for(String controlString : controls) { + String[] nameAndData = controlString.split("="); + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + + if(nameAndData[0].trim().equals("FINAL TIME")) { + model.setEndTime(Double.parseDouble(expressionUnitsAndComments[0])); + } else if(nameAndData[0].trim().equals("INITIAL TIME")) { + model.setStartTime(Double.parseDouble(expressionUnitsAndComments[0])); + } else if(nameAndData[0].trim().equals("TIME STEP")) { + model.setTimeStep(Double.parseDouble(expressionUnitsAndComments[0])); + } else if(nameAndData[0].trim().equals("SAVEPER")) { + model.setSaveper(expressionUnitsAndComments[0]); + model.setTimeUnit(expressionUnitsAndComments[1]); + } + } + + } + + private static Variable getVariable(Model model, String name) { + Element e = model.getElement(name); + Variable variable = null; + if(e != null && e instanceof Variable) + variable = (Variable)e; + return variable; + } + + private static String[] getNormalVariableNameDataAndRange(String element) { + String[] nameAndData = element.split("=", 2); + String[] nameAndRange = nameAndData[0].trim().split("[\\[|\\]]"); + if(nameAndData.length == 2) + return new String[] {nameAndRange[0], nameAndData[1], nameAndRange.length == 2 ? nameAndRange[1] : null}; + return null; + } + + private static String[] getSubscriptNameAndData(String element) { + String[] nameAndData = element.split(":"); + if(nameAndData.length == 2) + return nameAndData; + return null; + } + + private static String[] getEquivalenceSubscriptNameAndData(String element) { + String[] nameAndData = element.split("\\<\\-\\>"); + if(nameAndData.length == 2) + return nameAndData; + return null; + } + + private static String[] getTableNameDataAndRange(String element) { + String[] parts = element.split("\\~"); + if(!parts[0].contains("(") || !parts[0].contains(")")) + return null; + String name = element.substring(0, element.indexOf("(")); + String theRest = element.substring(element.indexOf("(")); + String[] nameAndData = {name, theRest}; + String[] nameAndRange = nameAndData[0].trim().split("[\\[|\\]]"); + if(nameAndData.length == 2) + return new String[] {nameAndRange[0], nameAndData[1], nameAndRange.length == 2 ? nameAndRange[1] : null}; + return nameAndData; + } + + private static String[] getDataVariableNameAndData(String element) { + String[] nameAndData = { + element.substring(0, element.indexOf("~")), + " " + element.substring(element.indexOf("~"))}; + return nameAndData; + } + + private static Variable createVariable(Model model, String elementString) { + + String[] elementExpressions = elementString.split("\\~\\~\\|"); + + Variable variable = null; + + for(String s : elementExpressions) { + // Skip these definitions at least for now + if(elementExpressions.length > 1 && s.contains("A FUNCTION OF")) + continue; + + Expression expression = new Expression(); + + String[] nameAndData = null; + String name; + + // Create the expression based on the expression string + if((nameAndData = getNormalVariableNameDataAndRange(s)) != null) { + + name = nameAndData[0].replace("\"", ""); + variable = getVariable(model, name); + if(variable == null) { + variable = new Auxiliary(); + variable.setName(name); + model.addElement(variable); + } + + if(!nameAndData[1].trim().endsWith("|")) { + // Multiple expressions + expression.setExpression(nameAndData[1].trim()); + } else { + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + expression.setExpression(expressionUnitsAndComments[0].trim()); + } + + } else if((nameAndData = getSubscriptNameAndData(s)) != null) { + + name = nameAndData[0].replace("\"", ""); + variable = getVariable(model, name); + if(variable == null) { + variable = new Subscript(); + variable.setName(name); + model.addElement(variable); + } + + // No support for multidimensional variables. Don't know what that would mean + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + expression.setExpression(expressionUnitsAndComments[0].trim()); + variable.setUnits(expressionUnitsAndComments[1].trim()); + variable.setComments(expressionUnitsAndComments[2].trim()); + + } else if((nameAndData = getEquivalenceSubscriptNameAndData(s)) != null) { + + name = nameAndData[0].replace("\"", ""); + variable = getVariable(model, name); + if(variable == null) { + variable = new EquivalenceSubscript(); + variable.setName(name); + model.addElement(variable); + } + + // No support for multidimensional variables. Don't know what that would mean + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + expression.setExpression(expressionUnitsAndComments[0].trim()); + variable.setUnits(expressionUnitsAndComments[1].trim()); + variable.setComments(expressionUnitsAndComments[2].trim()); + + } else if((nameAndData = getTableNameDataAndRange(s)) != null) { + + name =(nameAndData[0].replace("\"", "")); + variable = getVariable(model, name); + if(variable == null) { + variable = new Function(); + variable.setName(name); + model.addElement(variable); + } + + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + // ([(0,0)-(2,5)],(0,5),(0.5,3),(1,0.5),(2,0.5) => ( ; (0,0)-(2,5) ; ,(0,5),(0.5,3),(1,0.5),(2,0.5) + String table = expressionUnitsAndComments[0].trim().split("[\\[|\\]]")[2]; + // ,(0,5),(0.5,3),(1,0.5),(2,0.5) => (0,5),(0.5,3),(1,0.5),(2,0.5) + table = table.substring(table.indexOf(",") + 1, table.lastIndexOf(")")); + table = "{" + table + "}"; + table = table.replace("(", "{"); + table = table.replace(")", "}"); + expression.setExpression(table); + + + } else if((nameAndData = getDataVariableNameAndData(s)) != null) { + + name = nameAndData[0].replace("\"", ""); + variable = getVariable(model, name); + if(variable == null) { + variable = new Auxiliary(); + variable.setName(name); + model.addElement(variable); + } + + expression.setExpression(""); + } + + if(nameAndData == null || variable == null) + continue; + + // Set possible range for the expression + if(nameAndData.length == 3) + expression.setRange(nameAndData[2]); + + // Set units and comments for the variable + if(nameAndData[1].trim().endsWith("|")) { + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + String units = expressionUnitsAndComments[1].trim(); + if(units.contains("[") && + units.contains("]") && + units.lastIndexOf("]") == units.length() - 1) { + // Range definitions are at the end + String range = units.substring( + units.lastIndexOf("[") + 1, + units.length() - 1); + String[] rangeParts = range.split(","); + + try { + variable.setRangeStart(Double.parseDouble(rangeParts[0])); + if(rangeParts.length >= 2) + variable.setRangeEnd(Double.parseDouble(rangeParts[1])); + if(rangeParts.length >= 3) + variable.setRangeStep(Double.parseDouble(rangeParts[2])); + } catch (NumberFormatException e) { + // Not a double + } + expressionUnitsAndComments[1] = units.substring(0, units.lastIndexOf("[")); + } + variable.setUnits(expressionUnitsAndComments[1].trim()); + variable.setComments(expressionUnitsAndComments[2].trim()); + } + + // Finally add the expression to element + variable.getExpressions().add(expression); + } + return variable; + } + + private static int SCALE = 4; + private static void getSketchData(Model model, ArrayList sketchData) { + + String line = null; + View view = null; + int i = 0; + while(i < sketchData.size()) { + line = sketchData.get(i); + if(line.startsWith("*")) { + view = new View(); + model.addView(view); + + view.setName(line.substring(1)); + + // STARTED A NEW VIEW + + HashMap elementNumbers = new HashMap(); + ArrayList ghostNumbers = new ArrayList(); + ArrayList connections = new ArrayList(); + HashMap emptyValves = new HashMap(); // map for valves that don't have an element + + + i++; + line = sketchData.get(i); + while(i < sketchData.size() && !sketchData.get(i).startsWith("*")) { + line = sketchData.get(i); + + if(line.startsWith("$")) { + view.setFontParameters(line); + i++; + continue; + } + + String[] data = line.split(","); + if(data[0].equals("1")) { + // Connections are handled after all elements + String[] connectionData = line.split(","); + connections.add(connectionData); + + } else if(data[0].equals("11")){ + // Valve + i = i + 1; + String elementLine = sketchData.get(i); + String[] elementData = elementLine.split(","); + // FIXME: Assumes that element is always attached to the valve + Element element = model.getElement(elementData[2].replace("\"", "")); + Valve valve = new Valve(); + if(element != null && element instanceof Variable) { + Variable v = (Variable) element; + valve.setName(v.getName()); + valve.setExpressions(v.getExpressions()); + valve.setUnits(v.getUnits()); + valve.setComments(v.getComments()); + valve.setX(Integer.parseInt(data[3]) / SCALE); + valve.setY(Integer.parseInt(data[4]) / SCALE); + + model.removeElement(element); + model.addElement(view, valve); + + // Add valve to the element list with both valve and variable symbol numbers + elementNumbers.put(elementData[1], valve); + elementNumbers.put(data[1], valve); + } else { + i = i - 1; + emptyValves.put(data[1], data); + } + } else if(data[0].equals("12")){ + // Cloud + Cloud cloud = new Cloud(); + cloud.setX(Integer.parseInt(data[3]) / SCALE); + cloud.setY(Integer.parseInt(data[4]) / SCALE); + elementNumbers.put(data[1], cloud); + model.addElement(view, cloud); + } else if(data[0].equals("10") && data.length <= 15){ + // Some variable + Element e = model.getElement(data[2].replace("\"", "").trim()); + if(e != null && e instanceof Variable) { + Variable v = (Variable) e; + if(v.getExpressions().get(0).getExpression().startsWith("INTEG (") && !(e instanceof Stock)) { + // Stock + Stock s = new Stock(); + s.setName(v.getName()); + s.setUnits(v.getUnits()); + s.setComments(v.getComments()); + s.setExpressions(v.getExpressions()); + model.removeElement(e); + e = s; + model.addElement(view, e); + } + } + + e.setX(Integer.parseInt(data[3]) / SCALE); + e.setY(Integer.parseInt(data[4]) / SCALE); + elementNumbers.put(data[1], e); + model.relocateElement(view, e); + } else if(data[0].equals("10") && data.length > 15){ + // TODO: Ghost + // for now, direct back to the original element + Element originalElement = model.getElement(data[2].replace("\"", "")); + if(originalElement != null) { + elementNumbers.put(data[1], originalElement); + ghostNumbers.add(data[1]); + } + } + + i++; + } + i--; + + // Find the first variable that is connected to an empty valve + for(String[] connectionData : connections) { + if(!connectionData[9].equals("64")) + continue; // not dependency + String[] end = emptyValves.get(connectionData[3]); + if(end != null && elementNumbers.get(connectionData[3]) == null) { + // Use the connected element to create a valve and give it a name + Element start = elementNumbers.get(connectionData[2]); + if(start == null) + continue; + + Valve valve = new Valve(); + valve.setName(start.getName() + " Rate"); + valve.setX(Integer.parseInt(end[3]) / SCALE); + valve.setY(Integer.parseInt(end[4]) / SCALE); + + model.addElement(view, valve); + elementNumbers.put(connectionData[3], valve); + valve.setUnits(""); + valve.setComments(""); + } + } + + + + for(String[] connectionData : connections) { + + Element start = elementNumbers.get(connectionData[2]); + Element end = elementNumbers.get(connectionData[3]); + // Discard connection if one of the ends is null + if(start == null || end == null) + continue; + + + Connection connection; + if(connectionData[9].equals("64")) { + // Dependency + Point2D startPoint = new Point2D.Double(start.getX(), start.getY()); + Point2D endPoint = new Point2D.Double(end.getX(), end.getY()); + String controlX = connectionData[13].substring(connectionData[13].indexOf("(") + 1); + String controlY = connectionData[14].substring(0, connectionData[14].indexOf(")")); + Point2D controlPoint = new Point2D.Double(Double.parseDouble(controlX) / SCALE, Double.parseDouble(controlY) / SCALE); + + if(ghostNumbers.contains(connectionData[2]) || + ghostNumbers.contains(connectionData[3])) { + connection = new Dependency(); + } else { + double angle = Dependency.angleOfArc( + startPoint.getX(), startPoint.getY(), + controlPoint.getX(), controlPoint.getY(), + endPoint.getX(), endPoint.getY()); + + connection = new Dependency(angle); + } + + } else { + // Flow + connection = new Flow(); + if(connectionData[4].equals("100")) { + // Flip the flow + Element temp = start; + start = end; + end = temp; + } + } + connection.setStart(start); + connection.setEnd(end); + model.addConnection(connection); + } + + + // Generate expressions for empty valves + for(String key : emptyValves.keySet()) { + Element e = elementNumbers.get(key); + if(e instanceof Valve && ((Valve)e).getExpressions().isEmpty()) { + Valve valve = (Valve)e; + // Find the stock + Stock stock = null; + for(Connection connection : valve.getConnections()) { + if(!(connection instanceof Flow)) + continue; + if(connection.getStart().equals(valve) && + connection.getEnd() instanceof Stock) { + stock = (Stock)connection.getEnd(); + break; + } + } + + // Create the expression. Use the expression of the stock, and undo the effect of other valves + if(stock != null && stock instanceof Stock) { + Expression expression = new Expression(); + + StringBuilder sb = new StringBuilder(); + sb.append(((Stock)stock).getIntegralParts(stock.getExpressions().get(0))[0]); + + for(Connection c : stock.getConnections()) { + if(c instanceof Flow) { + if(c.getStart().equals(stock) && !c.getEnd().equals(valve)) { + sb.append("+"); + sb.append(c.getEnd().getName()); + } else if(!c.getStart().equals(valve)){ + sb.append("-"); + sb.append(c.getStart().getName()); + } + } + } + expression.setExpression(sb.toString()); + ArrayList expressions = new ArrayList(); + expressions.add(expression); + valve.setExpressions(expressions); + } + } + } + } + i++; + } + + } + + private static void getOthertData(Model model, String otherData) { + + } + + private static void setAllSubscripts(Model model) { + + // Set subscripts for all elements + ArrayList elements = new ArrayList(); + elements.addAll(model.getUnlocatedElements()); + for(View view : model.getViews()) { + elements.addAll(view.getElements()); + } + + for(Element e : elements) { + if(!(e instanceof Variable)) + continue; + Variable v = (Variable)e; + v.initializeSubscripts(model); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Auxiliary.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Auxiliary.java new file mode 100644 index 00000000..62c3764b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Auxiliary.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.mdlImport.ImportUtils; + +public class Auxiliary extends Variable { + + @Override + public Resource getExpression(WriteGraph graph, Expression expression) throws DatabaseException { + + SysdynResource sr = SysdynResource.getInstance(graph); + Resource e = GraphUtils.create2(graph, + sr.NormalExpression, + sr.Expression_equation, ImportUtils.escapeExpression(expression.getExpression()).trim()); + return e; + } + + @Override + public void write(WriteGraph graph, Resource parent, double xOffset, + double yOffset) { + if(parent == null || graph == null) + return; + + try { + SysdynResource sr = SysdynResource.getInstance(graph); + if(!graph.isInstanceOf(parent, sr.Configuration)) + return; + createVariable(graph, parent, sr.Auxiliary, sr.AuxiliarySymbol, xOffset, yOffset); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Cloud.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Cloud.java new file mode 100644 index 00000000..95a83811 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Cloud.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; + +public class Cloud extends Element { + + @Override + public void write(WriteGraph graph, Resource parent, double xOffset, + double yOffset) { + if(parent == null || graph == null) + return; + + try { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + DiagramResource dr = DiagramResource.getInstance(graph); + G2DResource g2d = G2DResource.getInstance(graph); + + if(!graph.isInstanceOf(parent, sr.Configuration)) + return; + + Resource diagram = graph.getSingleObject(parent, mr.CompositeToDiagram); + + if(diagram == null) + return; + + Resource cloud = GraphUtils.create2(graph, + sr.Cloud); + + graph.claim(parent, l0.ConsistsOf, cloud); + + + + Resource symbol = GraphUtils.create2(graph, + sr.CloudSymbol, + mr.ElementToComponent, cloud); + + double[] transform = {1.0, 0.0, 0.0, 1.0, getX() + xOffset, getY() + yOffset}; + graph.claimLiteral(symbol, dr.HasTransform, g2d.Transform, transform); + + OrderedSetUtils.add(graph, diagram, symbol); + + setResource(cloud); + + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Connection.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Connection.java new file mode 100644 index 00000000..ba3be264 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Connection.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; + +public abstract class Connection implements IWriteableMDLObject { + protected Element start, end; + + public Resource writeConnection(WriteGraph graph, Resource configuration, Resource connectionType, Resource connectionSymbol) throws DatabaseException { + if(configuration == null || graph == null + || start.getResource() == null || end.getResource() == null) { + return null; + } + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + DiagramResource dr = DiagramResource.getInstance(graph); + StructuralResource2 sr2 = StructuralResource2.getInstance(graph); + + Resource diagram = graph.getPossibleObject(configuration, mr.CompositeToDiagram); + Resource startElement = graph.getPossibleObject(start.getResource(), mr.ComponentToElement); + Resource endElement = graph.getPossibleObject(end.getResource(), mr.ComponentToElement); + if(diagram == null || startElement == null || endElement == null) + return null; + + + if(connectionType == null) + connectionType = sr.Dependency; + + if(connectionSymbol == null) + connectionSymbol = sr.DependencyConnection; + + // Build the connection to configuration + Resource connection = GraphUtils.create2(graph, + connectionType, + sr.Variable_HasHead, end.getResource(), + sr.Variable_HasTail, start.getResource(), + l0.PartOf, configuration); + graph.claim(connection, mr.Mapped, connection); + + + // Build diagram connectors and connection + Resource tailConnector = GraphUtils.create2(graph, + dr.Connector, + sr.HasTailTerminal, startElement); + + Resource headConnector = GraphUtils.create2(graph, + dr.Connector, + sr.HasHeadTerminal, endElement, + dr.AreConnected, tailConnector); + + Resource diagramConnection = GraphUtils.create2(graph, + connectionSymbol, + sr2.HasConnectionType, sr.SysdynConnectionType, + mr.DiagramConnectionToConnection, connection, + dr.HasArrowConnector, headConnector, + dr.HasPlainConnector, tailConnector); + + OrderedSetUtils.add(graph, diagram, diagramConnection); + + return connection; + } + + public Element getStart() { + return start; + } + + public void setStart(Element start) { + this.start = start; + } + + public Element getEnd() { + return end; + } + + public void setEnd(Element end) { + this.end = end; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Dependency.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Dependency.java new file mode 100644 index 00000000..1b5bdc8e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Dependency.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; + +public class Dependency extends Connection { + + private double angle; + + public Dependency() { + this(-0.1); + } + + public Dependency(double angle) { + this.angle = angle; + } + + @Override + public void write(WriteGraph graph, Resource parent) { + if(parent == null || graph == null || start == null || end == null) + return; + try { + SysdynResource sr = SysdynResource.getInstance(graph); + Resource connection = writeConnection(graph, parent, sr.Dependency, sr.DependencyConnection); + + if(connection != null) { + ModelingResources mr = ModelingResources.getInstance(graph); + Resource diagramConnection = graph.getSingleObject(connection, mr.ConnectionToDiagramConnection); + graph.claimLiteral(diagramConnection, sr.Dependency_angle, angle); + } + + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + public double getAngle() { + return angle; + } + + public void setAngle(double angle) { + this.angle = angle; + } + + + + /** + * Returns an angle in radians between straight line from (x0,y0) to (x2,y2) + * and an arc from (x0,y0) to (x2,y2) thru (x1,y1). The angle + * is measured at (x0,y0) and is between -PI and PI. + */ + public static double angleOfArc( + double x0, double y0, + double x1, double y1, + double x2, double y2) { + double dx0 = x1-x0; + double dy0 = y1-y0; + double dx1 = x1-x2; + double dy1 = y1-y2; + double dx = x2-x0; + double dy = y2-y0; + // Length of cross product (p1-p0)x(p2-p0) + double dd = dx0*dy - dy0*dx; + + if(Math.abs(dd) < 1e-6) // Points are (almost) collinear + return 0.0; + else { + // (p1-p0)*(p1-p2) / dd + double offset = (dx0*dx1 + dy0*dy1) / dd; + double angle = Math.PI*0.5 - Math.atan(offset); + if(dd > 0.0) + angle = angle-Math.PI; + return angle; + + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Element.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Element.java new file mode 100644 index 00000000..fb233346 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Element.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import java.util.ArrayList; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; + +public abstract class Element implements IWriteableMDLElement { + + protected int x, y; + protected Resource resource; + protected String name; + protected ArrayList connections; + + protected Resource getExpression(WriteGraph graph, Expression expression) + throws DatabaseException { + return null; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + + public String getName() { + if(name == null) + return "Name"; + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Resource getResource() { + return resource; + } + + public void setResource(Resource resource) { + this.resource = resource; + } + + public ArrayList getConnections() { + if(connections == null) + connections = new ArrayList(); + return connections; + } + + public void setConnections(ArrayList connections) { + this.connections = connections; + } + + public void addConnection(Connection connection) { + getConnections().add(connection); + } +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/EquivalenceSubscript.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/EquivalenceSubscript.java new file mode 100644 index 00000000..74741b30 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/EquivalenceSubscript.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; + +public class EquivalenceSubscript extends Subscript { + + public String getEquivalentToName() { + String name = ""; + if(expressions != null && expressions.get(0) != null) { + name = expressions.get(0).getExpression().trim(); + } + return name; + } + + public void setEquivalentTo(Subscript equivalentTo) { + setExpressions(equivalentTo.getExpressions()); + } + + @Override + public void write(WriteGraph graph, Resource parent, double xOffset, + double yOffset) { + super.write(graph, parent, xOffset, yOffset); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Expression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Expression.java new file mode 100644 index 00000000..e36ca60a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Expression.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + + +public class Expression { + private String range, expression; + + @Override + public String toString() { + return (range != null ? "[" + range + "]: " : "") + expression; + } + + public String getRange() { + return range; + } + + public void setRange(String range) { + this.range = range; + } + + public String getExpression() { + if(expression == null) + return ""; + return expression; + } + + public void setExpression(String expression) { + this.expression = expression; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Flow.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Flow.java new file mode 100644 index 00000000..b8e8e50f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Flow.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.SysdynResource; + +public class Flow extends Connection { + + @Override + public void write(WriteGraph graph, Resource parent) { + if(parent == null || graph == null) + return; + try { + SysdynResource sr = SysdynResource.getInstance(graph); + writeConnection(graph, parent, sr.Flow, sr.FlowConnection); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Function.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Function.java new file mode 100644 index 00000000..43afed7e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Function.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.mdlImport.ImportUtils; + +public class Function extends Variable { + + @Override + public void write(WriteGraph graph, Resource parent, double xOffset, + double yOffset) { + if(parent == null || graph == null) + return; + + try { + SysdynResource sr = SysdynResource.getInstance(graph); + if(!graph.isInstanceOf(parent, sr.SysdynModel)) + return; + Layer0 l0 = Layer0.getInstance(graph); + + Resource function = GraphUtils.create2(graph, + sr.SysdynModelicaFunction, + l0.HasName, ImportUtils.escapeName(this.getName())); + + if(comments != null && comments.length() > 0) + graph.claimLiteral(function, l0.HasDescription, comments); + + if(expressions != null && expressions.get(0) != null) { + StringBuilder sb = new StringBuilder(); + sb.append(" input Real a;\n"); + sb.append(" output Real result;\n"); + sb.append("algorithm\n"); + sb.append(" result := interpolate(a, " + expressions.get(0).getExpression() + ");"); + graph.claimLiteral(function, sr.SysdynModelicaFunction_modelicaFunctionCode, sb.toString()); + } + + graph.claim(parent, l0.ConsistsOf, function); + resource = function; + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/IWriteableMDLElement.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/IWriteableMDLElement.java new file mode 100644 index 00000000..5f0a4250 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/IWriteableMDLElement.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; + +public interface IWriteableMDLElement { + + /** + * Writes an element with coordinates (variable, cloud) to the given resource. + * + * Offsets determine where the parent view is located in the combined diagram + * + * @param graph WriteGraph + * @param parent The resource where the object is located + * @param xOffset xOffset of the view in the diagram + * @param yOffset yOffset of the view in the diagram + */ + public void write(WriteGraph graph, Resource parent, double xOffset, double yOffset); +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/IWriteableMDLObject.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/IWriteableMDLObject.java new file mode 100644 index 00000000..a464cfb0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/IWriteableMDLObject.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; + +public interface IWriteableMDLObject { + + /** + * Writes an object with no coordinates (connection, model, view) to the given resource + * + * @param graph WriteGraph + * @param parent The resource where the object is located + */ + public void write(WriteGraph graph, Resource parent); +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Model.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Model.java new file mode 100644 index 00000000..dcc7d0d1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Model.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.utils.ModelUtils; + +public class Model implements IWriteableMDLObject { + + private String name, timeUnit, saveper; + private double startTime = 0, endTime = 10, timeStep = 1; + + private HashMap elementMap = new HashMap(); + private ArrayList subscripts = new ArrayList(); + private ArrayList functions = new ArrayList(); + private ArrayList connections = new ArrayList(); + private ArrayList views = new ArrayList(); + private ArrayList unlocatedElements = new ArrayList(); + + public void addElement(Element element) { + if(element instanceof Subscript) + addSubscript((Subscript)element); + else if(element instanceof Function) + addFunction((Function)element); + else + unlocatedElements.add(element); + if(element.getName() != null) + elementMap.put(element.getName(), element); + } + + public void addSubscript(Subscript subscript) { + subscripts.add(subscript); + } + + public void addFunction(Function function) { + functions.add(function); + } + + public void addElement(View view, Element element) { + if(element instanceof Subscript) + addSubscript((Subscript)element); + else { + if(unlocatedElements.contains(element)) + unlocatedElements.remove(element); + view.addElement(element); + } + if(element.getName() != null) + elementMap.put(element.getName(), element); + } + + public void relocateElement(View view, Element element) { + if(unlocatedElements.contains(element)) + unlocatedElements.remove(element); + for(View v : views) { + if(v.getElements().contains(element)) + v.getElements().remove(element); + } + view.addElement(element); + } + + public void removeElement(Element element) { + if(unlocatedElements.contains(element)) + unlocatedElements.remove(element); + + for(View view : views) { + if(view.getElements().contains(element)) { + view.getElements().remove(element); + } + } + + // just to be sure: loop the whole elementMap and don't trust the element's name + String toBeRemoved = null; + for(String key : elementMap.keySet()) { + if(element.equals(elementMap.get(key))) { + toBeRemoved = key; + break; + } + } + if(toBeRemoved != null) + elementMap.remove(toBeRemoved); + } + + public ArrayList getUnlocatedElements() { + return unlocatedElements; + } + + public Element getElement(String name) { + return elementMap.get(name); + } + + public void addConnection(Connection connection) { + connections.add(connection); + if(connection.getStart() != null && + !connection.getStart().getConnections().contains(connection)) { + connection.getStart().addConnection(connection); + } + if(connection.getEnd() != null && + !connection.getEnd().getConnections().contains(connection)) { + connection.getEnd().addConnection(connection); + } + } + + public ArrayList getConnections() { + return connections; + } + + public ArrayList getSubscripts() { + return subscripts; + } + + public String getName() { + if(name == null) + return "ModelName"; + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTimeUnit() { + return timeUnit; + } + + public void setTimeUnit(String timeUnit) { + this.timeUnit = timeUnit; + } + + public String getSaveper() { + return saveper; + } + + public void setSaveper(String saveper) { + this.saveper = saveper; + } + + public double getStartTime() { + return startTime; + } + + public void setStartTime(double startTime) { + this.startTime = startTime; + } + + public double getEndTime() { + return endTime; + } + + public void setEndTime(double endTime) { + this.endTime = endTime; + } + + public double getTimeStep() { + return timeStep; + } + + public void setTimeStep(double timeStep) { + this.timeStep = timeStep; + } + + public HashMap getElementMap() { + return elementMap; + } + + public void setElementMap(HashMap elementMap) { + this.elementMap = elementMap; + } + + public void setSubscripts(ArrayList subscripts) { + this.subscripts = subscripts; + } + + public void setConnections(ArrayList connections) { + this.connections = connections; + } + + public void addView(View view) { + views.add(view); + } + + public ArrayList getViews() { + return views; + } + + /** + * Write the model to a project + * @param graph WriteGraph + * @param parent Project resource + */ + @Override + public void write(WriteGraph graph, Resource parent) { + if(parent == null || graph == null) + return; + + try { + + + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + SimulationResource simu = SimulationResource.getInstance(graph); + + Resource model = ModelUtils.createModelAt(graph, parent); + graph.claimLiteral(model, l0.HasLabel, getName()); + graph.claimLiteral(model, sr.SysdynModel_startTime, startTime); + graph.claimLiteral(model, sr.SysdynModel_stopTime, endTime); + + + Resource conf = graph.getSingleObject(model, simu.HasConfiguration); + + for(Subscript s : subscripts) { + s.write(graph, conf, 0, 0); + } + + // Create the grid n*n of views: + + double n = Math.sqrt(views.size()); + n = Math.ceil(n); + + int width = 0, height = 0; + for(View v : views) { + if(v.getWidth() > width) + width = v.getWidth(); + if(v.getHeight() > height) + height = v.getHeight(); + } + + for(int i = 0; i < n; i++) { + for(int j = 0; j < n; j++) { + int index = i * (int)n + j; + if(index < views.size()) { + View v = views.get(index); + v.setxOffset(width * j); + v.setyOffset(height * i); + v.write(graph, conf); + } + } + } + + for(Element e : unlocatedElements) { + e.write(graph, conf, 0, 0); + } + + for(Connection c : connections) { + c.write(graph, conf); + } + + for(Function f : functions) { + f.write(graph, model, 0, 0); + } + + + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/ModelControl.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/ModelControl.java new file mode 100644 index 00000000..8197c773 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/ModelControl.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; + +public class ModelControl extends Variable { + + + + @Override + public Resource getExpression(WriteGraph graph, Expression expression) + throws DatabaseException { + return null; + } + + @Override + public void write(WriteGraph graph, Resource parent, double xOffset, + double yOffset) { + // TODO Auto-generated method stub + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Stock.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Stock.java new file mode 100644 index 00000000..61f3111b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Stock.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.mdlImport.ImportUtils; + +public class Stock extends Variable { + + @Override + public Resource getExpression(WriteGraph graph, Expression expression) throws DatabaseException { + + String integralEquation = ImportUtils.escapeExpression(getIntegralParts(expression)[1]); + SysdynResource sr = SysdynResource.getInstance(graph); + Resource e = GraphUtils.create2(graph, + sr.StockExpression, + sr.StockExpression_initialEquation, integralEquation); + + return e; + } + + public String[] getIntegralParts(Expression expression) { + // Does not work, if the integral has some other logic than +inflows -outflows! + + // Parsing the possible functions. Searching ',' that divides the INTEG -function + int parenthesiscount = 0; + int location = 0; + char[] charArray = expression.getExpression().toCharArray(); + for(int i = 0; i < charArray.length; i++) { + char c = charArray[i]; + if(c == '(') + parenthesiscount++; + else if(c == ')') + parenthesiscount--; + else if(c == ',' && parenthesiscount == 1) { + location = i + 1; + break; + } + } + + String exp = expression.getExpression(); + String initialEquation = exp.substring(location, exp.lastIndexOf(')')).trim(); + String integral = exp.substring(exp.indexOf("(") + 1, location - 1).trim(); + + + return new String[] {integral, initialEquation}; + } + + @Override + public void write(WriteGraph graph, Resource parent, double xOffset, + double yOffset) { + if(parent == null || graph == null) + return; + + try { + SysdynResource sr = SysdynResource.getInstance(graph); + if(!graph.isInstanceOf(parent, sr.Configuration)) + return; + createVariable(graph, parent, sr.Stock, sr.StockSymbol, xOffset, yOffset); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Subscript.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Subscript.java new file mode 100644 index 00000000..5be6073e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Subscript.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import java.util.ArrayList; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; + +public class Subscript extends Variable { + + @Override + public Resource getExpression(WriteGraph graph, Expression expression) + throws DatabaseException { + return null; + } + + @Override + public void write(WriteGraph graph, Resource parent, double xOffset, + double yOffset) { + if(parent == null || graph == null) + return; + + try { + SysdynResource sr = SysdynResource.getInstance(graph); + if(!graph.isInstanceOf(parent, sr.Configuration)) + return; + Layer0 l0 = Layer0.getInstance(graph); + ArrayList enumerationIndexes = new ArrayList(); + if(expressions != null && expressions.get(0) != null) { + String[] indexes = expressions.get(0).getExpression().split(","); + for(String s : indexes) { + Resource ei = GraphUtils.create2(graph, + sr.EnumerationIndex, + l0.HasName, s.trim()); + enumerationIndexes.add(ei); + } + } + + Resource enumeration = GraphUtils.create2(graph, + sr.Enumeration, + l0.HasName, this.getName(), + sr.Enumeration_enumerationIndexList, ListUtils.create(graph, enumerationIndexes)); + + graph.claim(parent, l0.ConsistsOf, enumeration); + + resource = enumeration; + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Valve.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Valve.java new file mode 100644 index 00000000..620ad56b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Valve.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.mdlImport.ImportUtils; + +public class Valve extends Variable { + + @Override + public Resource getExpression(WriteGraph graph, Expression expression) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + String expressionString = ImportUtils.escapeExpression(expression.getExpression()); + Resource e = GraphUtils.create2(graph, + sr.NormalExpression, + sr.Expression_equation, expressionString.trim()); + return e; + } + + @Override + public void write(WriteGraph graph, Resource parent, double xOffset, + double yOffset) { + try { + SysdynResource sr = SysdynResource.getInstance(graph); + if(!graph.isInstanceOf(parent, sr.Configuration)) + return; + createVariable(graph, parent, sr.Valve, sr.ValveSymbol, xOffset, yOffset); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java new file mode 100644 index 00000000..f2fc13bf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import java.util.ArrayList; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.OrderedSetUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.stubs.G2DResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.mdlImport.ImportUtils; + +public abstract class Variable extends Element { + protected String units; + protected String comments; + protected ArrayList expressions; + protected ArrayList subscripts; + + private Double rangeStart, rangeEnd, rangeStep; + + protected void createVariable(WriteGraph graph, Resource configuration, Resource variableType, Resource symbolType, double xOffset, double yOffset) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + DiagramResource dr = DiagramResource.getInstance(graph); + G2DResource g2d = G2DResource.getInstance(graph); + + Resource diagram = graph.getSingleObject(configuration, mr.CompositeToDiagram); + if(diagram == null) + return; + + // Make sure at least one expression exist + if(getExpressions().isEmpty()) { + Expression e = new Expression(); + e.setExpression(""); + getExpressions().add(e); + } + + Resource variable = GraphUtils.create2(graph, + variableType, + l0.HasName, ImportUtils.escapeName(name)); + graph.claim(variable, mr.Mapped, variable); + + ArrayList expressions = new ArrayList(); + for(Expression e : getExpressions()) { + + // Get expression from the variable. They have different types + Resource expression = getExpression(graph, e); + + if(e.getRange() != null) { + graph.claimLiteral(expression, sr.Expression_arrayRange, "[" + e.getRange().trim() + "]"); + } + expressions.add(expression); + graph.claim(variable, l0.ConsistsOf, expression); + } + graph.claim(variable, sr.Variable_expressionList, ListUtils.create(graph, expressions)); + + if(subscripts != null) { + ArrayList arrayIndexes = new ArrayList(); + for(Subscript sub : subscripts) { + if(sub.getResource() != null) + arrayIndexes.add(sub.getResource()); + } + graph.claim(variable, sr.Variable_arrayIndexesList, ListUtils.create(graph, arrayIndexes)); + } + + if(units != null && units.length() > 0) + graph.claimLiteral(variable, sr.Variable_unit, units); + if(comments != null && comments.length() > 0) + graph.claimLiteral(variable, l0.HasDescription, comments); + if(rangeStart != null) + graph.claimLiteral(variable, sr.HasRangeStart, rangeStart); + if(rangeEnd != null) + graph.claimLiteral(variable, sr.HasRangeEnd, rangeEnd); + if(rangeStep != null) + graph.claimLiteral(variable, sr.HasRangeStep, rangeStep); + + graph.claim(configuration, l0.ConsistsOf, variable); + + + Resource symbol = GraphUtils.create2(graph, + symbolType, + mr.ElementToComponent, variable); + + double[] transform = {1.0, 0.0, 0.0, 1.0, x + xOffset, y + yOffset}; + graph.claimLiteral(symbol, dr.HasTransform, g2d.Transform, transform); + + OrderedSetUtils.add(graph, diagram, symbol); + + resource = variable; + } + + + public String getUnits() { + return units; + } + + public void setUnits(String units) { + this.units = units; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public ArrayList getExpressions() { + if(expressions == null) { + expressions = new ArrayList(); + } + return expressions; + } + + public void setExpressions(ArrayList expressions) { + this.expressions = expressions; + } + + public ArrayList getSubscripts() { + if(subscripts == null) + subscripts = new ArrayList(); + return subscripts; + } + + public void setSubscripts(ArrayList subscripts) { + this.subscripts = subscripts; + } + + + public Double getRangeStart() { + return rangeStart; + } + + public void setRangeStart(Double rangeStart) { + this.rangeStart = rangeStart; + } + + public Double getRangeEnd() { + return rangeEnd; + } + + public void setRangeEnd(Double rangeEnd) { + this.rangeEnd = rangeEnd; + } + + public Double getRangeStep() { + return rangeStep; + } + + public void setRangeStep(Double rangeStep) { + this.rangeStep = rangeStep; + } + + /** + * Use this to set subscripts after all elements have been read + * + * @param model The model where the variable is located + */ + public void initializeSubscripts(Model model) { + for(Expression ex : getExpressions()) { + if(ex.getRange() != null) { + + // Subscripts exist, check that subscripts -array is initialized + getSubscripts(); + + String[] elements = ex.getRange().split(","); + // Search the corresponding subscript for each element, if it has not been searched already + for(int i = 0; i < elements.length; i++) { + // The subscript has been defined, move to next + if(subscripts.size() > i) + continue; + + String element = elements[i].trim(); + for(Subscript sub : model.getSubscripts()) { + if(sub.getName().equals(element)) { + subscripts.add(sub); + break; + } + for(String index : sub.getExpressions().get(0).getExpression().split(",")) { + if(index.trim().equals(element)) { + subscripts.add(sub); + break; + } + } + // Subscript was defined for this index in previous for-loop + if(subscripts.size() == i + 1) + break; + } + } + } + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/View.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/View.java new file mode 100644 index 00000000..88fe41e6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/View.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import java.util.ArrayList; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; + +public class View implements IWriteableMDLObject { + + private int minX = 0, maxX = 0, minY = 0, maxY = 0; + private double xOffset = 0, yOffset = 0; + private String name, fontParameters; + + private ArrayList elements = new ArrayList(); + + + @Override + public void write(WriteGraph graph, Resource parent) { + xOffset = xOffset - minX; + yOffset = yOffset - minY; + for(Element e : elements) { + e.write(graph, parent, xOffset, yOffset); + } + } + + public void addElement(Element e) { + if(e instanceof Subscript || + e instanceof Function) + return; + + if(e.getX()maxX) + maxX = e.getX(); + if(e.getY()maxY) + maxY = e.getY(); + this.elements.add(e); + } + + public ArrayList getElements() { + return elements; + } + + public void setElements(ArrayList elements) { + this.elements = elements; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + public String getFontParameters() { + return fontParameters; + } + + + public void setFontParameters(String fontParameters) { + this.fontParameters = fontParameters; + } + + + public int getMinX() { + return minX; + } + + public void setMinX(int minX) { + this.minX = minX; + } + + public int getMaxX() { + return maxX; + } + + public void setMaxX(int maxX) { + this.maxX = maxX; + } + + public int getMinY() { + return minY; + } + + public void setMinY(int minY) { + this.minY = minY; + } + + public int getMaxY() { + return maxY; + } + + public void setMaxY(int maxY) { + this.maxY = maxY; + } + + public double getxOffset() { + return xOffset; + } + + public void setxOffset(double xOffset) { + this.xOffset = xOffset; + } + + public double getyOffset() { + return yOffset; + } + + public void setyOffset(double yOffset) { + this.yOffset = yOffset; + } + + public int getWidth() { + return maxX - minX; + } + + public int getHeight() { + return maxY - minY; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelParser.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelParser.java new file mode 100644 index 00000000..eb87c0d9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelParser.java @@ -0,0 +1,3885 @@ +/* Generated By:JavaCC: Do not edit this line. ModelParser.java */ +package org.simantics.sysdyn.modelParser; + +import java.util.ArrayList; + +@SuppressWarnings({"unused", "serial"}) +public class ModelParser implements ModelParserConstants { + + private ArrayList inputs = new ArrayList(); + private ArrayList outputs = new ArrayList(); + + private enum InterfaceVariableType + { + INPUT, OUTPUT, OTHER + } + + public class Parameter + { + public String name; + public boolean optional; + public String description; + public String type; + + public Parameter() + { + name = new String(""); + optional = false; + description = null; + type = null; + } + } + + public ArrayList getInputs() + { + return inputs; + } + + public ArrayList getOutputs() + { + return outputs; + } + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + final public void parse() throws ParseException { + jj_input_stream.setTabSize(1); + stored_definition(); + jj_consume_token(0); + } + +/*** Stored Definition - Within ************************************/ + final public void stored_definition() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 53: + jj_consume_token(53); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + name(); + break; + default: + jj_la1[0] = jj_gen; + ; + } + jj_consume_token(70); + break; + default: + jj_la1[1] = jj_gen; + ; + } + label_1: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 11: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + ; + break; + default: + jj_la1[2] = jj_gen; + break label_1; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 11: + jj_consume_token(11); + break; + default: + jj_la1[3] = jj_gen; + ; + } + class_definition(); + jj_consume_token(70); + } + } + +/*** Class Definition **********************************************/ + final public void class_definition() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 30: + jj_consume_token(30); + break; + default: + jj_la1[4] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 47: + jj_consume_token(47); + break; + default: + jj_la1[5] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 34: + jj_consume_token(34); + break; + case 7: + jj_consume_token(7); + break; + case 61: + jj_consume_token(61); + break; + case 24: + jj_consume_token(24); + break; + case 44: + case 50: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 50: + jj_consume_token(50); + break; + default: + jj_la1[6] = jj_gen; + ; + } + jj_consume_token(44); + break; + case 38: + jj_consume_token(38); + break; + case 37: + jj_consume_token(37); + break; + case 26: + jj_consume_token(26); + break; + case 17: + jj_consume_token(17); + break; + case 94: + jj_consume_token(94); + break; + case 95: + jj_consume_token(95); + break; + default: + jj_la1[7] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + class_specifier(); + } + + final public void class_specifier() throws ParseException { + if (jj_2_1(2)) { + jj_consume_token(IDENT); + string_comment(); + composition(); + jj_consume_token(35); + jj_consume_token(IDENT); + } else if (jj_2_2(2)) { + jj_consume_token(IDENT); + jj_consume_token(88); + base_prefix(); + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[8] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + break; + default: + jj_la1[9] = jj_gen; + ; + } + comment(); + } else if (jj_2_3(3)) { + jj_consume_token(IDENT); + jj_consume_token(88); + jj_consume_token(40); + jj_consume_token(62); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + enum_list(); + break; + default: + jj_la1[10] = jj_gen; + ; + } + jj_consume_token(63); + comment(); + } else if (jj_2_4(3)) { + jj_consume_token(IDENT); + jj_consume_token(88); + jj_consume_token(58); + jj_consume_token(62); + name(); + jj_consume_token(71); + jj_consume_token(IDENT); + label_2: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[11] = jj_gen; + break label_2; + } + jj_consume_token(71); + jj_consume_token(IDENT); + } + jj_consume_token(63); + comment(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 55: + jj_consume_token(55); + jj_consume_token(IDENT); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + break; + default: + jj_la1[12] = jj_gen; + ; + } + string_comment(); + composition(); + jj_consume_token(35); + jj_consume_token(IDENT); + break; + default: + jj_la1[13] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + + final public void base_prefix() throws ParseException { + type_prefix(); + } + + final public void enum_list() throws ParseException { + enumeration_literal(); + label_3: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[14] = jj_gen; + break label_3; + } + jj_consume_token(71); + enumeration_literal(); + } + } + + final public void enumeration_literal() throws ParseException { + jj_consume_token(IDENT); + comment(); + } + + final public void parse_composition() throws ParseException { + composition(); + jj_consume_token(0); + } + + final public void composition() throws ParseException { + element_list(); + label_4: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 4: + case 45: + case 46: + case 52: + case 57: + ; + break; + default: + jj_la1[15] = jj_gen; + break label_4; + } + if (jj_2_5(2)) { + jj_consume_token(57); + element_list(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 52: + jj_consume_token(52); + element_list(); + break; + case 45: + case 46: + equation_section(); + break; + case 4: + algorithm_section(); + break; + default: + jj_la1[16] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 59: + jj_consume_token(59); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case STRING: + language_specification(); + break; + default: + jj_la1[17] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + external_function_call(); + break; + default: + jj_la1[18] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 14: + annotation(); + break; + default: + jj_la1[19] = jj_gen; + ; + } + jj_consume_token(70); + break; + default: + jj_la1[20] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 14: + annotation(); + jj_consume_token(70); + break; + default: + jj_la1[21] = jj_gen; + ; + } + } + + final public void language_specification() throws ParseException { + jj_consume_token(STRING); + } + + final public void external_function_call() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + component_reference(); + jj_consume_token(88); + break; + default: + jj_la1[22] = jj_gen; + ; + } + jj_consume_token(IDENT); + jj_consume_token(62); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression_list(); + break; + default: + jj_la1[23] = jj_gen; + ; + } + jj_consume_token(63); + } + + final public void element_list() throws ParseException { + label_5: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + case 7: + case 8: + case 11: + case 13: + case 16: + case 17: + case 23: + case 24: + case 26: + case 27: + case 30: + case 32: + case 34: + case 36: + case 37: + case 38: + case 42: + case 44: + case 47: + case 49: + case 50: + case 51: + case 55: + case 56: + case 61: + case 68: + case IDENT: + case 94: + case 95: + ; + break; + default: + jj_la1[24] = jj_gen; + break label_5; + } + element(); + jj_consume_token(70); + } + } + + final public void element() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 36: + import_clause(); + break; + case 55: + extends_clause(); + break; + case 5: + case 7: + case 8: + case 11: + case 13: + case 16: + case 17: + case 23: + case 24: + case 26: + case 27: + case 30: + case 32: + case 34: + case 37: + case 38: + case 42: + case 44: + case 47: + case 49: + case 50: + case 51: + case 56: + case 61: + case 68: + case IDENT: + case 94: + case 95: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 8: + jj_consume_token(8); + break; + default: + jj_la1[25] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 11: + jj_consume_token(11); + break; + default: + jj_la1[26] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 51: + jj_consume_token(51); + break; + default: + jj_la1[27] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 27: + jj_consume_token(27); + break; + default: + jj_la1[28] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + case 7: + case 16: + case 17: + case 23: + case 24: + case 26: + case 30: + case 32: + case 34: + case 37: + case 38: + case 42: + case 44: + case 47: + case 49: + case 50: + case 56: + case 61: + case 68: + case IDENT: + case 94: + case 95: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + class_definition(); + break; + case 5: + case 16: + case 23: + case 32: + case 42: + case 49: + case 56: + case 68: + case IDENT: + component_clause(); + break; + default: + jj_la1[29] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + case 13: + jj_consume_token(13); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + class_definition(); + break; + case 5: + case 16: + case 23: + case 32: + case 42: + case 49: + case 56: + case 68: + case IDENT: + component_clause(); + break; + default: + jj_la1[30] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 54: + constraining_clause(); + comment(); + break; + default: + jj_la1[31] = jj_gen; + ; + } + break; + default: + jj_la1[32] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[33] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void import_clause() throws ParseException { + jj_consume_token(36); + if (jj_2_6(2)) { + jj_consume_token(IDENT); + jj_consume_token(88); + name(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + jj_consume_token(68); + jj_consume_token(82); + break; + default: + jj_la1[34] = jj_gen; + ; + } + break; + default: + jj_la1[35] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + comment(); + } + +/*** Extends *******************************************************/ + final public void extends_clause() throws ParseException { + jj_consume_token(55); + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + break; + default: + jj_la1[36] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 14: + annotation(); + break; + default: + jj_la1[37] = jj_gen; + ; + } + } + + final public void constraining_clause() throws ParseException { + jj_consume_token(54); + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + break; + default: + jj_la1[38] = jj_gen; + ; + } + } + +/*** Component Clause **********************************************/ + final public void component_clause() throws ParseException { + InterfaceVariableType ioType = InterfaceVariableType.OTHER; + String typeSpecifier = ""; + //String arraySubscripts = null; + ArrayList componentList = new ArrayList(); + ioType = type_prefix(); + typeSpecifier = type_specifier(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[39] = jj_gen; + ; + } + componentList = component_list(); + if (ioType == InterfaceVariableType.INPUT) { + for (Parameter input : componentList) { + input.type = typeSpecifier; + inputs.add(input); + } + } else if (ioType == InterfaceVariableType.OUTPUT) { + for (Parameter output : componentList) { + output.type = typeSpecifier; + outputs.add(output); + } + } + } + + final public InterfaceVariableType type_prefix() throws ParseException { + InterfaceVariableType type = InterfaceVariableType.OTHER; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 16: + case 23: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 16: + jj_consume_token(16); + break; + case 23: + jj_consume_token(23); + break; + default: + jj_la1[40] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[41] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + case 42: + case 49: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + jj_consume_token(5); + break; + case 42: + jj_consume_token(42); + break; + case 49: + jj_consume_token(49); + break; + default: + jj_la1[42] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[43] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 32: + case 56: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 32: + jj_consume_token(32); + type = InterfaceVariableType.OUTPUT; + break; + case 56: + jj_consume_token(56); + type = InterfaceVariableType.INPUT; + break; + default: + jj_la1[44] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[45] = jj_gen; + ; + } + {if (true) return type;} + throw new Error("Missing return statement in function"); + } + + final public String type_specifier() throws ParseException { + String ret = new String(""); + ret = name(); + {if (true) return ret;} + throw new Error("Missing return statement in function"); + } + + final public ArrayList component_list() throws ParseException { + ArrayList ret = new ArrayList(); + Parameter temp; + // component_declaration { "," component_declaration } + temp = component_declaration(); + ret.add(temp); + label_6: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[46] = jj_gen; + break label_6; + } + jj_consume_token(71); + temp = component_declaration(); + ret.add(temp); + } + {if (true) return ret;} + throw new Error("Missing return statement in function"); + } + + final public Parameter component_declaration() throws ParseException { + Parameter ret; + String temp = ""; + // declaration [ conditional_attribute ] comment + ret = declaration(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 31: + conditional_attribute(); + break; + default: + jj_la1[47] = jj_gen; + ; + } + ret.description = comment(); + {if (true) return ret;} + throw new Error("Missing return statement in function"); + } + + final public void conditional_attribute() throws ParseException { + jj_consume_token(31); + expression(); + } + + final public Parameter declaration() throws ParseException { + // Parameter here without comment yet. + Parameter ret = new Parameter(); + jj_consume_token(IDENT); + ret.name = new String(token.image); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[48] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + case 88: + case 89: + ret.optional = modification(); + break; + default: + jj_la1[49] = jj_gen; + ; + } + {if (true) return ret;} + throw new Error("Missing return statement in function"); + } + +/*** Modification **********************************************/ + final public boolean modification() throws ParseException { + boolean optional = false; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + class_modification(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 88: + jj_consume_token(88); + expression(); + break; + default: + jj_la1[50] = jj_gen; + ; + } + break; + case 88: + jj_consume_token(88); + expression(); + optional = true; + break; + case 89: + jj_consume_token(89); + expression(); + optional = true; + break; + default: + jj_la1[51] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + {if (true) return optional;} + throw new Error("Missing return statement in function"); + } + + final public void class_modification() throws ParseException { + jj_consume_token(62); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 8: + case 10: + case 11: + case 13: + case 68: + case IDENT: + argument_list(); + break; + default: + jj_la1[52] = jj_gen; + ; + } + jj_consume_token(63); + } + + final public void argument_list() throws ParseException { + argument(); + label_7: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[53] = jj_gen; + break label_7; + } + jj_consume_token(71); + argument(); + } + } + + final public void argument() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 10: + case 11: + case 13: + case 68: + case IDENT: + element_modification_or_replaceable(); + break; + case 8: + element_redeclaration(); + break; + default: + jj_la1[54] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void element_modification_or_replaceable() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 10: + jj_consume_token(10); + break; + default: + jj_la1[55] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 11: + jj_consume_token(11); + break; + default: + jj_la1[56] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + element_modification(); + break; + case 13: + element_replaceable(); + break; + default: + jj_la1[57] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void element_modification() throws ParseException { + name(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 62: + case 88: + case 89: + modification(); + break; + default: + jj_la1[58] = jj_gen; + ; + } + string_comment(); + } + + final public void element_redeclaration() throws ParseException { + jj_consume_token(8); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 10: + jj_consume_token(10); + break; + default: + jj_la1[59] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 11: + jj_consume_token(11); + break; + default: + jj_la1[60] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 5: + case 7: + case 16: + case 17: + case 23: + case 24: + case 26: + case 30: + case 32: + case 34: + case 37: + case 38: + case 42: + case 44: + case 47: + case 49: + case 50: + case 56: + case 61: + case 68: + case IDENT: + case 94: + case 95: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + class_definition(); + break; + case 5: + case 16: + case 23: + case 32: + case 42: + case 49: + case 56: + case 68: + case IDENT: + component_clause1(); + break; + default: + jj_la1[61] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + case 13: + element_replaceable(); + break; + default: + jj_la1[62] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void element_replaceable() throws ParseException { + jj_consume_token(13); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 7: + case 17: + case 24: + case 26: + case 30: + case 34: + case 37: + case 38: + case 44: + case 47: + case 50: + case 61: + case 94: + case 95: + class_definition(); + break; + case 5: + case 16: + case 23: + case 32: + case 42: + case 49: + case 56: + case 68: + case IDENT: + component_clause1(); + break; + default: + jj_la1[63] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 54: + constraining_clause(); + break; + default: + jj_la1[64] = jj_gen; + ; + } + } + + final public void component_clause1() throws ParseException { + type_prefix(); + type_specifier(); + component_declaration1(); + } + + final public void component_declaration1() throws ParseException { + declaration(); + comment(); + } + +/*** Equations *************************************************/ + final public void equation_section() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 46: + jj_consume_token(46); + break; + default: + jj_la1[65] = jj_gen; + ; + } + jj_consume_token(45); + label_8: + while (true) { + if (jj_2_7(2)) { + ; + } else { + break label_8; + } + equation(); + jj_consume_token(70); + } + } + + final public void algorithm_section() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 46: + jj_consume_token(46); + break; + default: + jj_la1[66] = jj_gen; + ; + } + jj_consume_token(4); + label_9: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[67] = jj_gen; + break label_9; + } + statement(); + jj_consume_token(70); + } + } + + final public void equation() throws ParseException { + if (jj_2_8(3)) { + simple_expression(); + jj_consume_token(88); + expression(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 31: + if_equation(); + break; + case 21: + for_equation(); + break; + case 39: + connect_clause(); + break; + case 43: + when_equation(); + break; + case IDENT: + jj_consume_token(IDENT); + function_call_args(); + break; + default: + jj_la1[68] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + comment(); + } + + final public void statement() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + component_reference(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 89: + jj_consume_token(89); + expression(); + break; + case 62: + function_call_args(); + break; + default: + jj_la1[69] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + case 62: + jj_consume_token(62); + output_expression_list(); + jj_consume_token(63); + jj_consume_token(89); + component_reference(); + function_call_args(); + break; + case 29: + jj_consume_token(29); + break; + case 18: + jj_consume_token(18); + break; + case 31: + if_statement(); + break; + case 21: + for_statement(); + break; + case 48: + while_statement(); + break; + case 43: + when_statement(); + break; + default: + jj_la1[70] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + comment(); + } + + final public void if_equation() throws ParseException { + jj_consume_token(31); + expression(); + jj_consume_token(28); + label_10: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[71] = jj_gen; + break label_10; + } + equation(); + jj_consume_token(70); + } + label_11: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[72] = jj_gen; + break label_11; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + label_12: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[73] = jj_gen; + break label_12; + } + equation(); + jj_consume_token(70); + } + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 15: + jj_consume_token(15); + label_13: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[74] = jj_gen; + break label_13; + } + equation(); + jj_consume_token(70); + } + break; + default: + jj_la1[75] = jj_gen; + ; + } + jj_consume_token(35); + jj_consume_token(31); + } + + final public void if_statement() throws ParseException { + jj_consume_token(31); + expression(); + jj_consume_token(28); + label_14: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[76] = jj_gen; + break label_14; + } + statement(); + jj_consume_token(70); + } + label_15: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[77] = jj_gen; + break label_15; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + label_16: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[78] = jj_gen; + break label_16; + } + statement(); + jj_consume_token(70); + } + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 15: + jj_consume_token(15); + label_17: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[79] = jj_gen; + break label_17; + } + statement(); + jj_consume_token(70); + } + break; + default: + jj_la1[80] = jj_gen; + ; + } + jj_consume_token(35); + jj_consume_token(31); + } + + final public void for_equation() throws ParseException { + jj_consume_token(21); + for_indices(); + jj_consume_token(60); + label_18: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[81] = jj_gen; + break label_18; + } + equation(); + jj_consume_token(70); + } + jj_consume_token(35); + jj_consume_token(21); + } + + final public void for_statement() throws ParseException { + jj_consume_token(21); + for_indices(); + jj_consume_token(60); + label_19: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[82] = jj_gen; + break label_19; + } + statement(); + jj_consume_token(70); + } + jj_consume_token(35); + jj_consume_token(21); + } + + final public void for_indices() throws ParseException { + for_index(); + label_20: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[83] = jj_gen; + break label_20; + } + jj_consume_token(71); + for_index(); + } + } + + final public void for_index() throws ParseException { + jj_consume_token(IDENT); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 41: + jj_consume_token(41); + expression(); + break; + default: + jj_la1[84] = jj_gen; + ; + } + } + + final public void while_statement() throws ParseException { + jj_consume_token(48); + expression(); + jj_consume_token(60); + label_21: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[85] = jj_gen; + break label_21; + } + statement(); + jj_consume_token(70); + } + jj_consume_token(35); + jj_consume_token(48); + } + + final public void when_equation() throws ParseException { + jj_consume_token(43); + expression(); + jj_consume_token(28); + label_22: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[86] = jj_gen; + break label_22; + } + equation(); + jj_consume_token(70); + } + label_23: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 25: + ; + break; + default: + jj_la1[87] = jj_gen; + break label_23; + } + jj_consume_token(25); + expression(); + jj_consume_token(28); + label_24: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 21: + case 31: + case 33: + case 35: + case 39: + case 43: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + ; + break; + default: + jj_la1[88] = jj_gen; + break label_24; + } + equation(); + jj_consume_token(70); + } + } + jj_consume_token(35); + jj_consume_token(43); + } + + final public void when_statement() throws ParseException { + jj_consume_token(43); + expression(); + jj_consume_token(28); + label_25: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[89] = jj_gen; + break label_25; + } + statement(); + jj_consume_token(70); + } + label_26: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 25: + ; + break; + default: + jj_la1[90] = jj_gen; + break label_26; + } + jj_consume_token(25); + expression(); + jj_consume_token(28); + label_27: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + case 21: + case 29: + case 31: + case 43: + case 48: + case 62: + case 68: + case IDENT: + ; + break; + default: + jj_la1[91] = jj_gen; + break label_27; + } + statement(); + jj_consume_token(70); + } + } + jj_consume_token(35); + jj_consume_token(43); + } + + final public void connect_clause() throws ParseException { + jj_consume_token(39); + jj_consume_token(62); + component_reference(); + jj_consume_token(71); + component_reference(); + jj_consume_token(63); + } + +/*** Expressions ***************************************************/ + final public void expr() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + simple_expression(); + jj_consume_token(0); + break; + case 31: + jj_consume_token(31); + expression(); + jj_consume_token(28); + expression(); + label_28: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[92] = jj_gen; + break label_28; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + expression(); + } + jj_consume_token(15); + expression(); + jj_consume_token(0); + break; + default: + jj_la1[93] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void expression() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + simple_expression(); + break; + case 31: + jj_consume_token(31); + expression(); + jj_consume_token(28); + expression(); + label_29: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[94] = jj_gen; + break label_29; + } + jj_consume_token(20); + expression(); + jj_consume_token(28); + expression(); + } + jj_consume_token(15); + expression(); + break; + default: + jj_la1[95] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void simple_expression() throws ParseException { + logical_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + logical_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + logical_expression(); + break; + default: + jj_la1[96] = jj_gen; + ; + } + break; + default: + jj_la1[97] = jj_gen; + ; + } + } + + final public void logical_expression() throws ParseException { + logical_term(); + label_30: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 22: + ; + break; + default: + jj_la1[98] = jj_gen; + break label_30; + } + jj_consume_token(22); + logical_term(); + } + } + + final public void logical_term() throws ParseException { + logical_factor(); + label_31: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 9: + ; + break; + default: + jj_la1[99] = jj_gen; + break label_31; + } + jj_consume_token(9); + logical_factor(); + } + } + + final public void logical_factor() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 12: + jj_consume_token(12); + break; + default: + jj_la1[100] = jj_gen; + ; + } + relation(); + } + + final public void relation() throws ParseException { + arithmetic_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + rel_op(); + arithmetic_expression(); + break; + default: + jj_la1[101] = jj_gen; + ; + } + } + + final public void rel_op() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 72: + jj_consume_token(72); + break; + case 73: + jj_consume_token(73); + break; + case 74: + jj_consume_token(74); + break; + case 75: + jj_consume_token(75); + break; + case 76: + jj_consume_token(76); + break; + case 77: + jj_consume_token(77); + break; + default: + jj_la1[102] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void arithmetic_expression() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 78: + case 79: + case 80: + case 81: + add_op(); + break; + default: + jj_la1[103] = jj_gen; + ; + } + term(); + label_32: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 78: + case 79: + case 80: + case 81: + ; + break; + default: + jj_la1[104] = jj_gen; + break label_32; + } + add_op(); + term(); + } + } + + final public void add_op() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 78: + jj_consume_token(78); + break; + case 79: + jj_consume_token(79); + break; + case 80: + jj_consume_token(80); + break; + case 81: + jj_consume_token(81); + break; + default: + jj_la1[105] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void term() throws ParseException { + factor(); + label_33: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 82: + case 83: + case 84: + case 85: + ; + break; + default: + jj_la1[106] = jj_gen; + break label_33; + } + mul_op(); + factor(); + } + } + + final public void mul_op() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 82: + jj_consume_token(82); + break; + case 83: + jj_consume_token(83); + break; + case 84: + jj_consume_token(84); + break; + case 85: + jj_consume_token(85); + break; + default: + jj_la1[107] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public void factor() throws ParseException { + primary(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 86: + case 87: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 86: + jj_consume_token(86); + break; + case 87: + jj_consume_token(87); + primary(); + break; + default: + jj_la1[108] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[109] = jj_gen; + ; + } + } + + final public void primary() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case UNSIGNED_NUMBER: + jj_consume_token(UNSIGNED_NUMBER); + break; + case UNSIGNED_INTEGER: + jj_consume_token(UNSIGNED_INTEGER); + break; + case STRING: + jj_consume_token(STRING); + break; + case 6: + jj_consume_token(6); + break; + case 33: + jj_consume_token(33); + break; + default: + jj_la1[112] = jj_gen; + if (jj_2_9(2147483647)) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + name(); + break; + case 58: + jj_consume_token(58); + break; + case 46: + jj_consume_token(46); + break; + default: + jj_la1[110] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + function_call_args(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + case IDENT: + component_reference(); + break; + case 62: + jj_consume_token(62); + expression(); + jj_consume_token(63); + break; + case 66: + jj_consume_token(66); + expression_list(); + label_34: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 70: + ; + break; + default: + jj_la1[111] = jj_gen; + break label_34; + } + jj_consume_token(70); + expression_list(); + } + jj_consume_token(67); + break; + case 64: + jj_consume_token(64); + function_arguments(); + jj_consume_token(65); + break; + case 35: + jj_consume_token(35); + break; + default: + jj_la1[113] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } + + final public String name() throws ParseException { + String ret = new String(""); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + jj_consume_token(68); + ret += "."; + break; + default: + jj_la1[114] = jj_gen; + ; + } + jj_consume_token(IDENT); + ret += token.image; + label_35: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + ; + break; + default: + jj_la1[115] = jj_gen; + break label_35; + } + jj_consume_token(68); + ret += "."; + jj_consume_token(IDENT); + ret += token.image; + } + {if (true) return ret;} + throw new Error("Missing return statement in function"); + } + + final public void component_reference() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + jj_consume_token(68); + break; + default: + jj_la1[116] = jj_gen; + ; + } + jj_consume_token(IDENT); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[117] = jj_gen; + ; + } + label_36: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + ; + break; + default: + jj_la1[118] = jj_gen; + break label_36; + } + jj_consume_token(68); + jj_consume_token(IDENT); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + array_subscripts(); + break; + default: + jj_la1[119] = jj_gen; + ; + } + } + } + + final public void function_call_args() throws ParseException { + jj_consume_token(62); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + function_arguments(); + break; + default: + jj_la1[120] = jj_gen; + ; + } + jj_consume_token(63); + } + + final public void function_arguments() throws ParseException { + if (jj_2_10(2)) { + expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 21: + case 71: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + jj_consume_token(71); + function_arguments(); + break; + case 21: + jj_consume_token(21); + for_indices(); + break; + default: + jj_la1[121] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[122] = jj_gen; + ; + } + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + named_arguments(); + break; + default: + jj_la1[123] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + + final public void named_arguments() throws ParseException { + named_argument(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + jj_consume_token(71); + named_arguments(); + break; + default: + jj_la1[124] = jj_gen; + ; + } + } + + final public void named_argument() throws ParseException { + jj_consume_token(IDENT); + jj_consume_token(88); + expression(); + } + + final public void output_expression_list() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[125] = jj_gen; + ; + } + label_37: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[126] = jj_gen; + break label_37; + } + jj_consume_token(71); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[127] = jj_gen; + ; + } + } + } + + final public void expression_list() throws ParseException { + expression(); + label_38: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[128] = jj_gen; + break label_38; + } + jj_consume_token(71); + expression(); + } + } + + final public void array_subscripts() throws ParseException { + jj_consume_token(66); + subscript(); + label_39: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[129] = jj_gen; + break label_39; + } + jj_consume_token(71); + subscript(); + } + jj_consume_token(67); + } + + final public void subscript() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + break; + case 6: + case 12: + case 31: + case 33: + case 35: + case 46: + case 58: + case 62: + case 64: + case 66: + case 68: + case 78: + case 79: + case 80: + case 81: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[130] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + final public String comment() throws ParseException { + String ret; + // string_comment [ annotation ] + ret = string_comment(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 14: + annotation(); + break; + default: + jj_la1[131] = jj_gen; + ; + } + {if (true) return ret;} + throw new Error("Missing return statement in function"); + } + + final public String string_comment() throws ParseException { + String ret = null; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case STRING: + jj_consume_token(STRING); + ret = new String(token.image); + label_40: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 78: + ; + break; + default: + jj_la1[132] = jj_gen; + break label_40; + } + jj_consume_token(78); + ret += "+"; + jj_consume_token(STRING); + ret += token.image; + } + break; + default: + jj_la1[133] = jj_gen; + ; + } + {if (true) return ret;} + throw new Error("Missing return statement in function"); + } + + final public void annotation() throws ParseException { + jj_consume_token(14); + class_modification(); + } + + private boolean jj_2_1(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_1(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(0, xla); } + } + + private boolean jj_2_2(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_2(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(1, xla); } + } + + private boolean jj_2_3(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_3(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(2, xla); } + } + + private boolean jj_2_4(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_4(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(3, xla); } + } + + private boolean jj_2_5(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_5(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(4, xla); } + } + + private boolean jj_2_6(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_6(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(5, xla); } + } + + private boolean jj_2_7(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_7(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(6, xla); } + } + + private boolean jj_2_8(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_8(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(7, xla); } + } + + private boolean jj_2_9(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_9(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(8, xla); } + } + + private boolean jj_2_10(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_10(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(9, xla); } + } + + private boolean jj_3R_50() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_5()) { + jj_scanpos = xsp; + if (jj_3R_66()) { + jj_scanpos = xsp; + if (jj_3R_67()) { + jj_scanpos = xsp; + if (jj_3R_68()) return true; + } + } + } + return false; + } + + private boolean jj_3_5() { + if (jj_scan_token(57)) return true; + if (jj_3R_43()) return true; + return false; + } + + private boolean jj_3R_42() { + if (jj_3R_43()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_50()) { jj_scanpos = xsp; break; } + } + xsp = jj_scanpos; + if (jj_3R_51()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_52()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_74() { + if (jj_scan_token(43)) return true; + if (jj_3R_46()) return true; + return false; + } + + private boolean jj_3R_138() { + if (jj_3R_46()) return true; + return false; + } + + private boolean jj_3R_136() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(69)) { + jj_scanpos = xsp; + if (jj_3R_138()) return true; + } + return false; + } + + private boolean jj_3R_132() { + if (jj_scan_token(71)) return true; + return false; + } + + private boolean jj_3R_104() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(50)) jj_scanpos = xsp; + if (jj_scan_token(44)) return true; + return false; + } + + private boolean jj_3R_134() { + if (jj_scan_token(66)) return true; + if (jj_3R_136()) return true; + return false; + } + + private boolean jj_3R_131() { + if (jj_scan_token(68)) return true; + if (jj_scan_token(IDENT)) return true; + return false; + } + + private boolean jj_3R_64() { + if (jj_scan_token(71)) return true; + return false; + } + + private boolean jj_3R_48() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_64()) { + jj_scanpos = xsp; + if (jj_3R_65()) return true; + } + return false; + } + + private boolean jj_3R_92() { + if (jj_scan_token(IDENT)) return true; + return false; + } + + private boolean jj_3R_126() { + if (jj_3R_46()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_132()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_85() { + if (jj_3R_92()) return true; + return false; + } + + private boolean jj_3R_137() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + return false; + } + + private boolean jj_3_4() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + if (jj_scan_token(58)) return true; + return false; + } + + private boolean jj_3_3() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + if (jj_scan_token(40)) return true; + return false; + } + + private boolean jj_3_2() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + return false; + } + + private boolean jj_3_1() { + if (jj_scan_token(IDENT)) return true; + if (jj_3R_41()) return true; + if (jj_3R_42()) return true; + if (jj_scan_token(35)) return true; + return false; + } + + private boolean jj_3R_135() { + if (jj_3R_137()) return true; + return false; + } + + private boolean jj_3R_130() { + if (jj_3R_134()) return true; + return false; + } + + private boolean jj_3R_133() { + if (jj_3R_135()) return true; + return false; + } + + private boolean jj_3R_124() { + if (jj_3R_63()) return true; + return false; + } + + private boolean jj_3R_128() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_10()) { + jj_scanpos = xsp; + if (jj_3R_133()) return true; + } + return false; + } + + private boolean jj_3R_72() { + if (jj_scan_token(21)) return true; + if (jj_3R_85()) return true; + return false; + } + + private boolean jj_3_10() { + if (jj_3R_46()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_48()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_129() { + if (jj_3R_128()) return true; + return false; + } + + private boolean jj_3R_75() { + if (jj_scan_token(62)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_129()) jj_scanpos = xsp; + if (jj_scan_token(63)) return true; + return false; + } + + private boolean jj_3R_98() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(30)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(47)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(34)) { + jj_scanpos = xsp; + if (jj_scan_token(7)) { + jj_scanpos = xsp; + if (jj_scan_token(61)) { + jj_scanpos = xsp; + if (jj_scan_token(24)) { + jj_scanpos = xsp; + if (jj_3R_104()) { + jj_scanpos = xsp; + if (jj_scan_token(38)) { + jj_scanpos = xsp; + if (jj_scan_token(37)) { + jj_scanpos = xsp; + if (jj_scan_token(26)) { + jj_scanpos = xsp; + if (jj_scan_token(17)) { + jj_scanpos = xsp; + if (jj_scan_token(94)) { + jj_scanpos = xsp; + if (jj_scan_token(95)) return true; + } + } + } + } + } + } + } + } + } + } + return false; + } + + private boolean jj_3R_125() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(68)) jj_scanpos = xsp; + if (jj_scan_token(IDENT)) return true; + xsp = jj_scanpos; + if (jj_3R_130()) jj_scanpos = xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_131()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_127() { + if (jj_scan_token(70)) return true; + return false; + } + + private boolean jj_3R_79() { + if (jj_scan_token(68)) return true; + if (jj_scan_token(IDENT)) return true; + return false; + } + + private boolean jj_3R_78() { + if (jj_scan_token(68)) return true; + return false; + } + + private boolean jj_3R_63() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_78()) jj_scanpos = xsp; + if (jj_scan_token(IDENT)) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_79()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_47() { + if (jj_3R_63()) return true; + return false; + } + + private boolean jj_3_9() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_47()) { + jj_scanpos = xsp; + if (jj_scan_token(58)) { + jj_scanpos = xsp; + if (jj_scan_token(46)) return true; + } + } + if (jj_scan_token(62)) return true; + return false; + } + + private boolean jj_3R_123() { + if (jj_scan_token(87)) return true; + if (jj_3R_113()) return true; + return false; + } + + private boolean jj_3R_106() { + if (jj_3R_63()) return true; + return false; + } + + private boolean jj_3R_114() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(86)) { + jj_scanpos = xsp; + if (jj_3R_123()) return true; + } + return false; + } + + private boolean jj_3R_71() { + if (jj_scan_token(31)) return true; + if (jj_3R_46()) return true; + return false; + } + + private boolean jj_3R_122() { + if (jj_scan_token(64)) return true; + if (jj_3R_128()) return true; + if (jj_scan_token(65)) return true; + return false; + } + + private boolean jj_3R_121() { + if (jj_scan_token(66)) return true; + if (jj_3R_126()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_127()) { jj_scanpos = xsp; break; } + } + if (jj_scan_token(67)) return true; + return false; + } + + private boolean jj_3R_117() { + if (jj_scan_token(56)) return true; + return false; + } + + private boolean jj_3R_120() { + if (jj_scan_token(62)) return true; + if (jj_3R_46()) return true; + if (jj_scan_token(63)) return true; + return false; + } + + private boolean jj_3R_118() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_124()) { + jj_scanpos = xsp; + if (jj_scan_token(58)) { + jj_scanpos = xsp; + if (jj_scan_token(46)) return true; + } + } + if (jj_3R_75()) return true; + return false; + } + + private boolean jj_3R_119() { + if (jj_3R_125()) return true; + return false; + } + + private boolean jj_3R_116() { + if (jj_scan_token(32)) return true; + return false; + } + + private boolean jj_3R_113() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(93)) { + jj_scanpos = xsp; + if (jj_scan_token(92)) { + jj_scanpos = xsp; + if (jj_scan_token(91)) { + jj_scanpos = xsp; + if (jj_scan_token(6)) { + jj_scanpos = xsp; + if (jj_scan_token(33)) { + jj_scanpos = xsp; + if (jj_3R_118()) { + jj_scanpos = xsp; + if (jj_3R_119()) { + jj_scanpos = xsp; + if (jj_3R_120()) { + jj_scanpos = xsp; + if (jj_3R_121()) { + jj_scanpos = xsp; + if (jj_3R_122()) { + jj_scanpos = xsp; + if (jj_scan_token(35)) return true; + } + } + } + } + } + } + } + } + } + } + return false; + } + + private boolean jj_3R_112() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_116()) { + jj_scanpos = xsp; + if (jj_3R_117()) return true; + } + return false; + } + + private boolean jj_3R_111() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(5)) { + jj_scanpos = xsp; + if (jj_scan_token(42)) { + jj_scanpos = xsp; + if (jj_scan_token(49)) return true; + } + } + return false; + } + + private boolean jj_3R_110() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(16)) { + jj_scanpos = xsp; + if (jj_scan_token(23)) return true; + } + return false; + } + + private boolean jj_3R_105() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_110()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_111()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_112()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_108() { + if (jj_3R_113()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_114()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_109() { + if (jj_3R_115()) return true; + if (jj_3R_108()) return true; + return false; + } + + private boolean jj_3R_68() { + if (jj_3R_81()) return true; + return false; + } + + private boolean jj_3R_102() { + if (jj_3R_107()) return true; + if (jj_3R_101()) return true; + return false; + } + + private boolean jj_3R_97() { + if (jj_3R_103()) return true; + if (jj_3R_96()) return true; + return false; + } + + private boolean jj_3R_115() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(82)) { + jj_scanpos = xsp; + if (jj_scan_token(83)) { + jj_scanpos = xsp; + if (jj_scan_token(84)) { + jj_scanpos = xsp; + if (jj_scan_token(85)) return true; + } + } + } + return false; + } + + private boolean jj_3R_101() { + if (jj_3R_108()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_109()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_58() { + if (jj_scan_token(IDENT)) return true; + if (jj_3R_75()) return true; + return false; + } + + private boolean jj_3R_57() { + if (jj_3R_74()) return true; + return false; + } + + private boolean jj_3R_56() { + if (jj_3R_73()) return true; + return false; + } + + private boolean jj_3R_107() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(78)) { + jj_scanpos = xsp; + if (jj_scan_token(79)) { + jj_scanpos = xsp; + if (jj_scan_token(80)) { + jj_scanpos = xsp; + if (jj_scan_token(81)) return true; + } + } + } + return false; + } + + private boolean jj_3R_55() { + if (jj_3R_72()) return true; + return false; + } + + private boolean jj_3R_54() { + if (jj_3R_71()) return true; + return false; + } + + private boolean jj_3_7() { + if (jj_3R_44()) return true; + return false; + } + + private boolean jj_3R_87() { + if (jj_scan_token(9)) return true; + if (jj_3R_86()) return true; + return false; + } + + private boolean jj_3R_99() { + if (jj_3R_105()) return true; + if (jj_3R_106()) return true; + return false; + } + + private boolean jj_3R_100() { + if (jj_3R_107()) return true; + return false; + } + + private boolean jj_3R_67() { + if (jj_3R_80()) return true; + return false; + } + + private boolean jj_3R_96() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_100()) jj_scanpos = xsp; + if (jj_3R_101()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_102()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_103() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(72)) { + jj_scanpos = xsp; + if (jj_scan_token(73)) { + jj_scanpos = xsp; + if (jj_scan_token(74)) { + jj_scanpos = xsp; + if (jj_scan_token(75)) { + jj_scanpos = xsp; + if (jj_scan_token(76)) { + jj_scanpos = xsp; + if (jj_scan_token(77)) return true; + } + } + } + } + } + return false; + } + + private boolean jj_3R_60() { + if (jj_scan_token(69)) return true; + if (jj_3R_59()) return true; + return false; + } + + private boolean jj_3R_77() { + if (jj_scan_token(22)) return true; + if (jj_3R_76()) return true; + return false; + } + + private boolean jj_3_8() { + if (jj_3R_45()) return true; + if (jj_scan_token(88)) return true; + if (jj_3R_46()) return true; + return false; + } + + private boolean jj_3R_93() { + if (jj_3R_96()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_97()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_44() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_8()) { + jj_scanpos = xsp; + if (jj_3R_54()) { + jj_scanpos = xsp; + if (jj_3R_55()) { + jj_scanpos = xsp; + if (jj_3R_56()) { + jj_scanpos = xsp; + if (jj_3R_57()) { + jj_scanpos = xsp; + if (jj_3R_58()) return true; + } + } + } + } + } + return false; + } + + private boolean jj_3R_95() { + if (jj_3R_99()) return true; + return false; + } + + private boolean jj_3R_86() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(12)) jj_scanpos = xsp; + if (jj_3R_93()) return true; + return false; + } + + private boolean jj_3_6() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(88)) return true; + return false; + } + + private boolean jj_3R_76() { + if (jj_3R_86()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_87()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_89() { + if (jj_scan_token(55)) return true; + return false; + } + + private boolean jj_3R_81() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(46)) jj_scanpos = xsp; + if (jj_scan_token(4)) return true; + return false; + } + + private boolean jj_3R_59() { + if (jj_3R_76()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_77()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_88() { + if (jj_scan_token(36)) return true; + return false; + } + + private boolean jj_3R_80() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(46)) jj_scanpos = xsp; + if (jj_scan_token(45)) return true; + return false; + } + + private boolean jj_3R_45() { + if (jj_3R_59()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_60()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_91() { + if (jj_scan_token(13)) return true; + return false; + } + + private boolean jj_3R_66() { + if (jj_scan_token(52)) return true; + return false; + } + + private boolean jj_3R_94() { + if (jj_3R_98()) return true; + return false; + } + + private boolean jj_3R_90() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_94()) { + jj_scanpos = xsp; + if (jj_3R_95()) return true; + } + return false; + } + + private boolean jj_3R_62() { + if (jj_scan_token(31)) return true; + if (jj_3R_46()) return true; + return false; + } + + private boolean jj_3R_61() { + if (jj_3R_45()) return true; + return false; + } + + private boolean jj_3R_46() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_61()) { + jj_scanpos = xsp; + if (jj_3R_62()) return true; + } + return false; + } + + private boolean jj_3R_84() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(8)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(11)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(51)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(27)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_90()) { + jj_scanpos = xsp; + if (jj_3R_91()) return true; + } + return false; + } + + private boolean jj_3R_83() { + if (jj_3R_89()) return true; + return false; + } + + private boolean jj_3R_70() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_82()) { + jj_scanpos = xsp; + if (jj_3R_83()) { + jj_scanpos = xsp; + if (jj_3R_84()) return true; + } + } + return false; + } + + private boolean jj_3R_82() { + if (jj_3R_88()) return true; + return false; + } + + private boolean jj_3R_73() { + if (jj_scan_token(39)) return true; + if (jj_scan_token(62)) return true; + return false; + } + + private boolean jj_3R_53() { + if (jj_3R_70()) return true; + return false; + } + + private boolean jj_3R_43() { + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_53()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_69() { + if (jj_scan_token(14)) return true; + return false; + } + + private boolean jj_3R_65() { + if (jj_scan_token(21)) return true; + return false; + } + + private boolean jj_3R_49() { + if (jj_scan_token(STRING)) return true; + return false; + } + + private boolean jj_3R_41() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_49()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_52() { + if (jj_3R_69()) return true; + return false; + } + + private boolean jj_3R_51() { + if (jj_scan_token(59)) return true; + return false; + } + + /** Generated Token Manager. */ + public ModelParserTokenManager token_source; + SimpleCharStream jj_input_stream; + /** Current token. */ + public Token token; + /** Next token. */ + public Token jj_nt; + private int jj_ntk; + private Token jj_scanpos, jj_lastpos; + private int jj_la; + private int jj_gen; + final private int[] jj_la1 = new int[134]; + static private int[] jj_la1_0; + static private int[] jj_la1_1; + static private int[] jj_la1_2; + static { + jj_la1_init_0(); + jj_la1_init_1(); + jj_la1_init_2(); + } + private static void jj_la1_init_0() { + jj_la1_0 = new int[] {0x0,0x0,0x45020880,0x800,0x40000000,0x0,0x0,0x5020080,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x10,0x0,0x0,0x4000,0x0,0x4000,0x0,0x80001040,0x4d8329a0,0x100,0x800,0x0,0x8000000,0x458300a0,0x458300a0,0x0,0x458320a0,0x4d8329a0,0x0,0x0,0x0,0x4000,0x0,0x0,0x810000,0x810000,0x20,0x20,0x0,0x0,0x0,0x80000000,0x0,0x0,0x0,0x0,0x2d00,0x0,0x2d00,0x400,0x800,0x2000,0x0,0x400,0x800,0x458300a0,0x458320a0,0x458300a0,0x0,0x0,0x0,0xa0240000,0x80200000,0x0,0xa0240000,0x80201040,0x100000,0x80201040,0x80201040,0x8000,0xa0240000,0x100000,0xa0240000,0xa0240000,0x8000,0x80201040,0xa0240000,0x0,0x0,0xa0240000,0x80201040,0x2000000,0x80201040,0xa0240000,0x2000000,0xa0240000,0x100000,0x80001040,0x100000,0x80001040,0x0,0x0,0x400000,0x200,0x1000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80001040,0x200000,0x200000,0x0,0x0,0x80001040,0x0,0x80001040,0x0,0x0,0x80001040,0x4000,0x0,0x0,}; + } + private static void jj_la1_init_1() { + jj_la1_1 = new int[] {0x0,0x200000,0x20049064,0x0,0x0,0x8000,0x40000,0x20041064,0x0,0x40000000,0x0,0x0,0x40000000,0x800000,0x0,0x2106000,0x106000,0x0,0x0,0x0,0x8000000,0x0,0x0,0x4400400a,0x218e9475,0x0,0x0,0x80000,0x0,0x21069465,0x21069465,0x400000,0x21069465,0x218e9475,0x0,0x0,0x40000000,0x0,0x40000000,0x0,0x0,0x0,0x20400,0x20400,0x1000001,0x1000001,0x0,0x0,0x0,0x40000000,0x0,0x40000000,0x0,0x0,0x0,0x0,0x0,0x0,0x40000000,0x0,0x0,0x21069465,0x21069465,0x21069465,0x400000,0x4000,0x4000,0x40010800,0x880,0x40000000,0x40010800,0x4400488a,0x0,0x4400488a,0x4400488a,0x0,0x40010800,0x0,0x40010800,0x40010800,0x0,0x4400488a,0x40010800,0x0,0x200,0x40010800,0x4400488a,0x0,0x4400488a,0x40010800,0x0,0x40010800,0x0,0x4400400a,0x0,0x4400400a,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4004000,0x0,0x2,0x40000008,0x0,0x0,0x0,0x0,0x0,0x0,0x4400400a,0x0,0x0,0x0,0x0,0x4400400a,0x0,0x4400400a,0x0,0x0,0x4400400a,0x0,0x0,0x0,}; + } + private static void jj_la1_init_2() { + jj_la1_2 = new int[] {0x4000010,0x0,0xc0000000,0x0,0x0,0x0,0x0,0xc0000000,0x4,0x0,0x4000000,0x80,0x0,0x0,0x80,0x0,0x0,0x8000000,0x4000010,0x0,0x0,0x0,0x4000010,0x3c03c015,0xc4000010,0x0,0x0,0x0,0x0,0xc4000010,0xc4000010,0x0,0xc4000010,0xc4000010,0x10,0x4000010,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x4,0x3000000,0x1000000,0x3000000,0x4000010,0x80,0x4000010,0x0,0x0,0x4000010,0x3000000,0x0,0x0,0xc4000010,0xc4000010,0xc4000010,0x0,0x0,0x0,0x4000010,0x4000000,0x2000000,0x4000010,0x3c03c015,0x0,0x3c03c015,0x3c03c015,0x0,0x4000010,0x0,0x4000010,0x4000010,0x0,0x3c03c015,0x4000010,0x80,0x0,0x4000010,0x3c03c015,0x0,0x3c03c015,0x4000010,0x0,0x4000010,0x0,0x3c03c015,0x0,0x3c03c015,0x20,0x20,0x0,0x0,0x0,0x3f00,0x3f00,0x3c000,0x3c000,0x3c000,0x3c0000,0x3c0000,0xc00000,0xc00000,0x4000010,0x40,0x38000000,0x4000015,0x10,0x10,0x10,0x4,0x10,0x4,0x3c03c015,0x80,0x80,0x4000000,0x80,0x3c03c015,0x80,0x3c03c015,0x80,0x80,0x3c03c035,0x0,0x4000,0x8000000,}; + } + final private JJCalls[] jj_2_rtns = new JJCalls[10]; + private boolean jj_rescan = false; + private int jj_gc = 0; + + /** Constructor with InputStream. */ + public ModelParser(java.io.InputStream stream) { + this(stream, null); + } + /** Constructor with InputStream and supplied encoding */ + public ModelParser(java.io.InputStream stream, String encoding) { + try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source = new ModelParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream, String encoding) { + try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor. */ + public ModelParser(java.io.Reader stream) { + jj_input_stream = new SimpleCharStream(stream, 1, 1); + token_source = new ModelParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor with generated Token Manager. */ + public ModelParser(ModelParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(ModelParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 134; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + jj_gen++; + if (++jj_gc > 100) { + jj_gc = 0; + for (int i = 0; i < jj_2_rtns.length; i++) { + JJCalls c = jj_2_rtns[i]; + while (c != null) { + if (c.gen < jj_gen) c.first = null; + c = c.next; + } + } + } + return token; + } + token = oldToken; + jj_kind = kind; + throw generateParseException(); + } + + static private final class LookaheadSuccess extends java.lang.Error { } + final private LookaheadSuccess jj_ls = new LookaheadSuccess(); + private boolean jj_scan_token(int kind) { + if (jj_scanpos == jj_lastpos) { + jj_la--; + if (jj_scanpos.next == null) { + jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); + } else { + jj_lastpos = jj_scanpos = jj_scanpos.next; + } + } else { + jj_scanpos = jj_scanpos.next; + } + if (jj_rescan) { + int i = 0; Token tok = token; + while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; } + if (tok != null) jj_add_error_token(kind, i); + } + if (jj_scanpos.kind != kind) return true; + if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls; + return false; + } + + +/** Get the next Token. */ + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; + } + +/** Get the specific Token. */ + final public Token getToken(int index) { + Token t = token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + private int jj_ntk() { + if ((jj_nt=token.next) == null) + return (jj_ntk = (token.next=token_source.getNextToken()).kind); + else + return (jj_ntk = jj_nt.kind); + } + + private java.util.List jj_expentries = new java.util.ArrayList(); + private int[] jj_expentry; + private int jj_kind = -1; + private int[] jj_lasttokens = new int[100]; + private int jj_endpos; + + private void jj_add_error_token(int kind, int pos) { + if (pos >= 100) return; + if (pos == jj_endpos + 1) { + jj_lasttokens[jj_endpos++] = kind; + } else if (jj_endpos != 0) { + jj_expentry = new int[jj_endpos]; + for (int i = 0; i < jj_endpos; i++) { + jj_expentry[i] = jj_lasttokens[i]; + } + jj_entries_loop: for (java.util.Iterator it = jj_expentries.iterator(); it.hasNext();) { + int[] oldentry = (int[])(it.next()); + if (oldentry.length == jj_expentry.length) { + for (int i = 0; i < jj_expentry.length; i++) { + if (oldentry[i] != jj_expentry[i]) { + continue jj_entries_loop; + } + } + jj_expentries.add(jj_expentry); + break jj_entries_loop; + } + } + if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind; + } + } + + /** Generate ParseException. */ + public ParseException generateParseException() { + jj_expentries.clear(); + boolean[] la1tokens = new boolean[96]; + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int i = 0; i < 134; i++) { + if (jj_la1[i] == jj_gen) { + for (int j = 0; j < 32; j++) { + if ((jj_la1_0[i] & (1< jj_gen) { + jj_la = p.arg; jj_lastpos = jj_scanpos = p.first; + switch (i) { + case 0: jj_3_1(); break; + case 1: jj_3_2(); break; + case 2: jj_3_3(); break; + case 3: jj_3_4(); break; + case 4: jj_3_5(); break; + case 5: jj_3_6(); break; + case 6: jj_3_7(); break; + case 7: jj_3_8(); break; + case 8: jj_3_9(); break; + case 9: jj_3_10(); break; + } + } + p = p.next; + } while (p != null); + } catch(LookaheadSuccess ls) { } + } + jj_rescan = false; + } + + private void jj_save(int index, int xla) { + JJCalls p = jj_2_rtns[index]; + while (p.gen > jj_gen) { + if (p.next == null) { p = p.next = new JJCalls(); break; } + p = p.next; + } + p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla; + } + + static final class JJCalls { + int gen; + Token first; + int arg; + JJCalls next; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelParserConstants.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelParserConstants.java new file mode 100644 index 00000000..b307d246 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelParserConstants.java @@ -0,0 +1,131 @@ +/* Generated By:JavaCC: Do not edit this line. ModelParserConstants.java */ +package org.simantics.sysdyn.modelParser; + + +/** + * Token literal values and constants. + * Generated by org.javacc.parser.OtherFilesGen#start() + */ +public interface ModelParserConstants { + + /** End of File. */ + int EOF = 0; + /** RegularExpression Id. */ + int WHITESPACE = 1; + /** RegularExpression Id. */ + int COMMENT1 = 2; + /** RegularExpression Id. */ + int COMMENT2 = 3; + /** RegularExpression Id. */ + int IDENT = 90; + /** RegularExpression Id. */ + int STRING = 91; + /** RegularExpression Id. */ + int UNSIGNED_INTEGER = 92; + /** RegularExpression Id. */ + int UNSIGNED_NUMBER = 93; + + /** Lexical state. */ + int DEFAULT = 0; + + /** Literal token values. */ + String[] tokenImage = { + "", + "", + "", + "", + "\"algorithm\"", + "\"discrete\"", + "\"false\"", + "\"model\"", + "\"redeclare\"", + "\"and\"", + "\"each\"", + "\"final\"", + "\"not\"", + "\"replaceable\"", + "\"annotation\"", + "\"else\"", + "\"flow\"", + "\"operator\"", + "\"return\"", + "\"assert\"", + "\"elseif\"", + "\"for\"", + "\"or\"", + "\"stream\"", + "\"block\"", + "\"elsewhen\"", + "\"function\"", + "\"outer\"", + "\"then\"", + "\"break\"", + "\"encapsulated\"", + "\"if\"", + "\"output\"", + "\"true\"", + "\"class\"", + "\"end\"", + "\"import\"", + "\"package\"", + "\"type\"", + "\"connect\"", + "\"enumeration\"", + "\"in\"", + "\"parameter\"", + "\"when\"", + "\"connector\"", + "\"equation\"", + "\"initial\"", + "\"partial\"", + "\"while\"", + "\"constant\"", + "\"expandable\"", + "\"inner\"", + "\"protected\"", + "\"within\"", + "\"constrainedby\"", + "\"extends\"", + "\"input\"", + "\"public\"", + "\"der\"", + "\"external\"", + "\"loop\"", + "\"record\"", + "\"(\"", + "\")\"", + "\"{\"", + "\"}\"", + "\"[\"", + "\"]\"", + "\".\"", + "\":\"", + "\";\"", + "\",\"", + "\"<\"", + "\"<=\"", + "\">\"", + "\">=\"", + "\"==\"", + "\"<>\"", + "\"+\"", + "\"-\"", + "\".+\"", + "\".-\"", + "\"*\"", + "\"/\"", + "\".*\"", + "\"./\"", + "\"^\"", + "\".^\"", + "\"=\"", + "\":=\"", + "", + "", + "", + "", + "\"operator function\"", + "\"operator record\"", + }; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelParserTokenManager.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelParserTokenManager.java new file mode 100644 index 00000000..19264f96 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelParserTokenManager.java @@ -0,0 +1,1435 @@ +/* Generated By:JavaCC: Do not edit this line. ModelParserTokenManager.java */ +package org.simantics.sysdyn.modelParser; +import java.util.ArrayList; + +/** Token Manager. */ +public class ModelParserTokenManager implements ModelParserConstants +{ + + /** Debug output. */ + public java.io.PrintStream debugStream = System.out; + /** Set debug output. */ + public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } +private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1) +{ + switch (pos) + { + case 0: + if ((active0 & 0x3ffffffffffffff0L) != 0L || (active1 & 0xc0000000L) != 0L) + { + jjmatchedKind = 90; + return 2; + } + if ((active1 & 0x80000L) != 0L) + return 13; + if ((active1 & 0xb30010L) != 0L) + return 9; + return -1; + case 1: + if ((active0 & 0x108420080400000L) != 0L) + return 2; + if ((active0 & 0x3ef7bdff7fbffff0L) != 0L || (active1 & 0xc0000000L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 90; + jjmatchedPos = 1; + } + return 2; + } + return -1; + case 2: + if ((active0 & 0x400000800201200L) != 0L) + return 2; + if ((active0 & 0x3bfffdf77f9fedf0L) != 0L || (active1 & 0xc0000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 2; + return 2; + } + return -1; + case 3: + if ((active0 & 0x1000084212118400L) != 0L) + return 2; + if ((active0 & 0x2bfff5b56d8e69f0L) != 0L || (active1 & 0xc0000000L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 90; + jjmatchedPos = 3; + } + return 2; + } + return -1; + case 4: + if ((active0 & 0x1090004290008c0L) != 0L) + return 2; + if ((active0 & 0x2af6f5b1469e6130L) != 0L || (active1 & 0xc0000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 4; + return 2; + } + return -1; + case 5: + if ((active0 & 0x22200011009c0000L) != 0L) + return 2; + if ((active0 & 0x8d6f5a046026130L) != 0L || (active1 & 0xc0000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 5; + return 2; + } + return -1; + case 6: + if ((active0 & 0x80d0a000000000L) != 0L) + return 2; + if ((active0 & 0x856250046026130L) != 0L || (active1 & 0xc0000000L) != 0L) + { + if (jjmatchedPos != 6) + { + jjmatchedKind = 90; + jjmatchedPos = 6; + } + return 2; + } + return -1; + case 7: + if ((active0 & 0x54150040006110L) != 0L) + { + if (jjmatchedPos != 7) + { + jjmatchedKind = 90; + jjmatchedPos = 7; + } + return 2; + } + if ((active0 & 0x802200006020020L) != 0L || (active1 & 0xc0000000L) != 0L) + return 2; + return -1; + case 8: + if ((active0 & 0x10140000000110L) != 0L) + return 2; + if ((active0 & 0x44010040006000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 8; + return 2; + } + return -1; + case 9: + if ((active0 & 0x40010040002000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 9; + return 2; + } + if ((active0 & 0x4000000004000L) != 0L) + return 2; + return -1; + case 10: + if ((active0 & 0x10000002000L) != 0L) + return 2; + if ((active0 & 0x40000040000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 10; + return 2; + } + return -1; + case 11: + if ((active0 & 0x40000000L) != 0L) + return 2; + if ((active0 & 0x40000000000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 11; + return 2; + } + return -1; + case 12: + if ((active0 & 0x40000000000000L) != 0L) + return 2; + return -1; + default : + return -1; + } +} +private final int jjStartNfa_0(int pos, long active0, long active1) +{ + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1); +} +private int jjStopAtPos(int pos, int kind) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} +private int jjMoveStringLiteralDfa0_0() +{ + switch(curChar) + { + case 40: + return jjStopAtPos(0, 62); + case 41: + return jjStopAtPos(0, 63); + case 42: + return jjStopAtPos(0, 82); + case 43: + return jjStopAtPos(0, 78); + case 44: + return jjStopAtPos(0, 71); + case 45: + return jjStopAtPos(0, 79); + case 46: + jjmatchedKind = 68; + return jjMoveStringLiteralDfa1_0(0x0L, 0xb30000L); + case 47: + return jjStartNfaWithStates_0(0, 83, 13); + case 58: + jjmatchedKind = 69; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2000000L); + case 59: + return jjStopAtPos(0, 70); + case 60: + jjmatchedKind = 72; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2200L); + case 61: + jjmatchedKind = 88; + return jjMoveStringLiteralDfa1_0(0x0L, 0x1000L); + case 62: + jjmatchedKind = 74; + return jjMoveStringLiteralDfa1_0(0x0L, 0x800L); + case 91: + return jjStopAtPos(0, 66); + case 93: + return jjStopAtPos(0, 67); + case 94: + return jjStopAtPos(0, 86); + case 97: + return jjMoveStringLiteralDfa1_0(0x84210L, 0x0L); + case 98: + return jjMoveStringLiteralDfa1_0(0x21000000L, 0x0L); + case 99: + return jjMoveStringLiteralDfa1_0(0x42108400000000L, 0x0L); + case 100: + return jjMoveStringLiteralDfa1_0(0x400000000000020L, 0x0L); + case 101: + return jjMoveStringLiteralDfa1_0(0x884210842108400L, 0x0L); + case 102: + return jjMoveStringLiteralDfa1_0(0x4210840L, 0x0L); + case 105: + return jjMoveStringLiteralDfa1_0(0x108421080000000L, 0x0L); + case 108: + return jjMoveStringLiteralDfa1_0(0x1000000000000000L, 0x0L); + case 109: + return jjMoveStringLiteralDfa1_0(0x80L, 0x0L); + case 110: + return jjMoveStringLiteralDfa1_0(0x1000L, 0x0L); + case 111: + return jjMoveStringLiteralDfa1_0(0x108420000L, 0xc0000000L); + case 112: + return jjMoveStringLiteralDfa1_0(0x210842000000000L, 0x0L); + case 114: + return jjMoveStringLiteralDfa1_0(0x2000000000042100L, 0x0L); + case 115: + return jjMoveStringLiteralDfa1_0(0x800000L, 0x0L); + case 116: + return jjMoveStringLiteralDfa1_0(0x4210000000L, 0x0L); + case 119: + return jjMoveStringLiteralDfa1_0(0x21080000000000L, 0x0L); + case 123: + return jjStopAtPos(0, 64); + case 125: + return jjStopAtPos(0, 65); + default : + return jjMoveNfa_0(0, 0); + } +} +private int jjMoveStringLiteralDfa1_0(long active0, long active1) +{ + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(0, active0, active1); + return 1; + } + switch(curChar) + { + case 42: + if ((active1 & 0x100000L) != 0L) + return jjStopAtPos(1, 84); + break; + case 43: + if ((active1 & 0x10000L) != 0L) + return jjStopAtPos(1, 80); + break; + case 45: + if ((active1 & 0x20000L) != 0L) + return jjStopAtPos(1, 81); + break; + case 47: + if ((active1 & 0x200000L) != 0L) + return jjStopAtPos(1, 85); + break; + case 61: + if ((active1 & 0x200L) != 0L) + return jjStopAtPos(1, 73); + else if ((active1 & 0x800L) != 0L) + return jjStopAtPos(1, 75); + else if ((active1 & 0x1000L) != 0L) + return jjStopAtPos(1, 76); + else if ((active1 & 0x2000000L) != 0L) + return jjStopAtPos(1, 89); + break; + case 62: + if ((active1 & 0x2000L) != 0L) + return jjStopAtPos(1, 77); + break; + case 94: + if ((active1 & 0x800000L) != 0L) + return jjStopAtPos(1, 87); + break; + case 97: + return jjMoveStringLiteralDfa2_0(active0, 0x842000000440L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa2_0(active0, 0x2400000000042100L, active1, 0L); + case 102: + if ((active0 & 0x80000000L) != 0L) + return jjStartNfaWithStates_0(1, 31, 2); + break; + case 104: + return jjMoveStringLiteralDfa2_0(active0, 0x1080010000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa2_0(active0, 0x20000000000820L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa2_0(active0, 0x403118010L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa2_0(active0, 0x1000000000L, active1, 0L); + case 110: + if ((active0 & 0x20000000000L) != 0L) + { + jjmatchedKind = 41; + jjmatchedPos = 1; + } + return jjMoveStringLiteralDfa2_0(active0, 0x108410840004200L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa2_0(active0, 0x1042108000201080L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa2_0(active0, 0x20000L, active1, 0xc0000000L); + case 113: + return jjMoveStringLiteralDfa2_0(active0, 0x200000000000L, active1, 0L); + case 114: + if ((active0 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(1, 22, 2); + return jjMoveStringLiteralDfa2_0(active0, 0x10000220000000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa2_0(active0, 0x80000L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa2_0(active0, 0x800000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa2_0(active0, 0x20000010c000000L, active1, 0L); + case 120: + return jjMoveStringLiteralDfa2_0(active0, 0x884000000000000L, active1, 0L); + case 121: + return jjMoveStringLiteralDfa2_0(active0, 0x4000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(0, active0, active1); +} +private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(0, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(1, active0, active1); + return 2; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa3_0(active0, 0x400000000L, active1, 0L); + case 98: + return jjMoveStringLiteralDfa3_0(active0, 0x200000000000000L, active1, 0L); + case 99: + return jjMoveStringLiteralDfa3_0(active0, 0x2000002040000400L, active1, 0L); + case 100: + if ((active0 & 0x200L) != 0L) + return jjStartNfaWithStates_0(2, 9, 2); + else if ((active0 & 0x800000000L) != 0L) + return jjStartNfaWithStates_0(2, 35, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x180L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa3_0(active0, 0x80030020000L, active1, 0xc0000000L); + case 103: + return jjMoveStringLiteralDfa3_0(active0, 0x10L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa3_0(active0, 0x1400000000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa3_0(active0, 0x40L, active1, 0L); + case 110: + return jjMoveStringLiteralDfa3_0(active0, 0x4a108004004800L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa3_0(active0, 0x1010000001010000L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa3_0(active0, 0x104005000002000L, active1, 0L); + case 114: + if ((active0 & 0x200000L) != 0L) + return jjStartNfaWithStates_0(2, 21, 2); + else if ((active0 & 0x400000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 58, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x840000800000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa3_0(active0, 0x2188020L, active1, 0L); + case 116: + if ((active0 & 0x1000L) != 0L) + return jjStartNfaWithStates_0(2, 12, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x8a0000108040000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa3_0(active0, 0x210200000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(1, active0, active1); +} +private int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(1, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(2, active0, active1); + return 3; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa4_0(active0, 0x4240060000800L, active1, 0L); + case 99: + return jjMoveStringLiteralDfa4_0(active0, 0x5000020L, active1, 0L); + case 101: + if ((active0 & 0x8000L) != 0L) + { + jjmatchedKind = 15; + jjmatchedPos = 3; + } + else if ((active0 & 0x200000000L) != 0L) + return jjStartNfaWithStates_0(3, 33, 2); + else if ((active0 & 0x4000000000L) != 0L) + return jjStartNfaWithStates_0(3, 38, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x88800000a980180L, active1, 0L); + case 104: + if ((active0 & 0x400L) != 0L) + return jjStartNfaWithStates_0(3, 10, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x20000000000000L, active1, 0L); + case 107: + return jjMoveStringLiteralDfa4_0(active0, 0x2000000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa4_0(active0, 0x201000000002000L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa4_0(active0, 0x10000000000L, active1, 0L); + case 110: + if ((active0 & 0x10000000L) != 0L) + return jjStartNfaWithStates_0(3, 28, 2); + else if ((active0 & 0x80000000000L) != 0L) + return jjStartNfaWithStates_0(3, 43, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x108000000000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa4_0(active0, 0x2000001000004010L, active1, 0L); + case 112: + if ((active0 & 0x1000000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 60, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x100000000L, active1, 0L); + case 114: + return jjMoveStringLiteralDfa4_0(active0, 0x20000L, active1, 0xc0000000L); + case 115: + return jjMoveStringLiteralDfa4_0(active0, 0x42000400000040L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa4_0(active0, 0x10c00000000000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa4_0(active0, 0x100000000040000L, active1, 0L); + case 119: + if ((active0 & 0x10000L) != 0L) + return jjStartNfaWithStates_0(3, 16, 2); + break; + default : + break; + } + return jjStartNfa_0(2, active0, active1); +} +private int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(2, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(3, active0, active1); + return 4; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa5_0(active0, 0x2000822000L, active1, 0xc0000000L); + case 99: + return jjMoveStringLiteralDfa5_0(active0, 0x100L, active1, 0L); + case 101: + if ((active0 & 0x40L) != 0L) + return jjStartNfaWithStates_0(4, 6, 2); + else if ((active0 & 0x1000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 48, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x10118000000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa5_0(active0, 0x220c00000100000L, active1, 0L); + case 107: + if ((active0 & 0x1000000L) != 0L) + return jjStartNfaWithStates_0(4, 24, 2); + else if ((active0 & 0x20000000L) != 0L) + return jjStartNfaWithStates_0(4, 29, 2); + break; + case 108: + if ((active0 & 0x80L) != 0L) + return jjStartNfaWithStates_0(4, 7, 2); + else if ((active0 & 0x800L) != 0L) + return jjStartNfaWithStates_0(4, 11, 2); + break; + case 109: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L, active1, 0L); + case 110: + return jjMoveStringLiteralDfa5_0(active0, 0x84000000000000L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000L, active1, 0L); + case 114: + if ((active0 & 0x8000000L) != 0L) + return jjStartNfaWithStates_0(4, 27, 2); + else if ((active0 & 0x8000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 51, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x28000010000c0030L, active1, 0L); + case 115: + if ((active0 & 0x400000000L) != 0L) + return jjStartNfaWithStates_0(4, 34, 2); + break; + case 116: + if ((active0 & 0x100000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 56, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x42200004004000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa5_0(active0, 0x100000000L, active1, 0L); + case 119: + return jjMoveStringLiteralDfa5_0(active0, 0x2000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(3, active0, active1); +} +private int jjMoveStringLiteralDfa5_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(3, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(4, active0, active1); + return 5; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa6_0(active0, 0x2c00000004000L, active1, 0L); + case 99: + if ((active0 & 0x200000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 57, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x10108000002000L, active1, 0L); + case 100: + if ((active0 & 0x2000000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 61, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x84000000000000L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000020L, active1, 0L); + case 102: + if ((active0 & 0x100000L) != 0L) + return jjStartNfaWithStates_0(5, 20, 2); + break; + case 103: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000000L, active1, 0L); + case 104: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa6_0(active0, 0x200004000010L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa6_0(active0, 0x100L, active1, 0L); + case 109: + if ((active0 & 0x800000L) != 0L) + return jjStartNfaWithStates_0(5, 23, 2); + break; + case 110: + if ((active0 & 0x40000L) != 0L) + return jjStartNfaWithStates_0(5, 18, 2); + else if ((active0 & 0x20000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 53, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x800000000000000L, active1, 0L); + case 114: + return jjMoveStringLiteralDfa6_0(active0, 0x40010000000000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000L, active1, 0L); + case 116: + if ((active0 & 0x80000L) != 0L) + return jjStartNfaWithStates_0(5, 19, 2); + else if ((active0 & 0x100000000L) != 0L) + return jjStartNfaWithStates_0(5, 32, 2); + else if ((active0 & 0x1000000000L) != 0L) + return jjStartNfaWithStates_0(5, 36, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x20000L, active1, 0xc0000000L); + default : + break; + } + return jjStartNfa_0(4, active0, active1); +} +private int jjMoveStringLiteralDfa6_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(4, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(5, active0, active1); + return 6; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa7_0(active0, 0x844010000000100L, active1, 0L); + case 101: + if ((active0 & 0x2000000000L) != 0L) + return jjStartNfaWithStates_0(6, 37, 2); + return jjMoveStringLiteralDfa7_0(active0, 0x2002000L, active1, 0L); + case 108: + if ((active0 & 0x400000000000L) != 0L) + return jjStartNfaWithStates_0(6, 46, 2); + else if ((active0 & 0x800000000000L) != 0L) + return jjStartNfaWithStates_0(6, 47, 2); + break; + case 110: + return jjMoveStringLiteralDfa7_0(active0, 0x2000000000000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa7_0(active0, 0x200004020000L, active1, 0xc0000000L); + case 115: + if ((active0 & 0x80000000000000L) != 0L) + return jjStartNfaWithStates_0(6, 55, 2); + break; + case 116: + if ((active0 & 0x8000000000L) != 0L) + { + jjmatchedKind = 39; + jjmatchedPos = 6; + } + return jjMoveStringLiteralDfa7_0(active0, 0x10140000004030L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa7_0(active0, 0x40000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(5, active0, active1); +} +private int jjMoveStringLiteralDfa7_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(5, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(6, active0, active1); + return 7; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa8_0(active0, 0x2000L, active1, 0L); + case 98: + return jjMoveStringLiteralDfa8_0(active0, 0x4000000000000L, active1, 0L); + case 101: + if ((active0 & 0x20L) != 0L) + return jjStartNfaWithStates_0(7, 5, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x10040000000000L, active1, 0L); + case 104: + return jjMoveStringLiteralDfa8_0(active0, 0x10L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa8_0(active0, 0x40000000004000L, active1, 0L); + case 108: + if ((active0 & 0x800000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 59, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x40000000L, active1, 0L); + case 110: + if ((active0 & 0x2000000L) != 0L) + return jjStartNfaWithStates_0(7, 25, 2); + else if ((active0 & 0x4000000L) != 0L) + return jjStartNfaWithStates_0(7, 26, 2); + else if ((active0 & 0x200000000000L) != 0L) + return jjStartNfaWithStates_0(7, 45, 2); + break; + case 111: + return jjMoveStringLiteralDfa8_0(active0, 0x100000000000L, active1, 0L); + case 114: + if ((active0 & 0x20000L) != 0L) + { + jjmatchedKind = 17; + jjmatchedPos = 7; + } + return jjMoveStringLiteralDfa8_0(active0, 0x100L, active1, 0xc0000000L); + case 116: + if ((active0 & 0x2000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 49, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x10000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(6, active0, active1); +} +private int jjMoveStringLiteralDfa8_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(6, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(7, active0, active1); + return 8; + } + switch(curChar) + { + case 32: + return jjMoveStringLiteralDfa9_0(active0, 0L, active1, 0xc0000000L); + case 97: + return jjMoveStringLiteralDfa9_0(active0, 0x40000000L, active1, 0L); + case 98: + return jjMoveStringLiteralDfa9_0(active0, 0x2000L, active1, 0L); + case 100: + if ((active0 & 0x10000000000000L) != 0L) + return jjStartNfaWithStates_0(8, 52, 2); + break; + case 101: + if ((active0 & 0x100L) != 0L) + return jjStartNfaWithStates_0(8, 8, 2); + break; + case 105: + return jjMoveStringLiteralDfa9_0(active0, 0x10000000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa9_0(active0, 0x4000000000000L, active1, 0L); + case 109: + if ((active0 & 0x10L) != 0L) + return jjStartNfaWithStates_0(8, 4, 2); + break; + case 110: + return jjMoveStringLiteralDfa9_0(active0, 0x40000000000000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa9_0(active0, 0x4000L, active1, 0L); + case 114: + if ((active0 & 0x40000000000L) != 0L) + return jjStartNfaWithStates_0(8, 42, 2); + else if ((active0 & 0x100000000000L) != 0L) + return jjStartNfaWithStates_0(8, 44, 2); + break; + default : + break; + } + return jjStartNfa_0(7, active0, active1); +} +private int jjMoveStringLiteralDfa9_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(7, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(8, active0, active1); + return 9; + } + switch(curChar) + { + case 101: + if ((active0 & 0x4000000000000L) != 0L) + return jjStartNfaWithStates_0(9, 50, 2); + return jjMoveStringLiteralDfa10_0(active0, 0x40000000000000L, active1, 0L); + case 102: + return jjMoveStringLiteralDfa10_0(active0, 0L, active1, 0x40000000L); + case 108: + return jjMoveStringLiteralDfa10_0(active0, 0x2000L, active1, 0L); + case 110: + if ((active0 & 0x4000L) != 0L) + return jjStartNfaWithStates_0(9, 14, 2); + break; + case 111: + return jjMoveStringLiteralDfa10_0(active0, 0x10000000000L, active1, 0L); + case 114: + return jjMoveStringLiteralDfa10_0(active0, 0L, active1, 0x80000000L); + case 116: + return jjMoveStringLiteralDfa10_0(active0, 0x40000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(8, active0, active1); +} +private int jjMoveStringLiteralDfa10_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(8, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(9, active0, active1); + return 10; + } + switch(curChar) + { + case 100: + return jjMoveStringLiteralDfa11_0(active0, 0x40000000000000L, active1, 0L); + case 101: + if ((active0 & 0x2000L) != 0L) + return jjStartNfaWithStates_0(10, 13, 2); + return jjMoveStringLiteralDfa11_0(active0, 0x40000000L, active1, 0x80000000L); + case 110: + if ((active0 & 0x10000000000L) != 0L) + return jjStartNfaWithStates_0(10, 40, 2); + break; + case 117: + return jjMoveStringLiteralDfa11_0(active0, 0L, active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(9, active0, active1); +} +private int jjMoveStringLiteralDfa11_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(9, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(10, active0, active1); + return 11; + } + switch(curChar) + { + case 98: + return jjMoveStringLiteralDfa12_0(active0, 0x40000000000000L, active1, 0L); + case 99: + return jjMoveStringLiteralDfa12_0(active0, 0L, active1, 0x80000000L); + case 100: + if ((active0 & 0x40000000L) != 0L) + return jjStartNfaWithStates_0(11, 30, 2); + break; + case 110: + return jjMoveStringLiteralDfa12_0(active0, 0L, active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(10, active0, active1); +} +private int jjMoveStringLiteralDfa12_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(10, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(11, active0, active1); + return 12; + } + switch(curChar) + { + case 99: + return jjMoveStringLiteralDfa13_0(active0, 0L, active1, 0x40000000L); + case 111: + return jjMoveStringLiteralDfa13_0(active0, 0L, active1, 0x80000000L); + case 121: + if ((active0 & 0x40000000000000L) != 0L) + return jjStartNfaWithStates_0(12, 54, 2); + break; + default : + break; + } + return jjStartNfa_0(11, active0, active1); +} +private int jjMoveStringLiteralDfa13_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(11, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(12, 0L, active1); + return 13; + } + switch(curChar) + { + case 114: + return jjMoveStringLiteralDfa14_0(active1, 0x80000000L); + case 116: + return jjMoveStringLiteralDfa14_0(active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(12, 0L, active1); +} +private int jjMoveStringLiteralDfa14_0(long old1, long active1) +{ + if (((active1 &= old1)) == 0L) + return jjStartNfa_0(12, 0L, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(13, 0L, active1); + return 14; + } + switch(curChar) + { + case 100: + if ((active1 & 0x80000000L) != 0L) + return jjStopAtPos(14, 95); + break; + case 105: + return jjMoveStringLiteralDfa15_0(active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(13, 0L, active1); +} +private int jjMoveStringLiteralDfa15_0(long old1, long active1) +{ + if (((active1 &= old1)) == 0L) + return jjStartNfa_0(13, 0L, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(14, 0L, active1); + return 15; + } + switch(curChar) + { + case 111: + return jjMoveStringLiteralDfa16_0(active1, 0x40000000L); + default : + break; + } + return jjStartNfa_0(14, 0L, active1); +} +private int jjMoveStringLiteralDfa16_0(long old1, long active1) +{ + if (((active1 &= old1)) == 0L) + return jjStartNfa_0(14, 0L, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(15, 0L, active1); + return 16; + } + switch(curChar) + { + case 110: + if ((active1 & 0x40000000L) != 0L) + return jjStopAtPos(16, 94); + break; + default : + break; + } + return jjStartNfa_0(15, 0L, active1); +} +private int jjStartNfaWithStates_0(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_0(state, pos + 1); +} +static final long[] jjbitVec0 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +private int jjMoveNfa_0(int startState, int curPos) +{ + int startsAt = 0; + jjnewStateCnt = 31; + int i = 1; + jjstateSet[0] = startState; + int kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + do + { + switch(jjstateSet[--i]) + { + case 13: + if (curChar == 47) + { + if (kind > 3) + kind = 3; + jjCheckNAdd(20); + } + else if (curChar == 42) + jjCheckNAddStates(0, 2); + break; + case 0: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 92) + kind = 92; + jjCheckNAddStates(3, 7); + } + else if ((0x100002600L & l) != 0L) + { + if (kind > 1) + kind = 1; + } + else if (curChar == 47) + jjAddStates(8, 9); + else if (curChar == 46) + jjCheckNAdd(9); + else if (curChar == 34) + jjCheckNAddStates(10, 12); + break; + case 2: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjstateSet[jjnewStateCnt++] = 2; + break; + case 3: + if (curChar == 34) + jjCheckNAddStates(10, 12); + break; + case 4: + if ((0xfffffffbfffffbffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 6: + if ((0xfffffffffffffbffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 7: + if (curChar == 34 && kind > 91) + kind = 91; + break; + case 8: + if (curChar == 46) + jjCheckNAdd(9); + break; + case 9: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(9, 10); + break; + case 11: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjstateSet[jjnewStateCnt++] = 11; + break; + case 12: + if (curChar == 47) + jjAddStates(8, 9); + break; + case 14: + if ((0xfffffbffffffffffL & l) != 0L) + jjCheckNAddStates(0, 2); + break; + case 15: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 16; + break; + case 16: + if ((0xffff7fffffffffffL & l) != 0L) + jjCheckNAddStates(0, 2); + break; + case 17: + if (curChar == 47 && kind > 2) + kind = 2; + break; + case 18: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 17; + break; + case 19: + if (curChar != 47) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(20); + break; + case 20: + if ((0xfffffffffffffbffL & l) == 0L) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(20); + break; + case 21: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjCheckNAddStates(3, 7); + break; + case 22: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjCheckNAdd(22); + break; + case 23: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(23, 24); + break; + case 24: + if (curChar != 46) + break; + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(25, 26); + break; + case 25: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(25, 26); + break; + case 27: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjstateSet[jjnewStateCnt++] = 27; + break; + case 28: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(28, 29); + break; + case 30: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjstateSet[jjnewStateCnt++] = 30; + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 0: + case 2: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjCheckNAdd(2); + break; + case 4: + if ((0xffffffffefffffffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 5: + if (curChar == 92) + jjstateSet[jjnewStateCnt++] = 6; + break; + case 6: + jjCheckNAddStates(10, 12); + break; + case 10: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 11; + break; + case 14: + case 16: + jjCheckNAddStates(0, 2); + break; + case 20: + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 20; + break; + case 26: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 27; + break; + case 29: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 30; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 4: + case 6: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddStates(10, 12); + break; + case 14: + case 16: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddStates(0, 2); + break; + case 20: + if ((jjbitVec0[i2] & l2) == 0L) + break; + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 20; + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 31 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +static final int[] jjnextStates = { + 14, 15, 18, 22, 23, 24, 28, 29, 13, 19, 4, 5, 7, +}; + +/** Token literal values. */ +public static final String[] jjstrLiteralImages = { +"", null, null, null, "\141\154\147\157\162\151\164\150\155", +"\144\151\163\143\162\145\164\145", "\146\141\154\163\145", "\155\157\144\145\154", +"\162\145\144\145\143\154\141\162\145", "\141\156\144", "\145\141\143\150", "\146\151\156\141\154", "\156\157\164", +"\162\145\160\154\141\143\145\141\142\154\145", "\141\156\156\157\164\141\164\151\157\156", "\145\154\163\145", +"\146\154\157\167", "\157\160\145\162\141\164\157\162", "\162\145\164\165\162\156", +"\141\163\163\145\162\164", "\145\154\163\145\151\146", "\146\157\162", "\157\162", +"\163\164\162\145\141\155", "\142\154\157\143\153", "\145\154\163\145\167\150\145\156", +"\146\165\156\143\164\151\157\156", "\157\165\164\145\162", "\164\150\145\156", "\142\162\145\141\153", +"\145\156\143\141\160\163\165\154\141\164\145\144", "\151\146", "\157\165\164\160\165\164", "\164\162\165\145", +"\143\154\141\163\163", "\145\156\144", "\151\155\160\157\162\164", "\160\141\143\153\141\147\145", +"\164\171\160\145", "\143\157\156\156\145\143\164", +"\145\156\165\155\145\162\141\164\151\157\156", "\151\156", "\160\141\162\141\155\145\164\145\162", "\167\150\145\156", +"\143\157\156\156\145\143\164\157\162", "\145\161\165\141\164\151\157\156", "\151\156\151\164\151\141\154", +"\160\141\162\164\151\141\154", "\167\150\151\154\145", "\143\157\156\163\164\141\156\164", +"\145\170\160\141\156\144\141\142\154\145", "\151\156\156\145\162", "\160\162\157\164\145\143\164\145\144", +"\167\151\164\150\151\156", "\143\157\156\163\164\162\141\151\156\145\144\142\171", +"\145\170\164\145\156\144\163", "\151\156\160\165\164", "\160\165\142\154\151\143", "\144\145\162", +"\145\170\164\145\162\156\141\154", "\154\157\157\160", "\162\145\143\157\162\144", "\50", "\51", "\173", "\175", +"\133", "\135", "\56", "\72", "\73", "\54", "\74", "\74\75", "\76", "\76\75", +"\75\75", "\74\76", "\53", "\55", "\56\53", "\56\55", "\52", "\57", "\56\52", "\56\57", +"\136", "\56\136", "\75", "\72\75", null, null, null, null, +"\157\160\145\162\141\164\157\162\40\146\165\156\143\164\151\157\156", "\157\160\145\162\141\164\157\162\40\162\145\143\157\162\144", }; + +/** Lexer state names. */ +public static final String[] lexStateNames = { + "DEFAULT", +}; +static final long[] jjtoToken = { + 0xfffffffffffffff1L, 0xffffffffL, +}; +static final long[] jjtoSkip = { + 0xeL, 0x0L, +}; +protected SimpleCharStream input_stream; +private final int[] jjrounds = new int[31]; +private final int[] jjstateSet = new int[62]; +private final StringBuilder jjimage = new StringBuilder(); +private StringBuilder image = jjimage; +private int jjimageLen; +private int lengthOfMatch; +protected char curChar; +/** Constructor. */ +public ModelParserTokenManager(SimpleCharStream stream){ + if (SimpleCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + input_stream = stream; +} + +/** Constructor. */ +public ModelParserTokenManager(SimpleCharStream stream, int lexState){ + this(stream); + SwitchTo(lexState); +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream) +{ + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); +} +private void ReInitRounds() +{ + int i; + jjround = 0x80000001; + for (i = 31; i-- > 0;) + jjrounds[i] = 0x80000000; +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream, int lexState) +{ + ReInit(stream); + SwitchTo(lexState); +} + +/** Switch to specified lex state. */ +public void SwitchTo(int lexState) +{ + if (lexState >= 1 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); + else + curLexState = lexState; +} + +protected Token jjFillToken() +{ + final Token t; + final String curTokenImage; + final int beginLine; + final int endLine; + final int beginColumn; + final int endColumn; + String im = jjstrLiteralImages[jjmatchedKind]; + curTokenImage = (im == null) ? input_stream.GetImage() : im; + beginLine = input_stream.getBeginLine(); + beginColumn = input_stream.getBeginColumn(); + endLine = input_stream.getEndLine(); + endColumn = input_stream.getEndColumn(); + t = Token.newToken(jjmatchedKind, curTokenImage); + + t.beginLine = beginLine; + t.endLine = endLine; + t.beginColumn = beginColumn; + t.endColumn = endColumn; + + return t; +} + +int curLexState = 0; +int defaultLexState = 0; +int jjnewStateCnt; +int jjround; +int jjmatchedPos; +int jjmatchedKind; + +/** Get the next Token. */ +public Token getNextToken() +{ + Token matchedToken; + int curPos = 0; + + EOFLoop : + for (;;) + { + try + { + curChar = input_stream.BeginToken(); + } + catch(java.io.IOException e) + { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + } + image = jjimage; + image.setLength(0); + jjimageLen = 0; + + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + if (jjmatchedKind != 0x7fffffff) + { + if (jjmatchedPos + 1 < curPos) + input_stream.backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) + { + matchedToken = jjFillToken(); + TokenLexicalActions(matchedToken); + return matchedToken; + } + else + { + continue EOFLoop; + } + } + int error_line = input_stream.getEndLine(); + int error_column = input_stream.getEndColumn(); + String error_after = null; + boolean EOFSeen = false; + try { input_stream.readChar(); input_stream.backup(1); } + catch (java.io.IOException e1) { + EOFSeen = true; + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + if (curChar == '\n' || curChar == '\r') { + error_line++; + error_column = 0; + } + else + error_column++; + } + if (!EOFSeen) { + input_stream.backup(1); + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + } + throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); + } +} + +void TokenLexicalActions(Token matchedToken) +{ + switch(jjmatchedKind) + { + case 91 : + image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); + matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); + break; + default : + break; + } +} +private void jjCheckNAdd(int state) +{ + if (jjrounds[state] != jjround) + { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } +} +private void jjAddStates(int start, int end) +{ + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); +} +private void jjCheckNAddTwoStates(int state1, int state2) +{ + jjCheckNAdd(state1); + jjCheckNAdd(state2); +} + +private void jjCheckNAddStates(int start, int end) +{ + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); +} + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelicaParser.jj b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelicaParser.jj new file mode 100644 index 00000000..2f9f31eb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelicaParser.jj @@ -0,0 +1,741 @@ +options { + JDK_VERSION = "1.6"; + STATIC = false; +} + +PARSER_BEGIN(ModelParser) +package org.simantics.sysdyn.modelParser; + +import java.util.ArrayList; + +@SuppressWarnings({"unused", "serial"}) +public class ModelParser { + + private ArrayList inputs = new ArrayList(); + private ArrayList outputs = new ArrayList(); + + private enum InterfaceVariableType { INPUT, OUTPUT, OTHER + } + + public class Parameter { + public String name; + public boolean optional; + public String description; + public String type; + + public Parameter() { + name = new String(""); + optional = false; + description = null; + type = null; + } } + + public ArrayList getInputs() + { + return inputs; + } + + public ArrayList getOutputs() + { + return outputs; + } + +} + +PARSER_END(ModelParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ +"algorithm" | "discrete" | "false" | "model" | "redeclare" +| "and" | "each" | "final" | "not" | "replaceable" +| "annotation" | "else" | "flow" | "operator" | "return" +|"assert" | "elseif" | "for" | "or" | "stream" +| "block" | "elsewhen" | "function" | "outer" | "then" +| "break" | "encapsulated" | "if" | "output" | "true" +| "class" | "end" | "import" | "package" | "type" +| "connect" | "enumeration" | "in" | "parameter" | "when" +| "connector" | "equation" | "initial" | "partial" | "while" +| "constant" | "expandable" | "inner" | "protected" | "within" +| "constrainedby" | "extends" | "input" | "public" +| "der" | "external" | "loop" | "record" +| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | "," +| "<" | "<=" | ">" | ">=" | "==" | "<>" +| "+" | "-" | ".+" | ".-" +| "*" | "/" | ".*" | "./" +| "^" | ".^" +| "=" | ":=" +| +| + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +| +| "." ()? (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +} + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + +void parse() : { + jj_input_stream.setTabSize(1); +} { + stored_definition() +} + +/*** Stored Definition - Within ************************************/ + +void stored_definition() : { +} { +// stored_definition: +// [ within [ name ] ";" ] +// { [ final ] class_definition ";" } + ( "within" ( name() )? ";" )? + ( ( "final" )? class_definition() ";" )* +} + +/*** Class Definition **********************************************/ + +void class_definition() : { +} { +// class_definition : +// [ encapsulated ] +// [ partial +// ] ( class modelrecordblock expandableconnectortype +// | | | | [ ] | | package | function | operator | operator function | operator record ) +// class_specifier + ( "encapsulated" )? + ( "partial" )? + ( "class" | "model" | "record" | "block" | ( "expandable" )? "connector" | "type" | + "package" | "function" | "operator" | "operator function" | "operator record" ) + class_specifier() +} + + +void class_specifier() : { +} { +// class_specifier : +// IDENT string_comment composition end IDENT +// | IDENT "=" base_prefix name [ array_subscripts ] +// [ class_modification ] comment +// | IDENT "=" enumeration "(" ( [enum_list] | ":" ) ")" comment +// | IDENT "=" der "(" name "," IDENT { "," IDENT } ")" comment +// | extends IDENT [ class_modification ] string_comment composition +// end IDENT + LOOKAHEAD(2) string_comment() composition() "end" + | LOOKAHEAD(2) "=" base_prefix() name() ( array_subscripts() )? ( class_modification() )? comment() + | LOOKAHEAD(3) "=" "enumeration" "(" ( ( enum_list() )? | ":" ) ")" comment() + |LOOKAHEAD(3) "=" "der" "(" name() "," ( "," )* ")" comment() + | "extends" ( class_modification() )? string_comment() composition() "end" +} + +void base_prefix() : { +} { + type_prefix() +} + +void enum_list() : { +} { +// enumeration_literal { "," enumeration_literal} + enumeration_literal() ( "," enumeration_literal() )* +} + +void enumeration_literal() : { +} { + comment() +} + +void parse_composition() : { +} { + composition() +} + +void composition() : { +} { +// element_list +// { public element_list | +// protected element_list | +// equation_section | +// algorithm_section +// } +// [ external [ language_specification ] +// [ external_function_call ] [ annotation ] ";" ] +// [ annotation ";" ] + element_list() + ( LOOKAHEAD(2) "public" element_list() | "protected" element_list() | equation_section() | algorithm_section() )* + ( "external" ( language_specification() )? ( external_function_call() )? ( annotation() )? ";" )? + ( annotation() ";" )? +} + +void language_specification() : { +} { + +} + +void external_function_call() : { +} { +// [ component_reference "=" ] +// IDENT "(" [ expression_list ] ")" + ( component_reference() "=" )? + "(" ( expression_list() )? ")" +} + +void element_list() : { +} { + ( element() ";" )* +} + +void element() : { +} { +// import_clause | +// extends_clause | +// [ redeclare ] +// [ final ] +// [ inner ] [ outer ] +// ( ( class_definition | component_clause) | +// replaceable ( class_definition | component_clause) +// [constraining_clause comment]) + import_clause() | + extends_clause() | + ( "redeclare" )? + ( "final" )? + ( "inner" )? ( "outer" )? + ( (class_definition() | component_clause()) | + "replaceable" (class_definition() | component_clause()) + (constraining_clause() comment())?) +} + +void import_clause() : { +} { +// import ( IDENT "=" name | name ["." "*"] ) comment + "import" (LOOKAHEAD(2) "=" name() | name() ("." "*")? ) comment() +} + +/*** Extends *******************************************************/ +void extends_clause() : { +} { +// extends name [ class_modification ] [annotation] + "extends" name() ( class_modification() )? ( annotation() )? +} + +void constraining_clause() : { +} { +// constrainedby name [ class_modification ] + "constrainedby" name() ( class_modification() )? +} + +/*** Component Clause **********************************************/ +void component_clause() : { + InterfaceVariableType ioType = InterfaceVariableType.OTHER; + String typeSpecifier = ""; + //String arraySubscripts = null; + ArrayList componentList = new ArrayList(); +} { + +// type_prefix type_specifier [ array_subscripts ] component_list + ( ioType = type_prefix() ) + ( typeSpecifier = type_specifier() ) + ( /*arraySubscripts =*/ array_subscripts() )? + ( componentList = component_list() ) + { + if (ioType == InterfaceVariableType.INPUT) { + for (Parameter input : componentList) { + input.type = typeSpecifier; + inputs.add(input); } + } else if (ioType == InterfaceVariableType.OUTPUT) { + for (Parameter output : componentList) { + output.type = typeSpecifier; + outputs.add(output); + } + } + } +} + +InterfaceVariableType type_prefix() : { + InterfaceVariableType type = InterfaceVariableType.OTHER; +} { +// [ flow | stream ] +// [ discrete | parameter | constant ] [ input | output ] + ( "flow" | "stream" )? + ( "discrete" | "parameter" | "constant" )? + ( "output" { type = InterfaceVariableType.OUTPUT; } + | "input" { type = InterfaceVariableType.INPUT; } + )? + { + return type; + } +} +String type_specifier() : { + String ret = new String(""); +} { + ret = name() + { return ret; + } +} + +ArrayList component_list() : { + ArrayList ret = new ArrayList(); + Parameter temp; +} { +// component_declaration { "," component_declaration } + temp = component_declaration() { ret.add(temp); } ( "," temp = component_declaration() { ret.add(temp); } )* + { return ret; + } +} + +Parameter component_declaration() : { + Parameter ret; + String temp = ""; +} { +// declaration [ conditional_attribute ] comment + ret = declaration() ( conditional_attribute() )? ret.description = comment() + { + return ret; + } +} + +void conditional_attribute() : { +} { + "if" expression() +} + +Parameter declaration() : { + // Parameter here without comment yet. + Parameter ret = new Parameter(); +} { +// IDENT [ array_subscripts ] [ modification ] + { ret.name = new String(token.image); } + ( array_subscripts() )? + ( ret.optional = modification() )? + { return ret; } +} + +/*** Modification **********************************************/ +boolean modification() : { + boolean optional = false; +} { +// class_modification [ "=" expression ] +// | "=" expression +// | ":=" expression + ( class_modification() ( "=" expression() )? + | "=" expression() { optional = true; } + | ":=" expression() { optional = true; } ) + { return optional; + } +} + +void class_modification() : { +} { +// "(" [ argument_list ] ")" + "(" ( argument_list() )? ")" +} + +void argument_list() : { +} { +// argument { "," argument } + argument() ( "," argument() )* +} + +void argument() : { +} { +// element_modification_or_replaceable +// | element_redeclaration + element_modification_or_replaceable() | + element_redeclaration() +} + +void element_modification_or_replaceable() : { +} { +// [ each ] [ final ] ( element_modification | element_replaceable) + ( "each" )? ( "final" )? ( element_modification() | element_replaceable() ) } + +void element_modification() : { +} { +// name [ modification ] string_comment + name() ( modification() )? string_comment() +} + +void element_redeclaration() : { +} { +// redeclare [ each ] [ final ] +// ( ( class_definition | component_clause1) | element_replaceable ) + "redeclare" ( "each" )? ( "final" )? + ( ( class_definition() | component_clause1() ) | element_replaceable() ) } + +void element_replaceable() : { +} { +// replaceable ( class_definition | component_clause1) +// [constraining_clause] + "replaceable" ( class_definition() | component_clause1() ) ( constraining_clause() )? +} + +void component_clause1() : { +} { +// type_prefix type_specifier component_declaration1 + type_prefix() type_specifier() component_declaration1() +} + +void component_declaration1() : { +} { + declaration() comment() +} + + +/*** Equations *************************************************/ +void equation_section() : { +} { +// [ initial ] equation { equation ";" } + ( "initial" )? "equation" ( LOOKAHEAD(2) equation() ";" )* +} + +void algorithm_section() : { +} { +// [ initial ] algorithm { statement ";" } + ( "initial" )? "algorithm" ( statement() ";" )* } + +void equation() : { +} { +// ( simple_expression "=" expression +// | if_equation +// | for_equation +// | connect_clause +// | when_equation +// | IDENT function_call_args ) +// comment + ( LOOKAHEAD(3) simple_expression() "=" expression() + | if_equation() + | for_equation() + | connect_clause() + | when_equation() + | function_call_args() ) + comment() } + +void statement() : { +} { +// ( component_reference ( ":=" expression | function_call_args ) +// | "(" output_expression_list ")" ":=" component_reference function_call_args +// | break +// | return +// | if_statement +// | for_statement +// | while_statement +// | when_statement ) +// comment + ( component_reference() ( ":=" expression() | function_call_args() ) + | "(" output_expression_list() ")" ":=" component_reference() function_call_args() + | "break" + | "return" + | if_statement() + | for_statement() + | while_statement() + | when_statement() ) + comment() +} + +void if_equation() : { +} { +// if expression then +// { equation ";" } +// { elseif expression then +// { equation ";" } +// } +// [ else +// { equation ";" } +// ] +// end if + "if" expression() "then" + ( equation() ";" )* + ( "elseif" expression() "then" + ( equation() ";" )* + )* + ( "else" + ( equation() ";" )* + )? + "end" "if" } + +void if_statement() : { +} { +// if expression then +// { statement ";" } +// { elseif expression then +// { statement ";" } +// } +// [ else +// { statement ";" } +// ] +// end if + "if" expression() "then" + ( statement() ";" )* + ( "elseif" expression() "then" + ( statement() ";" )* + )* + ( "else" + ( statement() ";" )* + )? + "end" "if" } + +void for_equation() : { +} { +// for for_indices loop +// { equation ";" } +// end for + "for" for_indices() "loop" + ( equation() ";" )* + "end" "for" } + +void for_statement() : { +} { +// for for_indices loop +// { equation ";" } +// end for + "for" for_indices() "loop" + ( statement() ";" )* + "end" "for" } + +void for_indices() : { +} { + //for_index {"," for_index} + for_index() ("," for_index())* +} + +void for_index() : { +} { + //IDENT [ in expression ] + ( "in" expression() )? +} + +void while_statement() : { +} { +// while expression loop +// { statement ";" } +// end while + "while" expression() "loop" + ( statement() ";" )* + "end" "while" } + +void when_equation() : { +} { +// when expression then +// { equation ";" } +// { elsewhen expression then +// { equation ";" } } +// end when + "when" expression() "then" + ( equation() ";" )* + ( "elsewhen" expression() "then" + ( equation() ";" )* + )* + "end" "when" } + +void when_statement() : { +} { +// when expression then +// { statement ";" } +// { elsewhen expression then +// { statement ";" } } +// end when + "when" expression() "then" + ( statement() ";" )* + ( "elsewhen" expression() "then" + ( statement() ";" )* + )* + "end" "when" } + +void connect_clause() : { +} { +// connect "(" component_reference "," component_reference ")" + "connect" "(" component_reference() "," component_reference() ")" +} + +/*** Expressions ***************************************************/ +void expr() : { +} { + simple_expression() + | + "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* + "else" expression() +} + +void expression() : { +} { + simple_expression() + | "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* + "else" expression() +} + +void simple_expression() : { +} { + logical_expression() ( ":" logical_expression() ( ":" logical_expression() )? )? +} + +void logical_expression() : { +} { + logical_term() ( "or" logical_term() )* +} + +void logical_term() : { +} { + logical_factor() ( "and" logical_factor() )* +} + +void logical_factor() : { +} { + ( "not" )? relation() +} + +void relation() : { +} { + arithmetic_expression() ( rel_op() arithmetic_expression() )? +} + +void rel_op() : { +} { + "<" | "<=" | ">" | ">=" | "==" | "<>" +} + +void arithmetic_expression() : { +} { + (add_op())? term() (add_op() term())* +} + +void add_op() : { +} { + "+" | "-" | ".+" | ".-" +} + +void term() : { +} { + factor() ( mul_op() factor() )* +} + +void mul_op() : { +} { + "*" | "/" | ".*" | "./" +} + +void factor() : { +} { + primary() ( "^" | ".^" primary() )? +} + +void primary() : { +} { + + | + | + | "false" + | "true" + | LOOKAHEAD( (name()|"der"|"initial") "(" ) (name()|"der"|"initial") function_call_args() + | component_reference() + /* | "(" output_expression_list() ")" */ // Not needed, replaced with following: + | "(" expression() ")" + | "[" expression_list() ( ";" expression_list() )* "]" + | "{" function_arguments() "}" + | "end" +} + +String name() : { + String ret = new String(""); +} { +// [ "." ] IDENT { "." IDENT } + ( "." { ret += "."; } )? + { ret += token.image; } + ( "." { ret += "."; } + { ret += token.image; } + )* + { return ret; + } +} + +void component_reference() : { +} { +// [ "." ] IDENT [ array_subscripts ] { "." IDENT [ array_subscripts ] } + ( "." )? ( array_subscripts() )? ( "." ( array_subscripts() )? )* +} + +void function_call_args() : { +} { +// "(" [ function_arguments ] ")" + "(" ( function_arguments() )? ")" +} + +void function_arguments() : { +} { + //expression [ "," function_arguments | for for_indices ] + //| named_arguments + LOOKAHEAD(2) expression() ( "," function_arguments() | "for" for_indices() )? + | named_arguments() +} + +void named_arguments() : { +} { +// named_argument [ "," named_arguments ] + named_argument() ( "," named_arguments() )? +} + +void named_argument() : { +} { + "=" expression() +} + +void output_expression_list() : { +} { +// [ expression ] { "," [ expression ] } + ( expression() )? ( "," ( expression() )? )* +} + +void expression_list() : { +} { +// expression { "," expression } + expression() ( "," expression() )* +} + +void array_subscripts() : { +} { +// "[" subscript { "," subscript } "]" + "[" subscript() ( "," subscript() )* "]" +} + +void subscript() : { +} { +// ":" | expression ":" | expression() +} + +String comment() : { + String ret; } { // string_comment [ annotation ] + ret = string_comment() ( annotation() )? + { return ret; + } +} + +String string_comment() : { + String ret = null; +} { +// [ STRING { "+" STRING } ] + ( { ret = new String(token.image); } + ( "+" { ret += "+"; } + { ret += token.image; } + )* + )? + { return ret; + } } + +void annotation() : { +} { +// annotation class_modification + "annotation" class_modification() +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ParseException.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ParseException.java new file mode 100644 index 00000000..86734a78 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ParseException.java @@ -0,0 +1,187 @@ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */ +/* JavaCCOptions:KEEP_LINE_COL=null */ +package org.simantics.sysdyn.modelParser; + +/** + * This exception is thrown when parse errors are encountered. + * You can explicitly create objects of this exception type by + * calling the method generateParseException in the generated + * parser. + * + * You can modify this class to customize your error reporting + * mechanisms so long as you retain the public fields. + */ +public class ParseException extends Exception { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * This constructor is used by the method "generateParseException" + * in the generated parser. Calling this constructor generates + * a new object of this type with the fields "currentToken", + * "expectedTokenSequences", and "tokenImage" set. + */ + public ParseException(Token currentTokenVal, + int[][] expectedTokenSequencesVal, + String[] tokenImageVal + ) + { + super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal)); + currentToken = currentTokenVal; + expectedTokenSequences = expectedTokenSequencesVal; + tokenImage = tokenImageVal; + } + + /** + * The following constructors are for use by you for whatever + * purpose you can think of. Constructing the exception in this + * manner makes the exception behave in the normal way - i.e., as + * documented in the class "Throwable". The fields "errorToken", + * "expectedTokenSequences", and "tokenImage" do not contain + * relevant information. The JavaCC generated code does not use + * these constructors. + */ + + public ParseException() { + super(); + } + + /** Constructor with message. */ + public ParseException(String message) { + super(message); + } + + + /** + * This is the last token that has been consumed successfully. If + * this object has been created due to a parse error, the token + * followng this token will (therefore) be the first error token. + */ + public Token currentToken; + + /** + * Each entry in this array is an array of integers. Each array + * of integers represents a sequence of tokens (by their ordinal + * values) that is expected at this point of the parse. + */ + public int[][] expectedTokenSequences; + + /** + * This is a reference to the "tokenImage" array of the generated + * parser within which the parse error occurred. This array is + * defined in the generated ...Constants interface. + */ + public String[] tokenImage; + + /** + * It uses "currentToken" and "expectedTokenSequences" to generate a parse + * error message and returns it. If this object has been created + * due to a parse error, and you do not catch it (it gets thrown + * from the parser) the correct error message + * gets displayed. + */ + private static String initialise(Token currentToken, + int[][] expectedTokenSequences, + String[] tokenImage) { + String eol = System.getProperty("line.separator", "\n"); + StringBuffer expected = new StringBuffer(); + int maxSize = 0; + for (int i = 0; i < expectedTokenSequences.length; i++) { + if (maxSize < expectedTokenSequences[i].length) { + maxSize = expectedTokenSequences[i].length; + } + for (int j = 0; j < expectedTokenSequences[i].length; j++) { + expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); + } + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + expected.append("..."); + } + expected.append(eol).append(" "); + } + String retval = "Encountered \""; + Token tok = currentToken.next; + for (int i = 0; i < maxSize; i++) { + if (i != 0) retval += " "; + if (tok.kind == 0) { + retval += tokenImage[0]; + break; + } + retval += " " + tokenImage[tok.kind]; + retval += " \""; + retval += add_escapes(tok.image); + retval += " \""; + tok = tok.next; + } + retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; + retval += "." + eol; + if (expectedTokenSequences.length == 1) { + retval += "Was expecting:" + eol + " "; + } else { + retval += "Was expecting one of:" + eol + " "; + } + retval += expected.toString(); + return retval; + } + + /** + * The end of line string for this machine. + */ + protected String eol = System.getProperty("line.separator", "\n"); + + /** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal. + */ + static String add_escapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + +} +/* JavaCC - OriginalChecksum=e46c56bfa832359193465f81e8a2147e (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/SimpleCharStream.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/SimpleCharStream.java new file mode 100644 index 00000000..102b285e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/SimpleCharStream.java @@ -0,0 +1,471 @@ +/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */ +/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package org.simantics.sysdyn.modelParser; + +/** + * An implementation of interface CharStream, where the stream is assumed to + * contain only ASCII characters (without unicode processing). + */ + +public class SimpleCharStream +{ +/** Whether parser is static. */ + public static final boolean staticFlag = false; + int bufsize; + int available; + int tokenBegin; +/** Position in buffer. */ + public int bufpos = -1; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int inBuf = 0; + protected int tabSize = 8; + + protected void setTabSize(int i) { tabSize = i; } + protected int getTabSize(int i) { return tabSize; } + + + protected void ExpandBuff(boolean wrapAround) + { + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try + { + if (wrapAround) + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos += (bufsize - tokenBegin)); + } + else + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos -= tokenBegin); + } + } + catch (Throwable t) + { + throw new Error(t.getMessage()); + } + + + bufsize += 2048; + available = bufsize; + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException + { + if (maxNextCharInd == available) + { + if (available == bufsize) + { + if (tokenBegin > 2048) + { + bufpos = maxNextCharInd = 0; + available = tokenBegin; + } + else if (tokenBegin < 0) + bufpos = maxNextCharInd = 0; + else + ExpandBuff(false); + } + else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + int i; + try { + if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1) + { + inputStream.close(); + throw new java.io.IOException(); + } + else + maxNextCharInd += i; + return; + } + catch(java.io.IOException e) { + --bufpos; + backup(0); + if (tokenBegin == -1) + tokenBegin = bufpos; + throw e; + } + } + +/** Start. */ + public char BeginToken() throws java.io.IOException + { + tokenBegin = -1; + char c = readChar(); + tokenBegin = bufpos; + + return c; + } + + protected void UpdateLineColumn(char c) + { + column++; + + if (prevCharIsLF) + { + prevCharIsLF = false; + line += (column = 1); + } + else if (prevCharIsCR) + { + prevCharIsCR = false; + if (c == '\n') + { + prevCharIsLF = true; + } + else + line += (column = 1); + } + + switch (c) + { + case '\r' : + prevCharIsCR = true; + break; + case '\n' : + prevCharIsLF = true; + break; + case '\t' : + column--; + column += (tabSize - (column % tabSize)); + break; + default : + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + +/** Read a character. */ + public char readChar() throws java.io.IOException + { + if (inBuf > 0) + { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + if (++bufpos >= maxNextCharInd) + FillBuff(); + + char c = buffer[bufpos]; + + UpdateLineColumn(c); + return c; + } + + @Deprecated + /** + * @deprecated + * @see #getEndColumn + */ + + public int getColumn() { + return bufcolumn[bufpos]; + } + + @Deprecated + /** + * @deprecated + * @see #getEndLine + */ + + public int getLine() { + return bufline[bufpos]; + } + + /** Get token end column number. */ + public int getEndColumn() { + return bufcolumn[bufpos]; + } + + /** Get token end line number. */ + public int getEndLine() { + return bufline[bufpos]; + } + + /** Get token beginning column number. */ + public int getBeginColumn() { + return bufcolumn[tokenBegin]; + } + + /** Get token beginning line number. */ + public int getBeginLine() { + return bufline[tokenBegin]; + } + +/** Backup a number of characters. */ + public void backup(int amount) { + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length) + { + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + bufpos = -1; + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, 1, 1, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, startline, startcolumn, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + /** Get token literal value. */ + public String GetImage() + { + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + else + return new String(buffer, tokenBegin, bufsize - tokenBegin) + + new String(buffer, 0, bufpos + 1); + } + + /** Get the suffix. */ + public char[] GetSuffix(int len) + { + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else + { + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, + len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + /** Reset buffer when finished. */ + public void Done() + { + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + */ + public void adjustBeginLineColumn(int newLine, int newCol) + { + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin) + { + len = bufpos - tokenBegin + inBuf + 1; + } + else + { + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k = 0; + int nextColDiff = 0, columnDiff = 0; + + while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) + { + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len) + { + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while (i++ < len) + { + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + +} +/* JavaCC - OriginalChecksum=7ab7faca15b64bda32c7a4effb209066 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/Token.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/Token.java new file mode 100644 index 00000000..25d36184 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/Token.java @@ -0,0 +1,131 @@ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */ +/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package org.simantics.sysdyn.modelParser; + +/** + * Describes the input token stream. + */ + +public class Token implements java.io.Serializable { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** The line number of the first character of this Token. */ + public int beginLine; + /** The column number of the first character of this Token. */ + public int beginColumn; + /** The line number of the last character of this Token. */ + public int endLine; + /** The column number of the last character of this Token. */ + public int endColumn; + + /** + * The string image of the token. + */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** + * An optional attribute value of the Token. + * Tokens which are not used as syntactic sugar will often contain + * meaningful values that will be used later on by the compiler or + * interpreter. This attribute value is often different from the image. + * Any subclass of Token that actually wants to return a non-null value can + * override this method as appropriate. + */ + public Object getValue() { + return null; + } + + /** + * No-argument constructor + */ + public Token() {} + + /** + * Constructs a new token for the specified Image. + */ + public Token(int kind) + { + this(kind, null); + } + + /** + * Constructs a new token for the specified Image and Kind. + */ + public Token(int kind, String image) + { + this.kind = kind; + this.image = image; + } + + /** + * Returns the image. + */ + public String toString() + { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simply add something like : + * + * case MyParserConstants.ID : return new IDToken(ofKind, image); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use sit in your lexical actions. + */ + public static Token newToken(int ofKind, String image) + { + switch(ofKind) + { + default : return new Token(ofKind, image); + } + } + + public static Token newToken(int ofKind) + { + return newToken(ofKind, null); + } + +} +/* JavaCC - OriginalChecksum=8584b8a0988c627589640a007dbfe0bb (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/TokenMgrError.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/TokenMgrError.java new file mode 100644 index 00000000..60c67454 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/TokenMgrError.java @@ -0,0 +1,147 @@ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */ +/* JavaCCOptions: */ +package org.simantics.sysdyn.modelParser; + +/** Token Manager Error. */ +public class TokenMgrError extends Error +{ + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** + * Lexical error occurred. + */ + static final int LEXICAL_ERROR = 0; + + /** + * An attempt was made to create a second instance of a static token manager. + */ + static final int STATIC_LEXER_ERROR = 1; + + /** + * Tried to change to an invalid lexical state. + */ + static final int INVALID_LEXICAL_STATE = 2; + + /** + * Detected (and bailed out of) an infinite loop in the token manager. + */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + + /** + * Replaces unprintable characters by their escaped (or unicode escaped) + * equivalents in the given string + */ + protected static final String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + + /** + * Returns a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + * Parameters : + * EOFSeen : indicates if EOF caused the lexical error + * curLexState : lexical state in which this error occurred + * errorLine : line number when the error occurred + * errorColumn : column number when the error occurred + * errorAfter : prefix that was seen before this error occurred + * curchar : the offending character + * Note: You can customize the lexical error message by modifying this method. + */ + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { + return("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * + * "Internal Error : Please file a bug report .... " + * + * from this method for such cases in the release version of your parser. + */ + public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + /** No arg constructor. */ + public TokenMgrError() { + } + + /** Constructor with message and reason. */ + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + /** Full Constructor. */ + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); + } +} +/* JavaCC - OriginalChecksum=d047fc9c0c00c40e4d34a354929bb60c (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java new file mode 100644 index 00000000..186c92a5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java @@ -0,0 +1,398 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.modelica; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +import org.simantics.sysdyn.representation.Book; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.Dependency; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Input; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.ModuleType; +import org.simantics.sysdyn.representation.Sheet; +import org.simantics.sysdyn.representation.Stock; +import org.simantics.sysdyn.representation.Variable; + +/** + * ModelicaWriter writes Sysdyn model representations (objmap) into Modelica code. + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ModelicaWriter { + + /** + * Write a collection of configurations into a single Modelica code + * @param isGame + * + * @param Configurations Configurations, one main configuration and possible modules + * @return Complete Modelica code of a model + */ + public static String write(Collection configurations, boolean isGame, String omVersion) { + Configuration modelConf = null; + for(Configuration conf : configurations) { + if(conf.getModel() != null) { + modelConf = conf; + } + } + StringBuilder b = new StringBuilder(); + + int spreadsheetlocation = b.length(); + + String modelName = modelConf.getLabel().replace(" ", ""); + b.append("model " + modelName + "\n"); + + // Super class for enumerations + b.append("partial class Enumeration_class\n"); + b.append(" parameter Integer size;\n"); + b.append(" parameter Integer elements[:];\n"); + b.append("end Enumeration_class;\n\n"); + + + HashSet sheetNames = new HashSet(); + for(Sheet sheet : getSpreadSheets(configurations)) + sheetNames.add(sheet.getModelicaName()); + + // Write all module configurations to the declarations part (first) + for(Configuration conf : configurations) { + conf.setIsGameConfiguration(isGame); + if(!conf.equals(modelConf)) + writeConfiguration(conf, sheetNames, b); + } + + // Write model configuration last, so that equations-part does not contain module definitions + modelConf.setIsGameConfiguration(isGame); + writeConfiguration(modelConf, sheetNames, b); + + b.append("end " + modelName + ";\n\n"); + + // Insert spreadsheets + if(omVersion != null && omVersion.startsWith("1.9")) { + b.insert(spreadsheetlocation, getGlobalSpreadSheets(configurations)); + } else { + b.append(getGlobalSpreadSheets(configurations)); + } + + + return b.toString(); + } + + /** + * Get all spreadsheets that are found in the model + * @param configurations + * @return + */ + private static List getSpreadSheets(Collection configurations) { + for(Configuration conf : configurations) { + if(conf.getModel() != null) { + for(IElement e : conf.getElements()) { + if(e instanceof Book) { + return ((Book)e).getSheets(); + } + } + } + } + return Collections.emptyList(); + } + + /** + * + */ + private static String getGlobalSpreadSheets(Collection configurations) { + StringBuilder sheets = new StringBuilder(); + for(Configuration conf : configurations) { + if(conf.getModel() != null) { + for(IElement e : conf.getElements()) { + if(e instanceof Book) { + return ((Book)e).getBook(); + } + } + } + } + + return sheets.toString(); + } + + /** + * Write a single configuration to a given string builder + * + * @param configuration Model or module configuration + * @param b String builder + */ + private static void writeConfiguration(Configuration configuration, HashSet sheetNames, StringBuilder b) { + boolean defTime = true; + String app; + + // Lists for storing different configuration elements + ArrayList variables = new ArrayList(); + ArrayList inputs = new ArrayList(); + ArrayList modules = new ArrayList(); + ArrayList stocks = new ArrayList(); + ArrayList enumerations = new ArrayList(); + ArrayList inputDependencies = new ArrayList(); + ArrayList outputDependencies = new ArrayList(); + HashMap> moduleInputs = new HashMap>(); + + // Initialize lists + for(IElement element : configuration.getElements()) { + if(element instanceof IndependentVariable) { + // Normal variable + variables.add((IndependentVariable)element); + if(element instanceof Stock) + // Stock + stocks.add((Stock)element); + } else if (element instanceof Module) { + // Module + Module m = (Module)element; + modules.add(m); + moduleInputs.put(m.getName(), new ArrayList()); + for(IElement e : m.getType().getConfiguration().getElements()) + // Inputs inside the module + if(e instanceof Input && !((Input)e).isHeadOfDependency()) { + moduleInputs.get(m.getName()).add((Input)e); + } + } else if (element instanceof Input) { + // Input variables + inputs.add((Input)element); + } else if (element instanceof Enumeration) { + // Enumerations + enumerations.add((Enumeration)element); + } else if (element instanceof Dependency) { + Dependency dependency = (Dependency)element; + if(dependency.getHead() instanceof Module) { + // References given to child modules + outputDependencies.add(dependency); + } else if(dependency.getTail() instanceof Module){ + // References from child modules + inputDependencies.add(dependency); + } + } + } + + // Setup input references. (Input, String reference to another variable) + HashMap inputReferences = new HashMap(); + setupInputReferences(inputReferences, inputDependencies); + + + // If the configuration is model configuration, use model name. Otherwise, use configuration name. + ModuleType mt = configuration.getModuleType(); + + // className == null, if this is a model configuration. model configuration start and end are written in ModelicaWriter.write + String className = mt != null ? (mt.getName().replace(" ", "")) : null; + + if(className != null) + b.append("\nclass ").append(className); + + // Add spreadsheets to all modules and model. Model is "inner" and modules "outer" + String globalStatus = mt != null ? "outer" : "inner"; + for(String sheetName : sheetNames) + b.append("\n " + globalStatus + " " + sheetName + "_class" + " "+ sheetName + ";"); + + b.append("\n"); + + b.append("// Variable definitions\n"); + for(IndependentVariable variable : variables) { + app = variable.getDeclaration(); + if (app != null) b.append(app); + } + + if(defTime) { + // Time variable for FMU (game) simulations + if(configuration.isGameConfiguration()) { + if(configuration.getModel() != null) + // Parameter for model root. Values changed in FMU simulator + b.append(" parameter Real time = 0;\n"); + else + // Continuous variable for module instances + b.append(" Real time;\n"); + + } + } + + if(!modules.isEmpty()) { + b.append("// Module definitions\n"); + for(Module m : modules) { + b.append(m.getDeclaration()); + } + } + + + // Input definitions + inputDefinitions(b, configuration, inputs, inputReferences); + + if(!enumerations.isEmpty()) { + b.append("// Enumeration definitions\n"); + for(Enumeration e : enumerations) { + b.append(e.getDeclaration()); + } + } + + boolean initialEquations = false; + for(Stock stock : stocks) { + app = stock.getInitialEquation(); + if (app != null) { + if(initialEquations == false) { + initialEquations = true; + b.append("// Initial Equations\n"); + b.append("initial equation\n"); + } + b.append(app); + } + } + + boolean equation = false; + b.append("// Equations\n"); + for(IndependentVariable variable : variables) { + app = variable.getEquation(); + if (app != null) { + if(!equation) { + b.append("equation\n"); + equation = true; + } + + b.append(app); + } + } + + // If "equation" has not been added but there are still equations to be defined, add "equation" + if(!equation && (!inputReferences.isEmpty() || !outputDependencies.isEmpty() || + !moduleInputs.isEmpty() || !modules.isEmpty())) + b.append("equation\n"); + + // Continous input references + continuousInputReferences(b, inputReferences); + + b.append("// Outputs\n"); + for(Dependency dependency : outputDependencies) { + Variable variable = (Variable)dependency.getTail(); + Module module = (Module)dependency.getHead(); + Input reference = (Input)dependency.refersTo(); + if(reference != null && reference.getName() != null && (reference.getVariability() == null || reference.getVariability().isEmpty())) { + b.append(" " + module.getName() + "." + reference.getModelicaName() + " = " + variable.getModelicaName() + ";\n"); + moduleInputs.get(module.getName()).remove(reference); + } + } + + b.append("// Default values for inputs in modules\n"); + for(String moduleLabel : moduleInputs.keySet()) { + for(Input input : moduleInputs.get(moduleLabel)) { + if(input.getVariability() == null || input.getVariability().isEmpty()) + b.append(" " + moduleLabel + "." + input.getModelicaName() + " = " + input.getDefaultInputValue(moduleLabel) + ";\n"); + } + } + + if(defTime) { + if(configuration.isGameConfiguration() && !modules.isEmpty()) { + b.append("// Time values for module\n"); + for(Module m : modules) { + b.append(" " + m.getName() + ".time = time;\n"); + } + } + } + + if(className != null) + b.append("end ").append(className).append(";\n\n"); + + } + + /** + * Define continuous input references + * @param b String builder + * @param inputReferences Input references + */ + private static void continuousInputReferences(StringBuilder b, HashMap inputReferences) { + b.append("// Inputs\n"); + for(Input i : inputReferences.keySet()) { + if(i.getVariability() == null || i.getVariability().isEmpty()) { + // Define only continuous variables here + b.append(" " + i.getModelicaName() + " = " + inputReferences.get(i)); + } + } + } + + /** + * Setup input references for all inputs that are defined in child modules + * + * @param inputReferences Map containing the references + * @param inputDependencies List of input dependencies + */ + private static void setupInputReferences(HashMap inputReferences, ArrayList inputDependencies) { + for(Dependency dependency : inputDependencies) { + Input input = (Input)dependency.getHead(); + Module module = (Module)dependency.getTail(); + Variable reference = (Variable)dependency.refersTo(); + String expression; + // If reference exists, use reference name. Otherwise, use default value. + if(reference != null && reference.getName() != null) + expression = module.getName() + "." + reference.getModelicaName() + ";\n"; + + else + expression = input.getDefaultInputValue() + ";\n"; + + inputReferences.put(input, expression); + } + } + + /** + * Build input definitions + * + * @param b String builder + * @param configuration Module configuration + * @param inputs All inputs of this module + * @param inputReferences + */ + private static void inputDefinitions(StringBuilder b, Configuration configuration, ArrayList inputs, HashMap inputReferences) { + if(inputs.isEmpty()) + return; + + b.append("// Input definitions\n"); + for(Input i : inputs) { + if(i.getVariability() != null && !i.getVariability().isEmpty()) { + // Input is NOT continuous + if(inputReferences.containsKey(i)) { + // Input is defined in a child module + String declaration = i.getDeclaration(); + declaration = declaration.substring(0, declaration.length() - 2); // remove ";\n" from the end + b.append(declaration + " = " + inputReferences.get(i)); + } else { + // Input is not defined in a child module, use default value + b.append(i.getDeclarationWithValue()); + } + } else if(configuration.getModel() != null && !i.isHeadOfDependency()) { + /* + * Input is in the top of the hierarchy, + * and it does not get value from anywhere else. + * => Declare it wit its default value + */ + b.append(i.getDeclarationWithValue()); + } else { + // Continuous => Parent module takes care of declaring a value for the input + b.append(i.getDeclaration()); + } + } + } + + public String escape(String name) { + return name.replace(' ', '_'); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/refactoring/TGRefactoring.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/refactoring/TGRefactoring.java new file mode 100644 index 00000000..3e19f43c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/refactoring/TGRefactoring.java @@ -0,0 +1,91 @@ +package org.simantics.sysdyn.refactoring; + +import gnu.trove.set.hash.TIntHashSet; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.net.URLDecoder; +import java.util.ArrayList; + +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.databoard.container.DataContainer; +import org.simantics.databoard.container.DataContainers; +import org.simantics.graph.query.Path; +import org.simantics.graph.query.TransferableGraphConversion; +import org.simantics.graph.query.UriUtils; +import org.simantics.graph.refactoring.GraphRefactoringUtils; +import org.simantics.graph.refactoring.MappingSpecification; +import org.simantics.graph.refactoring.MappingSpecification.MappingRule; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.graph.store.IdentityStore; + +public class TGRefactoring { + + public static void main(String[] args) throws Exception { + // Select the directory where this file is + File dir = new File(URLDecoder.decode(TGRefactoring.class.getResource(".").getPath(), "UTF-8")).getAbsoluteFile(); + System.out.println(dir); + + // Choose input and output files for refactoring. Files are relative to the selected directory. + File input = new File(dir, "ServiceModel_2012-08-28b.tg"); // use your own file names + File mappingSpec = new File(dir, "mappingSpec.txt"); + File output = new File(dir, "ServiceModel_2012-08-28b-refactored.tg"); + + // Get a map containing the changed names + + // Read input file + DataContainer dc = DataContainers.readFile(input); + + // Get transferable graph from the input file + TransferableGraph1 tg1 = (TransferableGraph1) dc.content.getValue(TransferableGraph1.BINDING); + + MappingSpecification spec = readMappingSpec(mappingSpec); + boolean fixed = GraphRefactoringUtils.fixIncorrectRoot(tg1.identities); + IdentityStore idStore = TransferableGraphConversion.extractIdentities(tg1); + TIntHashSet parentsAffected = new TIntHashSet(); + GraphRefactoringUtils.refactor(tg1, idStore, spec, parentsAffected); + tg1.resourceCount = idStore.getResourceCount(); + tg1.identities = idStore.toArray(); +// GraphRefactoringUtils.compactify(tg1, parentsAffected); + if(fixed) + GraphRefactoringUtils.unfixIncorrectRoot(tg1.identities); + + // Rewrite DataContainer content + dc.content = new Variant(TransferableGraph1.BINDING, tg1); + + // Write the refactored graph to output file + DataContainers.writeFile(output, dc); + } + + private static MappingSpecification readMappingSpec(File mappingSpec) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader(mappingSpec)); + ArrayList rules = new ArrayList(); + while(true) { + String line = reader.readLine(); + if(line == null) + break; + line = line.trim(); + if(line.isEmpty()) + continue; + String[] parts = line.trim().split(" "); + if(parts.length == 2) { + Path from = UriUtils.uriToPath(parts[0]); + Path to = UriUtils.uriToPath(parts[1]); + rules.add(new MappingRule(from, to)); + } else { + if(line.trim().startsWith("//") || (line.trim().startsWith("/*") && line.trim().endsWith("/*"))) { + // Comment + } else { + reader.close(); + throw new IOException("Invalid mapping spec format. Every non-empty line should contain two URIs or comment"); + } + } + } + reader.close(); + + return new MappingSpecification(rules); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/refactoring/mappingSpec.txt b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/refactoring/mappingSpec.txt new file mode 100644 index 00000000..51835211 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/refactoring/mappingSpec.txt @@ -0,0 +1,38 @@ + +// 4.9.2012 ontology changes +http://www.simantics.org/Layer0-1.0 http://www.simantics.org/Layer0-1.1 +http://www.simantics.org/Layer0X-1.0 http://www.simantics.org/Layer0X-1.1 +http://www.simantics.org/G2D-1.0 http://www.simantics.org/G2D-1.1 +http://www.simantics.org/Structural-1.0 http://www.simantics.org/Structural-1.2 +http://www.simantics.org/Diagram-2.1 http://www.simantics.org/Diagram-2.2 +http://www.simantics.org/Simulation-1.0 http://www.simantics.org/Simulation-1.1 +http://www.simantics.org/Modeling-1.1 http://www.simantics.org/Modeling-1.2 +http://www.simantics.org/Project-1.1 http://www.simantics.org/Project-1.2 +http://www.simantics.org/Spreadsheet-1.1 http://www.simantics.org/Spreadsheet-1.2 +http://www.simantics.org/Viewpoint-1.1 http://www.simantics.org/Viewpoint-1.2 +http://www.simantics.org/Image2-1.1 http://www.simantics.org/Image2-1.2 +http://www.simantics.org/Color-1.0 http://www.simantics.org/Color-1.1 +http://www.simantics.org/Action-1.0 http://www.simantics.org/Action-1.1 +http://www.simantics.org/Silk-1.0 http://www.simantics.org/Silk-1.1 +http://www.simantics.org/Issue-1.1 http://www.simantics.org/Issue-1.2 +http://www.simantics.org/User-1.0 http://www.simantics.org/User-1.1 +http://www.simantics.org/Documentation-1.0 http://www.simantics.org/Documentation-1.1 +http://www.simantics.org/Document-1.1 http://www.simantics.org/Document-1.2 +http://www.simantics.org/SelectionView-1.1 http://www.simantics.org/SelectionView-1.2 + +// Spreadsheet changes +http://www.simantics.org/Spreadsheet-1.2/HasContent http://www.simantics.org/Spreadsheet-1.2/Cell/content +http://www.simantics.org/Spreadsheet-1.2/FitRows http://www.simantics.org/Spreadsheet-1.2/Dimensions/fitRows +http://www.simantics.org/Spreadsheet-1.2/FitColumns http://www.simantics.org/Spreadsheet-1.2/Dimensions/fitColumns +http://www.simantics.org/Spreadsheet-1.2/ColumnCount http://www.simantics.org/Spreadsheet-1.2/Dimensions/columnCount +http://www.simantics.org/Spreadsheet-1.2/ColumnLabels http://www.simantics.org/Spreadsheet-1.2/Headers/columnLabels +http://www.simantics.org/Spreadsheet-1.2/RowCount http://www.simantics.org/Spreadsheet-1.2/Dimensions/rowCount +http://www.simantics.org/Spreadsheet-1.2/ColumnWidths http://www.simantics.org/Spreadsheet-1.2/Headers/columnWidths + +http://www.simantics.org/Spreadsheet-1.2/ContentOf http://www.simantics.org/Spreadsheet-1.2/Cell/content/Inverse +http://www.simantics.org/Spreadsheet-1.2/FitRowsOf http://www.simantics.org/Spreadsheet-1.2/Dimensions/fitRows/Inverse +http://www.simantics.org/Spreadsheet-1.2/FitColumnsOf http://www.simantics.org/Spreadsheet-1.2/Dimensions/fitColumns/Inverse +http://www.simantics.org/Spreadsheet-1.2/ColumnCountOf http://www.simantics.org/Spreadsheet-1.2/Dimensions/columnCount/Inverse +http://www.simantics.org/Spreadsheet-1.2/ColumnLabelsOf http://www.simantics.org/Spreadsheet-1.2/Headers/columnLabels/Inverse +http://www.simantics.org/Spreadsheet-1.2/RowCountOf http://www.simantics.org/Spreadsheet-1.2/Dimensions/rowCount/Inverse +http://www.simantics.org/Spreadsheet-1.2/ColumnWidthsOf http://www.simantics.org/Spreadsheet-1.2/Headers/columnWidths/Inverse \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Auxiliary.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Auxiliary.java new file mode 100644 index 00000000..bf68a9d4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Auxiliary.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(SysdynResource.URIs.Auxiliary) +public class Auxiliary extends IndependentVariable { + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Book.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Book.java new file mode 100644 index 00000000..da0feb35 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Book.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; +import java.util.List; + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.spreadsheet.resource.SpreadsheetResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(SpreadsheetResource.URIs.Book) +public class Book extends Variable { + + @RelatedElements( + value = Layer0.URIs.ConsistsOf, + composition = true) + private ArrayList sheets = new ArrayList(); + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + public List getSheets() { + return sheets; + } + + public String markBook() { + return "BOOK " + this.getName(); + } + + public String getBook() { + StringBuilder book = new StringBuilder(); + +// book.append("partial class SpreadSheetBook\n"); + + for(Sheet sheet : sheets) + book.append(sheet.getStringRepresentation()); + +// book.append("end SpreadSheetBook;"); + + return book.toString(); + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Cloud.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Cloud.java new file mode 100644 index 00000000..1244dcf2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Cloud.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(SysdynResource.URIs.Cloud) +public class Cloud implements IElement { + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Configuration.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Configuration.java new file mode 100644 index 00000000..e5d8d053 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Configuration.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; + +/** + * Representation of a model or module configuration + * + * @author Teemu Lempinen + * + */ +@GraphType(SysdynResource.URIs.Configuration) +public class Configuration { + + @RelatedValue(Layer0.URIs.HasName) + private String name; + + @RelatedValue(Layer0.URIs.HasLabel) + private String label; + + /** + * Not null if configuration of a module + */ + @RelatedElement(StructuralResource2.URIs.Defines) + private ModuleType moduleType; + + /** + * Not null if is configuration of a model + */ + @RelatedElement(SimulationResource.URIs.IsConfigurationOf) + private Model model; + + @RelatedElements( + value = Layer0.URIs.ConsistsOf, + composition = true) + private ArrayList elements = new ArrayList(); + + private boolean isGameConfiguration = false; + + public void setIsGameConfiguration(boolean isGame) { + this.isGameConfiguration = isGame; + } + + public boolean isGameConfiguration() { + return this.isGameConfiguration; + } + + /** + * Get all elements of this configuration. Also all sheets from books are included. + * @return + */ + public ArrayList getElements() { + ArrayList elements = new ArrayList(); + elements.addAll(this.elements); + for(IElement e : this.elements) { + if(e instanceof Book) { + elements.addAll(((Book)e).getSheets()); + } + } + return elements; + } + + public String getName() { + return name; + } + + public String getLabel() { + return label != null ? label : name; + } + + public ModuleType getModuleType() { + return moduleType; + } + + public Model getModel() { + return model; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Dependency.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Dependency.java new file mode 100644 index 00000000..f41c2014 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Dependency.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(SysdynResource.URIs.Dependency) +public class Dependency implements IElement { + @RelatedElement(SysdynResource.URIs.Variable_HasTail) + private IElement tail; + @RelatedElement(SysdynResource.URIs.Variable_HasHead) + private IElement head; + @RelatedElement(SysdynResource.URIs.Dependency_refersTo) + private IElement refersTo; + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + public IElement getTail() { + return this.tail; + } + + public IElement getHead() { + return this.head; + } + + public IElement refersTo() { + return this.refersTo; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/DiagramContainerDummy.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/DiagramContainerDummy.java new file mode 100644 index 00000000..3ad14641 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/DiagramContainerDummy.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(DiagramResource.URIs.DiagramContainer) +public class DiagramContainerDummy implements IElement { + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Entity.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Entity.java new file mode 100644 index 00000000..ec61ed05 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Entity.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +/** + * Dummy class representing any entity. + * @author Teemu Lempinen + * + */ +@GraphType(Layer0.URIs.Entity) +public class Entity implements IElement { + + @Override + public void accept(IElementVisitorVoid v) { + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java new file mode 100644 index 00000000..c87889cb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.objmap.annotations.RelatedListElements; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(SysdynResource.URIs.Enumeration) +public class Enumeration extends Variable { + + @RelatedListElements(SysdynResource.URIs.Enumeration_enumerationIndexList) + private ArrayList enumerationIndexes = new ArrayList(); + + @RelatedValue(SysdynResource.URIs.Enumeration_isReplaceable) + private Boolean isReplaceable; + + @RelatedElements( + value = SysdynResource.URIs.Redeclaration_replacedEnumeration_Inverse, + composition = true) + private ArrayList redeclarations = new ArrayList(); + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + public String getDeclaration() { + StringBuilder sb = new StringBuilder(); + sb.append(getEnumerationClassDefinition()); + sb.append(" "); + sb.append(getModelicaName() + "_class"); + sb.append(" " + getModelicaName()); + sb.append(";\n"); + + sb.append(" parameter Integer " + getModelicaName() + "_size = " + getModelicaName() + ".size;\n"); + sb.append(" parameter Integer " + getModelicaName() + "_elements[:] = " + getModelicaName() + ".elements;\n"); + return sb.toString(); + } + + public ArrayList getEnumerationIndexes() { + return enumerationIndexes; + } + + public boolean isReplaceable() { + return Boolean.TRUE.equals(isReplaceable); + } + + public String getEnumerationClassDefinition() { + + // Build indexes (one = 1, two = 2, etc..) and elements {1,2,3,..,size} + ArrayList indexes = getEnumerationIndexes(); + StringBuilder elementsBuilder = new StringBuilder(); + elementsBuilder.append("{"); + StringBuilder indexesBuilder = new StringBuilder(); + for(int i = 1; i <= indexes.size(); i++) { + indexesBuilder.append(" constant Integer "); + indexesBuilder.append(indexes.get(i - 1).getModelicaName()); + indexesBuilder.append(" = " + i + ";\n"); + + elementsBuilder.append(i); + if(i < indexes.size()) + elementsBuilder.append(","); + } + elementsBuilder.append("}"); + + /* + * class E_class + * extends Enumeration_class(size = n, elements = {1,2,3,..n}); + * constant Integer index1 = 1; + * constant Integer index2 = 2; + * .... + * constant Integer indexn = n; + * end E_class; + */ + + StringBuilder sb = new StringBuilder(); + sb.append(" class "); + sb.append(getModelicaName()); + sb.append("_class\n"); + sb.append(" extends Enumeration_class(size="); + sb.append(indexes.size()); + sb.append(", elements="); + sb.append(elementsBuilder); + sb.append(");\n"); + sb.append(indexesBuilder); + sb.append(" end "); + sb.append(getModelicaName()); + sb.append("_class;\n"); + + return sb.toString(); + } + + public ArrayList getRedeclarations() { + return redeclarations; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndex.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndex.java new file mode 100644 index 00000000..7e7e8364 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/EnumerationIndex.java @@ -0,0 +1,29 @@ +package org.simantics.sysdyn.representation; + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; + +@GraphType(SysdynResource.URIs.EnumerationIndex) +public class EnumerationIndex { + + @RelatedValue(Layer0.URIs.HasName) + protected String name; + + public String getName() { + return this.name; + } + + /** + * Get Modelica compliant name + * @return The name of this variable with spaces (' ') replaced with + * underscore characters ('_') + */ + public String getModelicaName() { + if (this.name == null) + return null; + return this.name.replace(' ', '_'); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Flow.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Flow.java new file mode 100644 index 00000000..43a31d05 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Flow.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(SysdynResource.URIs.Flow) +public class Flow implements IElement { + @RelatedElement(SysdynResource.URIs.Variable_HasTail) + private IElement tail; + @RelatedElement(SysdynResource.URIs.Variable_HasHead) + private IElement head; + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + public IElement getTail() { + return this.tail; + } + + public IElement getHead() { + return this.head; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Function.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Function.java new file mode 100644 index 00000000..7210ddc1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Function.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.objmap.annotations.UpdateMethod; +import org.simantics.sysdyn.SysdynResource; + +/** + * Representation of a function + * + * @author Teemu Lempinen + * + */ +@GraphType(SysdynResource.URIs.SysdynModelicaFunction) +public class Function { + + @RelatedValue(Layer0.URIs.HasName) + private String name; + + @RelatedValue(SysdynResource.URIs.SysdynModelicaFunction_modelicaFunctionCode) + private String code; + + private boolean hasTimeReference = false; + + public String getCode() { + return + "function " + name + "\n" + + code + + "end " + name + ";\n"; + } + + public String getName() { + return name; + } + + /** + * Keep track if the function contains references to time. If there is a reference to time, + * the variables calling this function cannot be parameters or constants. + * + * @param g ReadGraph + * @param r Function resource + * @return + * @throws DatabaseException + */ + @UpdateMethod + public boolean update(ReadGraph g, Resource r) throws DatabaseException { + hasTimeReference = false; + + String code = g.getPossibleRelatedValue(r, SysdynResource.getInstance(g).SysdynModelicaFunction_modelicaFunctionCode); + if(code == null) + return true; + + String[] elements = code.split("[\\+\\-\\*\\/\\(\\)\\[\\]\\{\\}=;\\s]"); + for(String element : elements) { + if("time".equals(element)) { + hasTimeReference = true; + break; + } + } + return true; + } + + public boolean hasTimeReference() { + return hasTimeReference; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/FunctionLibrary.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/FunctionLibrary.java new file mode 100644 index 00000000..5300a34e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/FunctionLibrary.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; + + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +/** + * Representation of a function library + * + * @author Teemu Lempinen + * + */ +@GraphType(SysdynResource.URIs.SysdynModelicaFunctionLibrary) +public class FunctionLibrary { + + @RelatedValue(Layer0.URIs.HasName) + private String name; + + @RelatedElements( + value = Layer0.URIs.ConsistsOf, + composition = true) + private ArrayList elements = new ArrayList(); + + /** + * Get all functions inside this library. (sub-libraries excluded) + * @return + */ + public ArrayList getFunctions() { + ArrayList functions = new ArrayList(); + if(elements != null) { + for(Object element : elements) { + if(element instanceof Function) + functions.add((Function)element); + } + } + return functions; + } + + /** + * Get all function libraries included in this library + * @return All function libraries included in this library + */ + public ArrayList getLibraries() { + ArrayList libraries = new ArrayList(); + if(elements != null) { + for(Object element : elements) { + if(element instanceof FunctionLibrary) + libraries.add((FunctionLibrary)element); + } + } + return libraries; + } + + /** + * Get the name of this library + * @return The name of this library + */ + public String getName() { + return name; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IElement.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IElement.java new file mode 100644 index 00000000..a44aafa2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IElement.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +public interface IElement { + void accept(IElementVisitorVoid v); +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java new file mode 100644 index 00000000..d61abcf0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.expressions.IExpression; +import org.simantics.sysdyn.representation.expressions.ParameterExpression; +import org.simantics.sysdyn.representation.expressions.StockExpression; +import org.simantics.sysdyn.representation.utils.FormatUtils; + +/** + * Representation of an independent variable + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public abstract class IndependentVariable extends Variable { + + @RelatedElements( + value = SysdynResource.URIs.Variable_isHeadOf, + composition = true) + private ArrayList isHeadOf = new ArrayList(); + + /** + * Get the declaration of this variable + * @return Declaration of this variable + */ + public String getDeclaration() { + Variability variability = Variability.getVariability(this); + + // [variability] type name[range] + StringBuilder sb = new StringBuilder(); + sb.append(" "); + sb.append(variability.getText().isEmpty() ? "" : variability.getText() + " "); + sb.append(getType() + " "); + sb.append(getModelicaName()); + sb.append(getRange()); + + // [= expression] + if(variability == Variability.PARAMETER || variability == Variability.CONSTANT) { + // parameters and constants are guaranteed to have only one expression + String expression = getExpressions().get(0).getExpression(); + expression = FormatUtils.replaceWhitespace(expression); + String equation = FormatUtils.formatExpressionForModelica(this, expression); + sb.append(" = " + equation); + } + + // ;\n + sb.append(";\n"); + + // Possible additions to expressions. e.g. helper classes and variables + if(getExpressions() != null) { + String addition; + for(IExpression e : getExpressions()) { + addition = e.getDeclarationAddition(); + if(addition != null) + sb.append(addition); + } + } + + return sb.toString(); + } + + /** + * Get the range of this variable, if it is an array variable. + *

+ * Format: [EnumerationName.size (, Enumeration2Name.size)*] + * @return Range of this variable, if it is an array variable. Empty string otherwise. + */ + public String getRange() { + ArrayList enumerations = getArrayIndexes(); + String range = ""; + if(enumerations != null && enumerations.size() > 0) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + Iterator iterator = enumerations.iterator(); + while(iterator.hasNext()) { + sb.append(iterator.next().getModelicaName() + ".size"); + if(iterator.hasNext()) { + sb.append(", "); + } + } + sb.append("]"); + range = sb.toString(); + } + return range; + } + + /** + * Get all initial equations or null, if there are no initial equations. + * @return Initial equations as string or null. + */ + public String getInitialEquation() { + StringBuilder sb = new StringBuilder(); + + for(IExpression expression : getExpressions()) { + String initialEquation = expression.getInitialEquation(); + if(initialEquation != null) + sb.append(initialEquation); + } + String result = sb.toString(); + return result.length() > 0 ? result : null; + } + + /** + * Get the equation of this variable for equation block. Null is returned if this variable is not continuous. + * @return Equation or null + */ + public String getEquation() { + Variability variability = Variability.getVariability(this); + if(variability == Variability.CONTINUOUS) { + return getVariableEquation(); + } else { + return null; + } + + } + + /** + * Combines all possible equations for this variable. Array variables can have multiple equations. + * @return equations or null + */ + protected String getVariableEquation() { + if(this.expressions == null || this.expressions.isEmpty()) + return null; + + ArrayList expressions = getExpressions(); + ArrayList enumerations = getArrayIndexes(); + IExpression firstExpression = expressions.get(0); + if(enumerations == null || enumerations.size() < 1) { + if(firstExpression == null) + return null; + else + return firstExpression.getEquation(); + } else { + // ARRAY variable. Create all equations for the variable + StringBuilder sb = new StringBuilder(); + for(IExpression expression : expressions) { + sb.append(expression.getEquation()); + } + return sb.toString(); + } + } + + public ArrayList getIncomingDependencies() { + return isHeadOf; + } + + @Override + public String getDocumentationDefinition(ReadGraph graph) throws DatabaseException { + String declaration = getDeclaration(); + String initialEquation = getInitialEquation(); + + StringBuilder result = new StringBuilder(); + + if(declaration != null && declaration.length() > 0 && declaration.contains("=")) { + result.append("

"); + if(getExpressions().size() > 1) + result.append(formatForHTML(declaration)); + if(this instanceof Stock) + result.append(formatForHTML(declaration.substring(declaration.indexOf("(") + 1, declaration.lastIndexOf(")")))); + else + result.append(formatForHTML(declaration.substring(declaration.indexOf("=") + 1))); + result.append("

"); + } + + result.append("

"); + for(IExpression exp : getExpressions()) { + String expression = exp.getDocumentationExpression(graph); + if(!(exp instanceof StockExpression)) + expression = expression.substring(expression.indexOf("=") + 1); + if(!(exp instanceof ParameterExpression)) + result.append(formatForHTML(expression)); + } + result.append("

"); + + if(initialEquation != null && initialEquation.length() > 0) { + result.append("

Initial value:

"); + if(getExpressions().size() > 1) + result.append(formatForHTML(initialEquation)); + else + result.append(formatForHTML(initialEquation.substring(initialEquation.indexOf("=") + 1))); + result.append("

"); + } + + result.append(super.getDocumentationDefinition(graph)); + + return result.toString(); + } + + private String formatForHTML(String text) { + text= text.trim(); + text = text.replaceAll("\\r\\n|\\r|\\n", "
"); + if(text.endsWith(";")) + text = text.substring(0, text.length() - 1); + text = text.replace("/* Actual value read from init file */", ""); + return text; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Input.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Input.java new file mode 100644 index 00000000..fe899208 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Input.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +/** + * Representation of an input variable + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.Input) +public class Input extends Variable { + + @RelatedValue(SysdynResource.URIs.Input_defaultInputValue) + private Double defaultInputValue; + @RelatedElements(SysdynResource.URIs.Variable_isHeadOf) + private List isHeadOf; + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + /** + * Get the default value for this input. Default values may be set in either + * inside input's own module or in its parent module. If the value is set in a + * parent module, give input module's instance name as inModule. + * + * @param inModule The name of the instance in which this variable is. + * Can be null, if default value is set inside the variable's own module. + * @return Default input value. + */ + public String getDefaultInputValue(String inModule) { + if( getArrayIndexes() == null || getArrayIndexes().isEmpty()) { + return defaultInputValue.toString(); + } else { + StringBuilder sb = new StringBuilder(); + sb.append("fill("); + sb.append(defaultInputValue); + sb.append(", "); + Iterator i = getArrayIndexes().iterator(); + while(i.hasNext()) { + Enumeration e = i.next(); + sb.append((inModule != null && !inModule.isEmpty() ? inModule + "." : "") + e.getModelicaName() + ".size"); + if(i.hasNext()) + sb.append(", "); + } + sb.append(")"); + return sb.toString(); + } + } + + /** + * Get the default value for this input inside it's own module. + * @return Default value + */ + public String getDefaultInputValue() { + return getDefaultInputValue(null); + } + + /** + * Is there a connection to this input variable from a module. (i.e. does this input variable possibly get its value from a child module) + * @return + */ + public boolean isHeadOfDependency() { + return !isHeadOf.isEmpty(); + } + + /** + * Get the declaration of this input variable with its default value + * @return declaration of this input variable with its default value + */ + public String getDeclarationWithValue() { + String declaration = getDeclaration(); + declaration = declaration.substring(0, declaration.length() - 2); // remove ";\n" + declaration += " = " + getDefaultInputValue() + ";\n"; + return declaration; + } + + /** + * Get the declaration of this input variable without a default value + * @return declaration of this input variable without a default value + */ + public String getDeclaration() { + ArrayList enumerations = getArrayIndexes(); + String range = ""; + if(enumerations != null && enumerations.size() > 0) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + Iterator iterator = enumerations.iterator(); + while(iterator.hasNext()) { + sb.append(iterator.next().getModelicaName() + ".size"); + if(iterator.hasNext()) { + sb.append(", "); + } + } + sb.append("]"); + range = sb.toString(); + } + + boolean continuous = variability == null || variability.isEmpty(); + return " " + (continuous ? "" : variability + " ") + getType() + " " + getModelicaName() + range + ";\n"; + } + + @Override + public String getDocumentationDefinition(ReadGraph graph) throws DatabaseException { + String expression = getDefaultInputValue() + " // Default value"; + + if(isHeadOf.size() > 0 && isHeadOf.get(0) instanceof Dependency) { + Dependency dependency = (Dependency) isHeadOf.get(0); + Module module = (Module)dependency.getTail(); + Variable reference = (Variable)dependency.refersTo(); + // If reference exists, use reference name. Otherwise, use default value. + if(reference != null && reference.getModelicaName() != null) + expression = "Reference:
" + module.getName() + "." + reference.getModelicaName() + ";\n"; + } + + return expression + super.getDocumentationDefinition(graph); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/LibraryDummy.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/LibraryDummy.java new file mode 100644 index 00000000..6abe502c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/LibraryDummy.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +/** + * A dummy variable representing any possible library + * @author Teemu Lempinen + * + */ +@GraphType(Layer0.URIs.Library) +public class LibraryDummy implements IElement { + + @RelatedValue(Layer0.URIs.HasName) + private String name; + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + /** + * Name of the library + * @return Name of the library + */ + public String getName() { + return name; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/LoadRepresentation.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/LoadRepresentation.java new file mode 100644 index 00000000..fd5aac59 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/LoadRepresentation.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.objmap.IMapping; +import org.simantics.objmap.MappingException; +import org.simantics.objmap.Mappings; +import org.simantics.sysdyn.manager.SysdynConsole; + +public class LoadRepresentation { + + public static IMapping loadMappedMapping(Session session, final Resource configuration) throws DatabaseException { + return session.syncRequest(new Read() { + + @Override + public IMapping perform(ReadGraph graph) + throws DatabaseException { + SysdynSchema schema = new SysdynSchema(graph); + IMapping mapping = Mappings.createWithoutListening(schema); + + try { + mapping.map(graph, configuration); + } catch (MappingException e) { + SysdynConsole.INSTANCE.message( + "Error: Mapping is broken! Find the problem, " + + "fix it and restart the program." + + "\nJava error message:\n" + + e.getMessage()); + throw e; + } + + return mapping; + } + + }); + } + + public static Configuration loadConfiguration(Session session, final Resource configuration) throws DatabaseException { + return session.syncRequest(new Read() { + + @Override + public Configuration perform(ReadGraph graph) + throws DatabaseException { + SysdynSchema schema = new SysdynSchema(graph); + IMapping mapping = Mappings.createWithoutListening(schema); + + try { + return (Configuration)mapping.map(graph, configuration); + } catch (MappingException e) { + SysdynConsole.INSTANCE.message( + "Error: Mapping is broken! Find the problem, " + + "fix it and restart the program." + + "\nJava error message:\n" + + e.getMessage()); + throw e; + } + + } + + }); + } + + public static IElement loadElement(Session session, final Resource element) throws DatabaseException { + return session.syncRequest(new Read() { + + @Override + public IElement perform(ReadGraph graph) + throws DatabaseException { + SysdynSchema schema = new SysdynSchema(graph); + IMapping mapping = Mappings.createWithoutListening(schema); + + try { + return (IElement)mapping.map(graph, element); + } catch (MappingException e) { + SysdynConsole.INSTANCE.message( + "Error: Mapping is broken! Find the problem, " + + "fix it and restart the program." + + "\nJava error message:\n" + + e.getMessage()); + throw e; + } + + } + + }); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Loop.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Loop.java new file mode 100644 index 00000000..f81e5355 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Loop.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedListElements; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + + +@GraphType(SysdynResource.URIs.Loop) +public class Loop implements IElement { + + @RelatedValue(Layer0.URIs.HasName) + protected String name; + + @RelatedElement(Layer0.URIs.PartOf) + protected Object parent; + + @RelatedValue(SysdynResource.URIs.LoopSymbol_Clockwise) + protected Boolean clockwise; + + @RelatedValue(SysdynResource.URIs.Loop_Comment) + protected String comment; + + @RelatedListElements(SysdynResource.URIs.Loop_Items) + protected ArrayList items = new ArrayList(); + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + /** + * + * @return The name of this loop + */ + public String getName() { + return this.name; + } + + /** + * + * @return The comment of this loop + */ + public String getComment() { + return this.comment; + } + + /** + * + * @return The variables and dependencies of this loop + */ + public ArrayList getItems() { + return this.items; + } + + /** + * + * @return true iff loop rotates clockwise. + */ + public boolean isClockwise() { + return this.clockwise; + } + + /** + * + * @return Parent configuration of this loop (or null if something is wrong) + */ + public Configuration getParentConfiguration() { + if(parent instanceof Configuration) { + return (Configuration)parent; + } else { + return null; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Model.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Model.java new file mode 100644 index 00000000..76f28a47 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Model.java @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.annotations.BuiltinFunctions; + +/** + * Representation of a system dynamics model + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.SysdynModel) +public class Model { + + @RelatedValue(SysdynResource.URIs.SysdynModel_startTime) + private final Double startTime = 0.0; + + @RelatedValue(SysdynResource.URIs.SysdynModel_stopTime) + private final Double stopTime = 10.0; + + @RelatedValue(SysdynResource.URIs.SysdynModel_outputInterval) + private Double outputInterval; + + @RelatedValue(SysdynResource.URIs.SysdynModel_simulationStepLength) + private Double stepLength; + + @RelatedValue(SysdynResource.URIs.SysdynModel_tolerance) + private Double tolerance; + + @RelatedValue(SysdynResource.URIs.SysdynModel_solver) + private String solver; + + @RelatedValue(SysdynResource.URIs.SysdynModel_variableFilter) + private String variableFilter; + + @RelatedElement(SimulationResource.URIs.HasConfiguration) + private Configuration configuration; + + @RelatedValue(SysdynResource.URIs.SysdynModel_timeUnit) + private String timeUnit; + + @RelatedElements( + value = Layer0.URIs.ConsistsOf, + composition = true) + private final ArrayList consistsOf = new ArrayList(); + + @RelatedElements( + value = Layer0.URIs.IsLinkedTo, + composition = true) + private final ArrayList linkedTo = new ArrayList(); + + + @BuiltinFunctions + private FunctionLibrary builtins; + + /** + * + * @return Simulation start time + */ + public Double getStartTime() { + return startTime; + } + + /** + * + * @return Simulation end time + */ + public Double getStopTime() { + return stopTime; + } + + /** + * Simulation output interval + * @return + */ + public Double getOutputInterval() { + return outputInterval; + } + + /** + * Simulation step length + * @return + */ + public Double getSimulationStepLength() { + return stepLength; + } + /** + * + * @return Tolerance for simulation engine + */ + public Double getTolerance() { + return tolerance; + } + + /** + * + * @return Solver name + */ + public String getSolver() { + return solver; + } + + /** + * + * @return variableFilter or ".*" if null + */ + public String getVariableFilter() { + if(variableFilter == null || variableFilter.isEmpty()) + return ".*"; + else + return variableFilter; + } + + /** + * Get all functions that are linked to this model: built-in functions, model's own functions and shared function libraries + * @return all functions liked to this model + */ + public HashMap getFunctions() { + HashMap functions = new HashMap(); + if(consistsOf != null ) { + for(Object o : consistsOf) { + if(o instanceof Function) { + Function f = (Function) o; + functions.put(f.getName(), f); + } else if (o instanceof FunctionLibrary) { + addFunctions("", (FunctionLibrary)o, functions); + } + } + } + + if(linkedTo != null) { + for(Object o : linkedTo) { + if(o instanceof SharedFunctionLibrary) { + SharedFunctionLibrary fl = (SharedFunctionLibrary)o; + addFunctions(fl.getName(), fl, functions); + } + } + } + + if(builtins != null) + addBuiltinFunctions(builtins, functions); + + return functions; + } + + /** + * Determine if this Model consists of a certain ModuleType. + * @param moduleType The name of the ModuleType that is sought + * @return true iff this consists of moduleType + */ + public boolean containsModuleType(String moduleType) { + if(consistsOf != null ) { + for(Object o : consistsOf) { + if(o instanceof ModuleType) { + ModuleType mt = (ModuleType)o; + if (mt.getName().equals(moduleType)) + return true; + } + } + } + return false; + } + + /** + * Determine if this Model consists of a certain Function or + * FunctionLibrary ON THE TOP LEVEL. + * @param elementName The name of the element that is sought + * @return true iff this consists of element + */ + public boolean containsFunctionOrLibrary(String elementName) { + if(consistsOf != null ) { + for(Object o : consistsOf) { + if(o instanceof Function) { + Function f = (Function)o; + if (f.getName().equals(elementName)) + return true; + } + else if(o instanceof FunctionLibrary) { + FunctionLibrary fl = (FunctionLibrary)o; + if (fl.getName().equals(elementName)) + return true; + } + } + } + return false; + } + + /** + * Add built-in functions to functions map. Built-in functions do not have any library path. + * @param library Built-in function library + * @param functions Function map containing all functions + */ + private void addBuiltinFunctions(FunctionLibrary library, HashMap functions) { + for(Function f : library.getFunctions()) + functions.put(f.getName(), f); + for(FunctionLibrary fl : library.getLibraries()) + addBuiltinFunctions(fl, functions); + } + + /** + * Add functions from a library to a library map + * @param path Path to the library + * @param library Function library + * @param functions Function map containing all functions + */ + private void addFunctions(String path, FunctionLibrary library, HashMap functions) { + for(Function f : library.getFunctions()) + functions.put(path + (path.isEmpty() ? "" : ".") + f.getName(), f); + for(FunctionLibrary fl : library.getLibraries()) + addFunctions((path.isEmpty() ? "" : path + ".") + fl.getName(), fl, functions); + } + + /** + * + * @return Built-in functions library + */ + public FunctionLibrary getBuiltins() { + return builtins; + } + + + /** + * + * @return Configuration of this model + */ + public Configuration getModelConfiguration() { + return configuration; + } + + + public String getTimeUnit() { + return timeUnit; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Module.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Module.java new file mode 100644 index 00000000..3938f200 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Module.java @@ -0,0 +1,352 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; +import org.simantics.utils.datastructures.Pair; + +/** + * Representation of a module instance + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.Module) +public class Module implements IElement { + + @RelatedValue(Layer0.URIs.HasName) + private String name; + + @RelatedElement(Layer0.URIs.PartOf) + private Configuration parentConfiguration; + + @RelatedElement(Layer0.URIs.InstanceOf) + private ModuleType type; + + @RelatedElements(SysdynResource.URIs.Module_redeclaration) + private List redeclarations; + + @RelatedElements(Layer0.URIs.ConsistsOf) + private List consistsOf; + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + public String getName() { + return name; + } + + public ModuleType getType() { + return type; + } + + /** + * Returns the declaration of a module with possible redeclared enumerations and parameter assignments + * + *

+ * Enumeration redeclaration: + * parameter Integer Enum__size = Enum.size;
+ * parameter Integer Enum__elements[:] = Enum.elements;
+ * ModuleType ModuleType1(Enum.size = Enum__size, Enum.elements = Enum__elements);
+ * + *

+ * Temporary parameter variables are needed to avoid name conflicts when redeclaring an + * enumeration with the same name. + * + * @return Declaration of a module instance + */ + public String getDeclaration() { + + + String enumerationRedeclarations = getEnumerationRedeclarations(); + Pair inputRedeclarations = getInputRedeclarations(); + String parameterOverrides = getParameterOverrideString(); + + StringBuilder redeclarations = new StringBuilder(); + + if(!enumerationRedeclarations.isEmpty() || !inputRedeclarations.first.isEmpty() || !parameterOverrides.isEmpty()) { + redeclarations.append("("); + redeclarations.append(enumerationRedeclarations); + + String ir = inputRedeclarations.first; + if(enumerationRedeclarations.isEmpty() && !inputRedeclarations.first.isEmpty()) + // remove first ", " if no enumeration redeclarations + ir = inputRedeclarations.first.substring(2); + redeclarations.append(ir); + + if(!parameterOverrides.isEmpty()) { + if(redeclarations.length() > 1) + redeclarations.append(", "); + redeclarations.append(parameterOverrides); + } + + redeclarations.append(")"); + } + + StringBuilder sb = new StringBuilder(); + + // Possible reference variables + if(inputRedeclarations.second != null && !inputRedeclarations.second.isEmpty()) { + sb.append(inputRedeclarations.second); + } + + sb.append(" "); + sb.append(getType().getName()); + sb.append(" "); + sb.append(getName()); + sb.append(redeclarations.toString()); // possible redeclarations + sb.append(";\n"); + return sb.toString(); + } + + /** + * Get possible enumeration redeclarations. + * @return enumeration redeclarations or empty string + */ + private String getEnumerationRedeclarations() { + StringBuilder redeclarations = new StringBuilder(); + if(!getRedeclarations().isEmpty()) { + + boolean first = true; + Iterator i = getRedeclarations().iterator(); + while(i.hasNext()) { + Redeclaration rd = i.next(); + String redeclaration = rd.getRedeclaration(); + if(redeclaration != null && !redeclaration.isEmpty()) { + if(!first) { + redeclarations.append(","); + } else { + first = false; + } + redeclarations.append(redeclaration); + } + } + } + return redeclarations.toString(); + } + + /** + * Get possible input redeclarations + * @return input redeclarations or empty string + */ + private Pair getInputRedeclarations() { + StringBuilder declarations = new StringBuilder(); + StringBuilder references = new StringBuilder(); + + for(IElement element : parentConfiguration.getElements()) { + if (element instanceof Dependency) { + Dependency dependency = (Dependency)element; + if(dependency.getHead().equals(this)){ + Input reference = (Input)dependency.refersTo(); + Variable outputVariable = (Variable)dependency.getTail(); + if(outputVariable instanceof Shadow) + outputVariable = ((Shadow) outputVariable).getOriginal(); + + String name = outputVariable.getModelicaName(); + + Module module = (Module)dependency.getHead(); + + if(reference != null && reference.getName() != null) { + if(reference.getVariability() == null || reference.getVariability().isEmpty()) + continue; // Only parameters and constants are redeclared + + for(IElement e : module.getType().getConfiguration().getElements()) { + if(e instanceof Variable) { + Variable v = (Variable)e; + + if(v.getName() != null && outputVariable.getName().equals(v.getName())) { + /* + * The target module contains a variable with the same name. Need to + * avoid Module(variable = variable) situations + */ + String declaration; + if(outputVariable instanceof Input) + declaration = ((Input)outputVariable).getDeclaration(); + else + declaration = ((IndependentVariable)outputVariable).getDeclaration(); + + if(declaration.contains("=")) + declaration = declaration.substring(0, declaration.indexOf("=") - 1); // Break to "=" + else + declaration = declaration.substring(0, declaration.length() - 2); // Remove ending ";\n" + + name = outputVariable.getModelicaName() + "_reference"; + declaration = declaration.replace(outputVariable.getModelicaName(), name); + declaration += " = " + outputVariable.getModelicaName() + " /* Reference value to avoid name conflicts in module instantiation */ ;\n"; + references.append(declaration); + break; + } + } + } + + declarations.append(", " + reference.getModelicaName() + " = " + name); + } + } + } + } + return new Pair(declarations.toString(), references.toString()); + } + + public Configuration getParentConfiguration() { + return this.parentConfiguration; + } + + /** + * Return the list of the defined redeclarations for this module instance. + * + * @return List of the defined redeclarations or an empty list if redeclarations have not been set + */ + public List getRedeclarations() { + if(redeclarations == null) { + redeclarations = new ArrayList(); + } + return redeclarations; + } + + + /** + * Get all parameter override elements for this module instance as a string "param = value, param2 = value2, ..." + * @return parameter overrides + */ + public String getParameterOverrideString() { + String result = ""; + + for(ParameterOverride po : getParameterOverrides()) { + IndependentVariable var = po.getVariable(); + if(!Variability.CONTINUOUS.equals(Variability.getVariability(var, false, parentConfiguration))) { + if(!result.isEmpty()) + result += ", "; + + result += po.getOverride(); + } + } + + return result; + } + + + /** + * Get all parameter overrides of this module instance + * @return + */ + public Set getParameterOverrides() { + HashSet result = new HashSet(); + if(consistsOf != null) { + for(Entity e : consistsOf) { + if(e instanceof ParameterOverride) { + result.add( (ParameterOverride) e); + } + } + } + return result; + } + + + + public String getDocumentationDefinition() { + String enumerationRedeclarations = getEnumerationRedeclarations(); + String parameterOverrides = getParameterOverrideString(); + + StringBuilder result = new StringBuilder(); + + String[] erecs = enumerationRedeclarations.split(","); + boolean first = true; + result.append("

"); + for(String s : erecs) { + if(s.length() == 0) + continue; + + if(first) { + result.append("Enumeration redeclarations:
"); + } + first = false; + result.append(s.trim()); + result.append("
"); + } + result.append("

"); + + + + first = true; + result.append("

"); + + String[] poverrds = parameterOverrides.split(","); + for(String s : poverrds) { + if(s.length() == 0) + continue; + + if(first) { + result.append("Parameter overrides:
"); + } + first = false; + result.append(s.trim()); + result.append("
"); + } + result.append("

"); + + ArrayList inputs = new ArrayList(); + ArrayList outputs = new ArrayList(); + for(IElement e : parentConfiguration.getElements()) { + if(e instanceof Dependency) { + Dependency d = (Dependency)e; + if(this.equals(d.getHead()) && d.refersTo() != null) { + inputs.add(d); + } else if(this.equals(d.getTail()) && d.refersTo() != null) { + outputs.add(d); + } + } + } + + first = true; + result.append("

"); + for(Dependency d : inputs) { + if(first) { + result.append("Inputs:
"); + } + first = false; + + result.append(getName() + "." + ((Variable)d.refersTo()).getModelicaName() + " = " + ((Variable)d.getTail()).getModelicaName()); + result.append("
"); + } + result.append("

"); + + first = true; + result.append("

"); + for(Dependency d : outputs) { + if(first) { + result.append("Outputs:
"); + } + first = false; + + result.append(((Variable)d.getHead()).getModelicaName() + " = " + getName() + "." + ((Variable)d.refersTo()).getModelicaName()); + result.append("
"); + } + result.append("

"); + + + return result.toString(); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ModuleType.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ModuleType.java new file mode 100644 index 00000000..bf7b84a9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ModuleType.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +/** + * Representation of a module type + * + * @author Teemu Lempinen + * + */ +@GraphType(StructuralResource2.URIs.ComponentType) +public class ModuleType implements IElement { + + @RelatedValue(Layer0.URIs.HasName) + private String name; + + @RelatedElement(StructuralResource2.URIs.IsDefinedBy) + private Object configuration; + + @RelatedElement(Layer0.URIs.PartOf) + protected Object parent; + + public String getName() { + return name; + } + + public Configuration getConfiguration() { + return configuration instanceof Configuration ? (Configuration)configuration : null; + } + + @Override + public void accept(IElementVisitorVoid v) { + } + + public Object getParent() { + return parent; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ParameterOverride.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ParameterOverride.java new file mode 100644 index 00000000..713f7ee0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ParameterOverride.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; + + +/** + * Representation of a parameter override + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.Module_ParameterOverride) +public class ParameterOverride extends Entity { + + @RelatedElement(SysdynResource.URIs.Module_ParameterOverride_overriddenParameter) + private IndependentVariable variable; + + @RelatedValue(SysdynResource.URIs.Module_ParameterOverride_overrideExpression) + private String expression; + + /** + * Get the parameter variable to be overridden + * @return parameter variable to be overridden + */ + public IndependentVariable getVariable() { + return variable; + } + + /** + * Get the overriding expression + * @return overriding expression + */ + public String getExpression() { + return expression; + } + + /** + * Get the complete override equation: "variable = overridingExpression" + * @return override equation + */ + public String getOverride() { + return variable.getModelicaName() + " = " + expression; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Redeclaration.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Redeclaration.java new file mode 100644 index 00000000..0d2efc98 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Redeclaration.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.sysdyn.SysdynResource; + +@GraphType(SysdynResource.URIs.Redeclaration) +public class Redeclaration { + + @RelatedElement(SysdynResource.URIs.Redeclaration_replacedEnumeration) + private Enumeration replacedEnumeration; + + @RelatedElement(SysdynResource.URIs.Redeclaration_replacingEnumeration) + private Enumeration replacingEnumeration; + + public String getRedeclaration() { + if(replacedEnumeration == null || replacingEnumeration == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + sb.append(replacedEnumeration.getModelicaName()); + sb.append(".size = "); + sb.append(replacingEnumeration.getModelicaName()); + sb.append("_size, "); + sb.append(replacedEnumeration.getModelicaName()); + sb.append(".elements = "); + sb.append(replacingEnumeration.getModelicaName()); + sb.append("_elements"); + + return sb.toString(); + } + + public Enumeration getReplacedEnumeration() { + return replacedEnumeration; + } + + public Enumeration getReplacingEnumeration() { + return replacingEnumeration; + } + + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Shadow.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Shadow.java new file mode 100644 index 00000000..91358b71 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Shadow.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.expressions.IExpression; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(SysdynResource.URIs.Shadow) +public class Shadow extends Variable { + + @RelatedElement(SysdynResource.URIs.Shadow_original) + private Variable original; + + @Override + public void accept(IElementVisitorVoid v) { + if(getOriginal() != null) + original.accept(v); + } + + public Variable getOriginal() { + return original; + } + + @Override + public String getName() { + if(getOriginal() != null) + return getOriginal().getName(); + else + return super.getName(); + } + + @Override + public ArrayList getArrayIndexes() { + if(getOriginal() != null) + return getOriginal().getArrayIndexes(); + else + return super.getArrayIndexes(); + } + + @Override + public ArrayList getExpressions() { + if(getOriginal() != null) + return getOriginal().getExpressions(); + else + return super.getExpressions(); + } + + @Override + public String getVariability() { + if(getOriginal() != null) + return getOriginal().getVariability(); + else + return super.getVariability(); + } + + @Override + public String getType() { + if(getOriginal() != null) + return getOriginal().getType(); + else + return super.getType(); + } + + @Override + public String getUnit() { + if(getOriginal() != null) + return getOriginal().getUnit(); + else + return super.getUnit(); + } + + @Override + public String getDocumentationDefinition(ReadGraph graph) throws DatabaseException { + return null; + } +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SharedFunctionLibrary.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SharedFunctionLibrary.java new file mode 100644 index 00000000..357f9d09 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SharedFunctionLibrary.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.sysdyn.SysdynResource; + +/** + * Representation of a shared function library. See {@link FunctionLibrary} + * + * @author Teemu Lempinen + * + */ +@GraphType(SysdynResource.URIs.SharedFunctionOntology) +public class SharedFunctionLibrary extends FunctionLibrary { + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Sheet.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Sheet.java new file mode 100644 index 00000000..7a87c0b5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Sheet.java @@ -0,0 +1,327 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; + +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.databoard.primitives.MutableString; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.UpdateMethod; +import org.simantics.spreadsheet.Range; +import org.simantics.spreadsheet.SheetVariables; +import org.simantics.spreadsheet.common.exception.CellParseException; +import org.simantics.spreadsheet.resource.SpreadsheetResource; +import org.simantics.spreadsheet.util.SpreadsheetUtils; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(SpreadsheetResource.URIs.Spreadsheet) +public class Sheet extends org.simantics.sysdyn.representation.Variable { + + @RelatedElement(Layer0.URIs.PartOf) + protected Book book; + + THashMap cells = new THashMap(); + THashSet usedRanges = new THashSet(); + + Resource resource; + + public String getSheet() { + return "Sheet"; + } + + @UpdateMethod + public boolean updateCells(ReadGraph g, Resource r) throws DatabaseException { + if(g.hasStatement(r)) { + this.resource = r; + THashMap newCells = new THashMap(); + + g.getObjects(r, Layer0.getInstance(g).ConsistsOf); + Variable v = g.adapt(r, Variable.class); + for(Variable child : v.getChildren(g)) { + String name = child.getName(g); + try { + SpreadsheetUtils.decodeCellAbsolute(name); + Variant value = child.getPropertyValue(g, SheetVariables.CONTENT, Bindings.VARIANT); + newCells.put(name, value.getValue()); + } catch (CellParseException e) { + } catch (MissingVariableException e) { + System.out.println("missing content for: " + name); + } + } + + boolean update = false; + if(newCells.size() == this.cells.size()) { + // Cells are the same size. There might not be changes. Next up: content + for(String key : this.cells.keySet()) { + if(!this.cells.get(key).equals(newCells.get(key))) { + update = true; + break; + } + } + } else { + update = true; + } + + if(update) { + this.cells = newCells; + this.usedRanges.clear(); + return true; + } + } + return false; + } + + public String getStringRepresentation() { + final StringBuilder clazz = new StringBuilder(); + clazz.append("class " + getModelicaName() + "_class\n"); + + try { + Simantics.getSession().syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + HashSet possibleRanges = new HashSet(); + + // Write all doubles that have been used in expressions + final HashSet usedCells = new HashSet(); + for(String key : usedRanges) { + if(cells.containsKey(key)) { + addRange(key, usedCells, clazz); + } else { + for(String range : getChildRanges(graph, key)) { + if(cells.containsKey(range)) + addRange(range, usedCells, clazz); + } + possibleRanges.add(key); + } + } + + // Get cell ranges. Add cell names that have not been used individually to usedCells set + // and use those names in ranges + + Variable v = graph.adapt(resource, Variable.class); + for(String possibleRange : possibleRanges) { + String[] parts = possibleRange.split(":"); + if(parts.length != 2 || !cells.containsKey(parts[0]) || !cells.containsKey(parts[1])) + continue; + Variable range = v.getChild(graph, possibleRange); + if(range == null) + continue; + String[][] rangeCells = range.getPropertyValue(graph, SheetVariables.RANGE_CELL_NAMES); + if(rangeCells == null) + continue; + + if(rangeCells[0].length > 1) { + // Has two dimensions + clazz.append(" parameter Real[" + rangeCells.length + ", " + rangeCells[0].length + "] "); + clazz.append(possibleRange.replace(":", "_") + " = {"); + for(int i = 0; i < rangeCells.length; i++) { + clazz.append("{"); + for(int j = 0; j < rangeCells[i].length; j++) { + clazz.append(rangeCells[i][j]); + usedCells.add(rangeCells[i][j]); // Add the cell name to used cells + if(j < rangeCells[i].length - 1) + clazz.append(", "); + } + clazz.append("}"); + if(i < rangeCells.length - 1) + clazz.append(", "); + } + clazz.append("};\n"); + } else { + // Has one dimension + clazz.append(" parameter Real[" + rangeCells.length + "] "); + clazz.append(possibleRange.replace(":", "_") + " = {"); + for(int i = 0; i < rangeCells.length; i++) { + clazz.append(rangeCells[i][0]); + usedCells.add(rangeCells[i][0]); // Add the cell name to used cells + if(i < rangeCells.length - 1) + clazz.append(", "); + } + clazz.append("};\n"); + } + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + clazz.append("end " + getModelicaName() + "_class;\n"); +// clazz.append(" " + name + "_class " + name + ";\n"); + return clazz.toString(); + } + + private void addRange(String key, HashSet usedCells, StringBuilder clazz) { + if(usedCells.add(key)) { + Object value = cells.get(key); + if(value instanceof String || value instanceof MutableString) { + try { + Double d = Double.parseDouble(value.toString()); + value = d; + } catch (NumberFormatException e) { + } + } + + if(value instanceof Double) { + Double d = (Double)value; + clazz.append(" parameter Real " + key + " = " + d + " /* Actual value read from init file */;\n"); + } + } + } + + private ArrayList getChildRanges(ReadGraph graph, String range) throws DatabaseException { + ArrayList ranges = new ArrayList(); + if(range.contains(":")) { + // Get cell ranges. Add cell names that have not been used individually to usedCells set + // and use those names in ranges + Variable v = graph.adapt(resource, Variable.class); + String[] parts = range.split(":"); + if(parts.length != 2 || !cells.containsKey(parts[0]) || !cells.containsKey(parts[1])) + return ranges; + Variable rangeVariable = v.getChild(graph, range); + if(rangeVariable == null) + return ranges; + String[][] rangeCells = rangeVariable.getPropertyValue(graph, SheetVariables.RANGE_CELL_NAMES); + if(rangeCells == null) + return ranges; + + for(int i = 0; i < rangeCells.length; i++) { + for(int j = 0; j < rangeCells[i].length; j++) { + ranges.add(rangeCells[i][j]); + } + } + } + return ranges; + } + + + public THashMap getCells() { + return cells; + } + + @Override + public void accept(IElementVisitorVoid v) { + + } + + /** + * Add a range that has been used for this sheet. + * + * Used ranges help to reduce code sent to Modelica. + * + * @param range range of cell/cells. (e.g. B2 or B4:B6) + */ + public void use(final String usedRange) { + usedRanges.add(usedRange); + } + + + @Override + public String getDocumentationDefinition(ReadGraph graph) throws DatabaseException { + Variable v = Variables.getVariable(graph, resource); + Collection children = v.getChildren(graph); + HashMap map = new HashMap(); + int minColumn = -1; + int maxColumn = -1; + int minRow = -1; + int maxRow = -1; + for(Variable child : children) { + Range range = SpreadsheetUtils.decodePossibleCellAbsolute(child.getName(graph)); + if(range != null) { + Variant valueVariant = child.getPropertyValue(graph, SheetVariables.CONTENT, Bindings.VARIANT); + Object valueObject = valueVariant.getValue(); + if(valueObject instanceof String) { + String value = (String) valueObject; + if(!value.isEmpty()) { + map.put(child, range); + if(minColumn < 0 || range.startColumn < minColumn) + minColumn = range.startColumn; + if(range.startColumn > maxColumn) + maxColumn = range.startColumn; + if(minRow < 0 || range.startRow < minRow) + minRow = range.startRow; + if(range.startRow > maxRow) + maxRow = range.startRow; + } + } + } + } + + int nColumns = maxColumn - minColumn + 1; + int nRows = maxRow - minRow + 1; + String[][] table = new String[nRows][nColumns]; + for(int i = 0; i < nRows; i++) + for(int j = 0; j < nColumns; j++) + table[i][j] = ""; + + for(Variable cell : map.keySet()) { + Range range = map.get(cell); + Variant valueVariant = cell.getPropertyValue(graph, SheetVariables.CONTENT, Bindings.VARIANT); + Object valueObject = valueVariant.getValue(); + table[range.startRow - minRow][range.startColumn - minColumn] = valueObject.toString(); + } + + StringBuilder result = new StringBuilder(); + result.append(""); + for(int i = -1; i < nRows; i++) { + result.append(""); + for(int j = -1; j < nColumns; j++) { + result.append(""); + } + result.append(""); + } + result.append("
"); + if(i == -1 || j == -1) + result.insert(result.length() - 2, "background-color:#D3D3D3; text-align:center;"); + if(i == -1 && j == -1) { + // Do nothing + } else if(i == -1) { + // First row, make column headers + result.append(SpreadsheetUtils.columnName(j + minColumn)); + } else if(j == -1){ + // First column, make row numbers. Rows start from 1 + result.append(i + minRow + 1); + } else { + // Actual content + result.append(table[i][j]); + } + result.append("
"); + + return result.toString(); + } + + + public Resource getResource() { + return resource; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java new file mode 100644 index 00000000..efa2f2db --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.expressions.StockExpression; +import org.simantics.sysdyn.representation.utils.SheetFormatUtils; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +/** + * Representation of a Stock variable + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.Stock) +public class Stock extends IndependentVariable { + + @RelatedElements( + value = SysdynResource.URIs.Variable_isHeadOf, + composition = true) + private ArrayList incomingConnections = new ArrayList(); + + + @RelatedElements( + value = SysdynResource.URIs.Variable_isTailOf, + composition = true) + private ArrayList outgoingConnections = new ArrayList(); + + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } + + @Override + public String getInitialEquation() { + if (Variability.getVariability(this) == Variability.CONTINUOUS) { + return super.getInitialEquation(); + } else { + return null; + } + } + + @Override + public String getDeclaration() { + + String each = ""; + // each is required when a single value is used for all dimensions e.g. Stock[30](each start = 0) + if (Variability.getVariability(this) == Variability.CONTINUOUS) { + // start parameter is not used, everything needs to be fixed=false + if(getArrayIndexes() != null && !getArrayIndexes().isEmpty()) + each = "each"; + return " " + getType() + " " + getModelicaName() + getRange() + "(" + each + " fixed=false);\n"; + } else { + // Start parameter is used. Parameter guarantees that there is only one expression. + StockExpression e = (StockExpression)getExpressions().get(0); + String initialEquation = e.getModelicaExpression(); + initialEquation = SheetFormatUtils.reformatSheetReferences(this, initialEquation); + + if(getArrayIndexes() != null && !getArrayIndexes().isEmpty()) + each = "each"; + + + return " " + + getType() + + " " + + getModelicaName() + + getRange() + + "(" + + (e.getStartValue() != null ? each : "") + + " start=" + + initialEquation + + ", " + + each + + " fixed=true);\n"; + } + } + + public String getEquation() { + return getVariableEquation(); + } + + + public ArrayList getIncomingValves() { + ArrayList valves = new ArrayList(); + for(IElement element : incomingConnections) { + if(element instanceof Flow) { + Flow flow = (Flow)element; + valves.add((Valve)flow.getTail()); + } + } + return valves; + } + + public ArrayList getOutgoingValves() { + ArrayList valves = new ArrayList(); + for(IElement element : outgoingConnections) { + if(element instanceof Flow) { + Flow flow = (Flow)element; + valves.add((Valve)flow.getHead()); + } + } + return valves; + } + + +} + + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java new file mode 100644 index 00000000..1cd9a727 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.objmap.schema.MappingSchemas; +import org.simantics.objmap.schema.SimpleSchema; +import org.simantics.sysdyn.representation.expressions.ConstantExpression; +import org.simantics.sysdyn.representation.expressions.DelayExpression; +import org.simantics.sysdyn.representation.expressions.LookupExpression; +import org.simantics.sysdyn.representation.expressions.NormalExpression; +import org.simantics.sysdyn.representation.expressions.ParameterExpression; +import org.simantics.sysdyn.representation.expressions.StockExpression; +import org.simantics.sysdyn.representation.expressions.WithLookupExpression; + +public class SysdynSchema extends SimpleSchema { + + public SysdynSchema(ReadGraph g) { + try { + addLinkType(MappingSchemas.fromAnnotations(g, Auxiliary.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Cloud.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Configuration.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Dependency.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Flow.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Stock.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Valve.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Module.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Input.class)); + addLinkType(MappingSchemas.fromAnnotations(g, ModuleType.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Model.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Enumeration.class)); + addLinkType(MappingSchemas.fromAnnotations(g, EnumerationIndex.class)); + addLinkType(MappingSchemas.fromAnnotations(g, NormalExpression.class)); + addLinkType(MappingSchemas.fromAnnotations(g, ParameterExpression.class)); + addLinkType(MappingSchemas.fromAnnotations(g, StockExpression.class)); + addLinkType(MappingSchemas.fromAnnotations(g, ConstantExpression.class)); + addLinkType(MappingSchemas.fromAnnotations(g, WithLookupExpression.class)); + addLinkType(MappingSchemas.fromAnnotations(g, LookupExpression.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Redeclaration.class)); + addLinkType(MappingSchemas.fromAnnotations(g, LibraryDummy.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Book.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Sheet.class)); + addLinkType(MappingSchemas.fromAnnotations(g, DiagramContainerDummy.class)); + addLinkType(MappingSchemas.fromAnnotations(g, DelayExpression.class)); + addLinkType(MappingSchemas.fromAnnotations(g, FunctionLibrary.class)); + addLinkType(MappingSchemas.fromAnnotations(g, SharedFunctionLibrary.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Function.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Entity.class)); + addLinkType(MappingSchemas.fromAnnotations(g, ParameterOverride.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Shadow.class)); + addLinkType(MappingSchemas.fromAnnotations(g, Loop.class)); + } catch (DatabaseException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Valve.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Valve.java new file mode 100644 index 00000000..aa3d012b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Valve.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType(SysdynResource.URIs.Valve) +public class Valve extends IndependentVariable { + @Override + public void accept(IElementVisitorVoid v) { + v.visit(this); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java new file mode 100644 index 00000000..27f33a69 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.expressionParser.Token; +import org.simantics.sysdyn.representation.utils.FormatUtils; +import org.simantics.sysdyn.representation.utils.RepresentationUtils; + +/** + * Variability of a variable in system dynamics models. + * + * @author Teemu Lempinen + * + */ +public enum Variability { + + PARAMETER("parameter"), + CONSTANT("constant"), + CONTINUOUS(""); + + + private static List timeDependentFunctions = Arrays.asList( + "pre", + "delay" + ); + + private String text; + + Variability(String text) { + this.text = text; + } + + public String getText() { + return this.text; + } + + /** + * Convert a textual representation to a Variability object. + * + * @param text Variability as text (parameter / constant / continuous) + * @return Variability or null + */ + public static Variability fromString(String text) { + if (text != null) { + for (Variability v : Variability.values()) { + if (text.equalsIgnoreCase(v.text)) { + return v; + } + } + } + return null; + } + + /** + * Check if reference in a configuration is a parameter. + * @param variable + * @param configuration Configuration + * @param reference String reference to a variable + * @return is the reference a parameter + */ + private static boolean isParameter(IndependentVariable variable, Configuration configuration, String reference, boolean allowVariables) { + // Check if references are references to sheets or enumerations. + // Sheet and Enumeration references are allowed, since sheets contain only constants / parameters + String r = reference.split("\\.")[0]; + for(IElement element : configuration.getElements()) { + if(element instanceof Module) { + Module m = (Module)element; + if(r.equals(m.getName())) { + if(!reference.contains(".")) { + // The reference contains only modules, implementation feature for the expression parser + return true; + } + Configuration moduleConfiguration = m.getType().getConfiguration(); + return isParameter(variable, moduleConfiguration, reference.substring(reference.indexOf(".") + 1), allowVariables); + } + } else if(element instanceof Book) { + for(Sheet sheet : ((Book)element).getSheets()) { + if(r.equals(sheet.getName())) { + return true; + } + } + } else if(element instanceof Enumeration) { + Enumeration e = (Enumeration)element; + if(r.equals(e.getName())) { + String[] split = reference.split("\\."); + if(split.length == 1) + return true; + if(split.length == 2) { + if(split[1].equals("size") || split[1].equals("elements")) + return true; + + for(EnumerationIndex ei : e.getEnumerationIndexes()) { + if(split[1].equals(ei.getName())) + return true; + } + } + } + } else if(allowVariables) { + // Only if variable references are allowed + if(element instanceof IndependentVariable && !(element instanceof Stock)) { + IndependentVariable v = (IndependentVariable)element; + if(r.equals(v.getName())) { + if(v.getName().equals(variable.getName())) // Reference to self. Can be used in pre(self) + return false; + else + return getVariability(v) != Variability.CONTINUOUS; + } + } else if(element instanceof Input) { + Input i = (Input)element; + if(r.equals(i.getName())) { + return i.getVariability() != null && !i.getVariability().equals(Variability.CONTINUOUS.getText()); + } + } + } + } + + // Try to find sheet in another way: this might be a module type configuration. Find the model configuration and its sheet + if(configuration.getModuleType() != null) { + Object parent = configuration.getModuleType().getParent(); + if(parent != null && parent instanceof Model) { + configuration = ((Model)parent).getModelConfiguration(); + for(IElement element : configuration.getElements()) { + if(element instanceof Book) { + for(Sheet sheet : ((Book)element).getSheets()) { + if(r.equals(sheet.getName())) { + return true; + } + } + break; + } + } + } + } + + + + // If there was no sheet for this reference name, or there was some other problem, return false + return false; + } + + + /** + * Get variability of a variable. Allows references to other parameter variables in parameter expressions + * if game experiment is not active. + * @param variable Variable + * @return Variabilty of a variable + */ + static public Variability getVariability(IndependentVariable variable) { + if(RepresentationUtils.isPartOfGameExperiment(variable) && !(variable instanceof Stock)) { + + /* + * Game experiments cannot use as many parameter variables as normal experiments. + * If a parameter variable is changed, other parameter values depending on that + * parameter value are not automatically changed. + * + * Something of a hack: + * Allow variable references, if there are not incoming dependencies to the variable. + * This enables the use of derived variables for initial values of stocks. + */ + if(variable.getIncomingDependencies() == null || variable.getIncomingDependencies().isEmpty()) + return getVariability(variable, true, null); + else + return getVariability(variable, false, null); + } else { + return getVariability(variable, true, null); + } + } + + /** + * Get variability of a variable + * @param variable Variable + * @param allowVariableReferences Allow references to other (parameter) variables in parameter expressions. + * @param configuration Configuration of the location for references. (null => variable.getParentConfiguration()) + * @return Variabilty of a variable + */ + static public Variability getVariability(IndependentVariable variable, boolean allowVariableReferences, Configuration configuration) { + if(variable == null || variable.getExpressions() == null) + return Variability.CONTINUOUS; + + ArrayList expressions = variable.getExpressions(); + + if(expressions.size() != 1) + return Variability.CONTINUOUS; // Cannot handle multiple expressions as parameters + + org.simantics.sysdyn.representation.expressions.IExpression ie = expressions.get(0); + + String expression = ie.getExpression(); + + return getVariability(variable, expression, allowVariableReferences, configuration); + } + + /** + * Get the variability of an expression in a variable. Variables may have multiple expressions. + * Allows references to other (parameter) variables in parameter expressions. + * + * @param variable Variable + * @param expression Expression + * @return Variability of the expression + */ + static public Variability getVariability(IndependentVariable variable, String expression) { + return getVariability(variable, expression, true, null); + } + + /** + * Get the variability of an expression in a variable. Variables may have multiple expressions. + * + * @param variable Variable + * @param expression Expression + * @param allowVariableReferences Allow references to other (parameter) variables in parameter expressions + * @param configuration Configuration of the location for references. (null => variable.getParentConfiguration()) + * @return Variability of the expression + */ + static public Variability getVariability(IndependentVariable variable, String expression, boolean allowVariableReferences, Configuration configuration) { + Configuration conf = configuration == null ? variable.getParentConfiguration() : configuration; + // If no variables are used in the equation, start value is used + + HashMap functions = new HashMap(); + if(conf != null) { + Model model = null; + if(conf.getModuleType() != null) { + ModuleType moduleType = conf.getModuleType(); + if (moduleType.getParent() instanceof Model) { + model = (Model) moduleType.getParent(); + } + } else { + model = conf.getModel(); + } + + if(model != null) + functions = model.getFunctions(); + } + + // First the equation is formatted and parsed + String equation = FormatUtils.formatExpressionForModelica(variable, expression, false); + ExpressionParser parser = new ExpressionParser(new StringReader(equation)); + try { + parser.expr(); + if(parser.getReferences().isEmpty() && parser.getFunctionCallReferences().isEmpty()) { + // if equation did not contain any references, start value is used + return Variability.PARAMETER; + } else { + Set references = parser.getReferences().keySet(); + + if(parser.getForIndices()!=null) { + for(Token t : parser.getForIndices().keySet()) { + references.remove(t.image); + } + } + + // Check used functions + for(String function : parser.getFunctionCallReferences().keySet()) { + if(functions.containsKey(function) && functions.get(function).hasTimeReference()) + return Variability.CONTINUOUS; + else if (timeDependentFunctions.contains(function)) { + return Variability.CONTINUOUS; + } + } + + // Go through each reference + for(String reference : references) { + if(!isParameter(variable, conf, reference, allowVariableReferences)) { + return Variability.CONTINUOUS; + } + } + + // All found variables were sheets or non-continuous + return Variability.PARAMETER; + } + } catch (ParseException e) { + } + + return Variability.CONTINUOUS; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java new file mode 100644 index 00000000..997e61db --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation; + +import java.util.ArrayList; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedListElements; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.expressions.IExpression; + +/** + * Abstract class for representing a variable in system dynamics models + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public abstract class Variable implements IElement { + + @RelatedValue(SysdynResource.URIs.Variable_type) + protected String type; + + @RelatedValue(Layer0.URIs.HasName) + protected String name; + + @RelatedElement(Layer0.URIs.PartOf) + protected Object parent; + + @RelatedListElements(SysdynResource.URIs.Variable_arrayIndexesList) + protected ArrayList arrayIndexes = new ArrayList(); + + @RelatedListElements(SysdynResource.URIs.Variable_expressionList) + protected ArrayList expressions = new ArrayList(); + + @RelatedValue(SysdynResource.URIs.Variable_variability) + protected String variability; + + @RelatedValue(SysdynResource.URIs.Variable_unit) + protected String unit; + + @RelatedValue(Layer0.URIs.HasDescription) + protected String description; + + @RelatedElement(SysdynResource.URIs.IsOutput) + protected IElement isOutput; + + /** + * Return the variability of this variable (Used in practice only with Input variables) + * @return Variability + */ + public String getVariability() { + return variability; + } + + /** + * + * @return The name of this variable + */ + public String getName() { + return this.name; + } + + /** + * Get Modelica compliant name + * @return The name of this variable with spaces (' ') replaced with + * underscore characters ('_') + */ + public String getModelicaName() { + if (this.name == null) + return null; + return this.name.replace(' ', '_'); + } + + /** + * + * @return Parent configuration of this variable (or null if something is wrong) + */ + public Configuration getParentConfiguration() { + if(parent instanceof Configuration) { + return (Configuration)parent; + } else if(parent instanceof Book) { + return (Configuration)((Book)parent).getParentConfiguration(); + } else { + return null; + } + } + + /** + * + * @return The type of this variable (Real / Boolean / ...) + */ + public String getType() { + return this.type; + } + + /** + * + * @return Array indexes for this variable + */ + public ArrayList getArrayIndexes() { + return this.arrayIndexes; + } + + /** + * + * @return Expressions of this variable + */ + public ArrayList getExpressions() { + return this.expressions; + } + + /** + * + * @return Units of this variable + */ + public String getUnit() { + return this.unit; + } + + /** + * Get description + * @return description + */ + public String getDescription() { + if(description == null) + return ""; + else + return description; + } + + public boolean isOutput() { + return !(isOutput == null); + } + + /** + * Get definition for documentation. + * + * For independent variables this is the equations + * For enumerations this is the indexes + * etc. + * @return + */ + public String getDocumentationDefinition(ReadGraph graph) throws DatabaseException { + if(isOutput()) + return "
Is output"; + else + return ""; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/annotations/BuiltinFunctions.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/annotations/BuiltinFunctions.java new file mode 100644 index 00000000..173db2c2 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/annotations/BuiltinFunctions.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; + +/** + * BuiltinFunctions -annotation returns the built-in functions function library + * @author Teemu Lempinen + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@HasFieldRuleFactory(BuiltinFunctionsFactory.class) +public @interface BuiltinFunctions { +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/annotations/BuiltinFunctionsAccessor.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/annotations/BuiltinFunctionsAccessor.java new file mode 100644 index 00000000..c010706c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/annotations/BuiltinFunctionsAccessor.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ + +package org.simantics.sysdyn.representation.annotations; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.objmap.MappingException; +import org.simantics.objmap.rules.domain.IDomainAccessor; +import org.simantics.sysdyn.SysdynResource; + +/** + * Accesses the built-in functions in Sysdyn ontology + * + * @author Teemu Lempinen + */ +public class BuiltinFunctionsAccessor implements IDomainAccessor { + + + public BuiltinFunctionsAccessor() { + } + + @Override + public Resource get(ReadGraph graph, Resource element) throws MappingException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + Resource builtinFunctions = null; + try { + Resource sysdyn = graph.getResource("http://www.simantics.org/Sysdyn-1.1"); + builtinFunctions = graph.syncRequest(new PossibleObjectWithType(sysdyn, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary)); + } catch (DatabaseException e) { + throw new MappingException(e); + } + return builtinFunctions; + } + + @Override + public boolean set(WriteGraph g, Resource element, Resource value) + throws MappingException { + // Built-in functions should not be set programmatically + return true; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/annotations/BuiltinFunctionsFactory.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/annotations/BuiltinFunctionsFactory.java new file mode 100644 index 00000000..f6800db4 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/annotations/BuiltinFunctionsFactory.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.annotations; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.exception.ValidationException; +import org.simantics.objmap.IMappingRule; +import org.simantics.objmap.rules.MappedElementRule; +import org.simantics.objmap.rules.factory.IFieldRuleFactory; +import org.simantics.objmap.rules.range.FieldAccessor; + +public class BuiltinFunctionsFactory implements IFieldRuleFactory { + + @Override + public IMappingRule create(ReadGraph g, Annotation _annotation, Field field) throws ResourceNotFoundException, ValidationException, ServiceException { + return new MappedElementRule( + new BuiltinFunctionsAccessor(), + new FieldAccessor(field) + ); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ConstantExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ConstantExpression.java new file mode 100644 index 00000000..3b4036fe --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ConstantExpression.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.utils.FormatUtils; + +/** + * Represents a constant expression + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.ConstantExpression) +public class ConstantExpression extends Expression { + + @RelatedValue(SysdynResource.URIs.Expression_equation) + private String equation; + + @Override + public String getExpression() { + return equation; + } + + @Override + public String getModelicaExpression() { + return FormatUtils.replaceWhitespace(equation); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java new file mode 100644 index 00000000..6409704b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java @@ -0,0 +1,284 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import org.simantics.db.ReadGraph; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Variability; +import org.simantics.sysdyn.representation.utils.FormatUtils; +import org.simantics.sysdyn.representation.utils.IndexUtils; +import org.simantics.sysdyn.representation.utils.UnitUtils; + +/** + * Representation of a delay expression. The order of the + * delay can be 1-n. + * + * Delay with n = 3: + * + * DELAY3=LV3/DL + * LV3=INTEG(RT2-DELAY3,DL*input) + * RT2=LV2/DL + * LV2=INTEG(RT1-RT2,LV3) + * RT1=LV1/DL + * LV1=INTEG(input-RT1,LV3) + * DL=delay time/3 + * + * DELAY3I=LV3/DL + * LV3=INTEG(RT2-DELAY3I,initial value*DL) + * RT2=LV2/DL + * LV2=INTEG(RT1-RT2,LV3) + * RT1=LV1/DL + * LV1=INTEG(input-RT1,LV3) + * DL=delay time/3 + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.DelayExpression) +public class DelayExpression extends Expression { + + @RelatedValue(SysdynResource.URIs.DelayExpression_initialValue) + private String initialValue; + + @RelatedValue(SysdynResource.URIs.DelayExpression_delayTime) + private String delayTime; + + @RelatedValue(SysdynResource.URIs.DelayExpression_order) + private Integer order; + + @RelatedValue(SysdynResource.URIs.DelayExpression_expression) + private String equation; + + @Override + public String getDeclarationAddition() { + String delayTime = FormatUtils.replaceWhitespace(this.delayTime); + delayTime = FormatUtils.formatExpressionForModelica(parent, delayTime); + String initialValue = FormatUtils.replaceWhitespace(this.initialValue); + initialValue = FormatUtils.formatExpressionForModelica(parent, initialValue); + Variability delayTimeVariability = Variability.getVariability((IndependentVariable)parent, delayTime); + Variability initialVariability = Variability.CONTINUOUS; + if(initialValue != null && initialValue.length() > 0) { + /* + * By default, initial value variability is continuous. + * If initial value has been set, it can be some other. + */ + initialVariability = Variability.getVariability(parent, initialValue); + } + + + StringBuilder declaration = new StringBuilder(); + + String range = parent.getRange(); + + // Delay declaration + declaration.append(" " + parent.getModelicaName() + "_delayClass " + parent.getModelicaName() + "_delayClass_instance"); + + // Change enumeration sizes from the delay class. Supports overridden enumerations in modules. + if(range.length() > 0 || !initialVariability.equals(Variability.CONTINUOUS) || !delayTimeVariability.equals(Variability.CONTINUOUS)) { + declaration.append("("); + + boolean started = false; + if(range.length() > 0) { + started = true; + String[] ranges = range.substring(1, range.length() - 1).split(","); + for(int i = 0; i < ranges.length; i++ ) { + String r = ranges[i]; + declaration.append(r.replace(".size", "size") + " = " + r); + if(i < ranges.length - 1) { + declaration.append(", "); + } + } + } + + // If initial value is not continuous, it is set in the module declaration + if(!initialVariability.equals(Variability.CONTINUOUS)) { + if(started) + declaration.append(", "); + started = true; + declaration.append("initialValue = " + initialValue); + } + + // If delay time is not continuous, it is set in the module declaration + if(!delayTimeVariability.equals(Variability.CONTINUOUS)) { + if(started) + declaration.append(", "); + declaration.append("delayTime = " + delayTime); + } + + declaration.append(")"); + } + declaration.append(";\n"); + + // Write the delay class + declaration.append(getDelayClass(range, order)); + return declaration.toString(); + } + + /** + * Creates a class that is used to implement the delay. Class contains + * a basic delay structure with "stocks and flows". The number of + * stocks and flows is determined by the order of the delay + * + * @param variable The variable for which the delay is created + * @param range Array range + * @param n Order of the delay + * @return + */ + private String getDelayClass(String range, int n) { + StringBuilder sb = new StringBuilder(); + + sb.append("class " + parent.getModelicaName() + "_delayClass\n"); + + // Enumeration sizes as parameters. Sizes correspond the enumeration sizes of variable + if(range.length() > 0) { + range = range.replaceAll(".size", "size"); + for(String r : range.substring(1, range.length() - 1).split(",")) { + sb.append("\t parameter Integer " + r + ";\n"); + } + } + + String delayTime = FormatUtils.replaceWhitespace(this.delayTime); + String dt = FormatUtils.formatExpressionForModelica(parent,delayTime); + Variability delayTimeVariability = Variability.getVariability(parent, dt); + if(!delayTimeVariability.equals(Variability.CONTINUOUS)) { + // Auxiliary variable + sb.append("\t" + delayTimeVariability.getText() + " Real" + range + " DL = delayTime/" + n + ";\n"); + // Delay time + sb.append("\t" + delayTimeVariability.getText() + " Real" + range + " delayTime;\n"); + } else { + // Continuous auxiliary variable + sb.append("\tReal" + range + " DL;\n"); + // Continuous delay time + sb.append("\tReal" + range + " delayTime;\n"); + } + + + // Get initial value variability + Variability initialValueVariability = Variability.CONTINUOUS; + String initEquation = FormatUtils.replaceWhitespace(this.initialValue); + initEquation = FormatUtils.formatExpressionForModelica(parent, initEquation); + if(initialValue != null && initialValue.length() > 0) { + initialValueVariability = Variability.getVariability(parent, initEquation); + } + + // Declare initial value (continuous or other) + String ivv = !initialValueVariability.equals(Variability.CONTINUOUS) ? initialValueVariability.getText() + " " : ""; + sb.append("\t" + ivv + "Real" + range + " initialValue;\n"); + + // First valve + sb.append("\tReal" + range + " delay0;\n"); + + // Stocks and valves. Valves are the delayed values of the variable + for(int i = 1; i <= n; i++) { + if(initialValueVariability.equals(Variability.CONTINUOUS) || delayTimeVariability.equals(Variability.CONTINUOUS)) + // Continuous initial value or delay time + sb.append("\tReal" + range + " LV" + i + "(" + (range.length() > 0 ? "each " : "") + "fixed=false);\n"); + else + // initial value and delay time are not continuous + sb.append("\tReal" + range + " LV" + i + + "(" + (range.length() > 0 ? "each " : "") + "fixed=true, start=initialValue " + (range.isEmpty() ? "*" : ".*") + " DL);\n"); + sb.append("\tReal" + range + " delay" + i + ";\n"); + } + + // If initial value or delay time are continuous, use initial equation block + if(initialValueVariability.equals(Variability.CONTINUOUS) || delayTimeVariability.equals(Variability.CONTINUOUS)) { + sb.append("initial equation\n"); + + // Each stock gets the same initial value + for(int i = 1; i <= n; i++) + sb.append("\tLV" + i +" = DL " + (range.isEmpty() ? "*" : ".*") + " initialValue;\n"); + } + + // Equation block + sb.append("equation\n"); + + if(delayTimeVariability.equals(Variability.CONTINUOUS)) + sb.append("\tDL = delayTime/" + n + ";\n"); + + // Valves and stocks + for(int i = 1; i <= n; i++) { + sb.append("\tder(LV" + i + ") = - delay" + i + " + delay" + (i - 1) + ";\n"); + sb.append("\tdelay" + i + " = LV" + i + " " + (range.isEmpty() ? "/" : "./") + "DL;\n"); + } + + sb.append("end " + parent.getModelicaName() + "_delayClass;\n"); + return sb.toString(); + } + + @Override + public String getEquation() { + StringBuilder sb = new StringBuilder(); + + String equation = FormatUtils.replaceWhitespace(this.equation); + equation = FormatUtils.formatExpressionForModelica(parent, equation); + String delayTime = FormatUtils.replaceWhitespace(this.delayTime); + delayTime = FormatUtils.formatExpressionForModelica(parent, delayTime); + String initialValue = FormatUtils.replaceWhitespace(this.initialValue); + initialValue = FormatUtils.formatExpressionForModelica(parent, initialValue); + + // First "valve" in the delay + sb.append(" " + parent.getModelicaName() + "_delayClass_instance.delay0 = " + equation + ";\n"); + + // Delay time (if continuous) + Variability delayTimeVariability = Variability.getVariability(parent, delayTime); + if(delayTimeVariability.equals(Variability.CONTINUOUS)) { + sb.append(" " + parent.getModelicaName() + "_delayClass_instance.delayTime = " + delayTime + ";\n"); + } + + // Initial value + if(initialValue == null || initialValue.length() == 0) { + // No initial value set, use delay0 (the first "valve") + sb.append(" " + parent.getModelicaName() + "_delayClass_instance.initialValue = " + parent.getModelicaName() + "_delayClass_instance.delay0;\n"); + } else { + // Continuous initial value + Variability initialVariability = Variability.getVariability(parent, initialValue); + if(initialVariability.equals(Variability.CONTINUOUS)) { + sb.append(" " + parent.getModelicaName() + "_delayClass_instance.initialValue = " + initialValue + ";\n"); + } + } + + // The value of the actual variable + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); + sb.append(" " + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = " + parent.getModelicaName() + "_delayClass_instance.delay" + order + ";\n"); + return sb.toString(); + } + + @Override + public String getExpression() { + return "This + is + not + a + parameter + at + any + time"; + } + + @Override + public String getModelicaExpression() { + return getExpression(); + } + + @Override + public String validateUnits(ReadGraph graph, SysdynModel model) { + if(parent.getUnit() == null) + return "Unit not defined for " + parent.getName(); + + String result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), parent.getUnit(), equation); + if(result == null) + result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), parent.getUnit(), initialValue); + if(result == null) + result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), UnitUtils.getTimeUnit(graph, model), delayTime); + + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java new file mode 100644 index 00000000..7463bfcc --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.layer0.Layer0; +import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.utils.UnitUtils; + +/** + * Abstract class for any expression + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public abstract class Expression implements IExpression { + + @RelatedValue(SysdynResource.URIs.Expression_arrayRange) + private String range; + + @RelatedElement(Layer0.URIs.PartOf) + protected IndependentVariable parent; + + @Override + public String getEquation() { + return null; + } + + @Override + public String getInitialEquation() { + return null; + } + + @Override + public String getDeclarationAddition() { + return null; + } + + @Override + public String getExpression() { + return null; + } + + /** + * Get Modelica compliant expression + * @return The expression with spaces (' ') replaced with + * underscore characters ('_') + */ + public String getModelicaExpression() { + return null; + } + + @Override + public String getArrayRange() { + if(range == null) + return ""; + else + return range; + } + + @Override + public String validateUnits() { + return validateUnits(null, null); + } + + @Override + public String validateUnits(ReadGraph graph, SysdynModel model) { + return UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), parent.getUnit(), getExpression()); + } + + @Override + public IndependentVariable getParent() { + return parent; + } + + @Override + public String getDocumentationExpression(ReadGraph graph) throws DatabaseException { + return getEquation(); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java new file mode 100644 index 00000000..94a119ce --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.representation.IndependentVariable; + + +/** + * Interface for all expressions in System Dynamics models + * + * @author Teemu Lempinen + * + */ +public interface IExpression { + + /** + * Get any possible additions to variable declaration. + * + * @param variable Declared independent variable + * @return additions or null + */ + String getDeclarationAddition(); + + /** + * Initial value for this variable and expression + * @param variable IndependentVariable + * @return initial value or null + */ + String getInitialEquation(); + + /** + * Get the actual equation of this expression + * @param variable IndependentVariable + * @return equation or null + */ + String getEquation(); + + /** + * Get the range of this expression + * @return Range or null if not multidimensional + */ + String getArrayRange(); + + /** + * Get the plain (possibly unformatted) expression from this expression. (type variable = EXPRESSION ;\n) + * @param variable + * @return + */ + String getExpression(); + + + /** + * Match the units of this expression to units of its variable + * @return null if match, Error message otherwise + */ + String validateUnits(); + + /** + * Match the units of this expression to units of its variable. + * + * Requests units of referred variables for request listening + * @param graph ReadGraph + * @param model SysdynModel (with mapping) + * @return null if match, ERror message otherwise + */ + String validateUnits(ReadGraph graph, SysdynModel model); + + /** + * Get the owner of this expression + * @return owner of this expression + */ + IndependentVariable getParent(); + + + /** + * Get the representation of this expression to web documentation + * @return + */ + String getDocumentationExpression(ReadGraph graph) throws DatabaseException; +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/LookupExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/LookupExpression.java new file mode 100644 index 00000000..5d5b4d89 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/LookupExpression.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.sysdyn.SysdynResource; + +@GraphType(SysdynResource.URIs.LookupExpression) +public class LookupExpression extends Expression { + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java new file mode 100644 index 00000000..696854ea --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.utils.FormatUtils; +import org.simantics.sysdyn.representation.utils.IndexUtils; + +/** + * Representation of a normal (auxiliary) expression + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.NormalExpression) +public class NormalExpression extends Expression { + + @RelatedValue(SysdynResource.URIs.Expression_equation) + private String equation; + + @Override + public String getExpression() { + return equation; + } + + @Override + public String getModelicaExpression() { + return FormatUtils.replaceWhitespace(getExpression()); + } + + @Override + public String getEquation() { + String equation = FormatUtils.replaceWhitespace(this.equation); + equation = FormatUtils.formatExpressionForModelica(parent, equation); + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); + return " " + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n"; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java new file mode 100644 index 00000000..6723be47 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.utils.FormatUtils; +import org.simantics.sysdyn.representation.utils.IndexUtils; + +/** + * Representation of a parameter expression + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.ParameterExpression) +public class ParameterExpression extends Expression { + + @RelatedValue(SysdynResource.URIs.Expression_equation) + private String equation; + + @Override + public String getExpression() { + return equation + " /* Actual value read from init file */"; + } + + @Override + public String getModelicaExpression() { + String equation = FormatUtils.replaceWhitespace(this.equation); + return equation + " /* Actual value read from init file */"; + } + + @Override + public String getDeclarationAddition() { + return ""; + } + + + /** + * Used when the expression is a part of an array variable. Then it is like a normal auxiliary. + */ + @Override + public String getEquation() { + String equation = FormatUtils.replaceWhitespace(this.equation); + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); + return " " + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n"; + }; + + public Double getValue() { + try { + return Double.parseDouble(equation); + } catch(NumberFormatException e) { + return null; + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java new file mode 100644 index 00000000..95a3a5bd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Set; + +import org.simantics.db.ReadGraph; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.representation.Book; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Sheet; +import org.simantics.sysdyn.representation.Stock; +import org.simantics.sysdyn.representation.Valve; +import org.simantics.sysdyn.representation.utils.FormatUtils; +import org.simantics.sysdyn.representation.utils.IndexUtils; +import org.simantics.sysdyn.representation.utils.UnitUtils; + +/** + * Class representing a stock expression in a variable + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.StockExpression) +public class StockExpression extends Expression { + + @RelatedValue(SysdynResource.URIs.StockExpression_initialEquation) + private String initialEquation; + + @RelatedValue(SysdynResource.URIs.StockExpression_integralEquation) + private String integralEquation; + + @Override + public String getExpression() { + return initialEquation; + } + + @Override + public String getModelicaExpression() { + return FormatUtils.replaceWhitespace(initialEquation); + } + + @Override + public String getEquation() { + return getEquation(true); + } + + private String getEquation(boolean modelicaEquation) { + + // Build range e.g. Stock[2,3] + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); + + // Stock equation is always der(Stock) + StringBuilder b = new StringBuilder(); + b.append(" der(") + .append(modelicaEquation ? parent.getModelicaName() : parent.getName() + range) + .append(") = "); + + if (integralEquation != null) { + if (modelicaEquation) { + String equation = FormatUtils.replaceWhitespace(this.integralEquation); + equation = FormatUtils.formatExpressionForModelica(parent, equation); + b.append(equation).append(";\n"); + } else { + b.append(integralEquation).append(";\n"); + } + } else { + // Stock equation is formed automatically using incoming and outgoing flows (actually the nearest valves in those flows) + ArrayList incoming = ((Stock)parent).getIncomingValves(); + ArrayList outgoing = ((Stock)parent).getOutgoingValves(); + if(incoming.isEmpty() && outgoing.isEmpty()) { + // No connections, add 0 for each array index if any. + ArrayList enumerations = parent.getArrayIndexes(); + if(enumerations == null || enumerations.isEmpty()) { + b.append(" 0.0"); + } else { + b.append(" zeros("); + for(int i = 0; i < enumerations.size(); i++) { + b.append(modelicaEquation ? enumerations.get(i).getModelicaName() : enumerations.get(i).getName() + ".size"); + if(i != enumerations.size() - 1) + b.append(", "); + } + b.append(")"); + } + + } else { + // incoming valves add and outgoing valves reduce the stock + for(Valve valve : outgoing) + b.append("\n - ").append(modelicaEquation ? valve.getModelicaName() : valve.getName() + range); + for(Valve valve : incoming) + b.append("\n + ").append(modelicaEquation ? valve.getModelicaName() : valve.getName() + range); + } + b.append(";\n"); + } + return b.toString(); + } + + /** + * Check whether to use fixed=true and start=... in Modelica code + * @return + */ + private boolean useStartValue() { + // If no variables are used in the equation, start value is used + + // First the equation is formatted and parsed + String equation = FormatUtils.formatExpressionForModelica(parent, initialEquation); + ExpressionParser parser = new ExpressionParser(new StringReader(equation)); + try { + parser.expr(); + if(parser.getReferences().isEmpty()) { + // if equation did not contain any references, start value is used + return true; + } else { + // Check if references are references to sheets. + // Sheet references are allowed, since sheets contain only constants + boolean found = false; + Set references = parser.getReferences().keySet(); + + // Go through each reference + for(String reference : references) { + // We only need the first element to know that it is a Sheet (SheetName.CellOrRange) + reference = reference.split("\\.")[0]; + found = false; + for(IElement element : parent.getParentConfiguration().getElements()) { + if(element instanceof Book) { + for(Sheet sheet : ((Book)element).getSheets()) { + if(reference.equals(sheet.getName())) { + found = true; + break; + } + } + } + if(found) + break; + } + + // If there was no sheet for this reference name, return false + if(!found) + return false; + } + } + } catch (ParseException e) { + e.printStackTrace(); + } + return true; + } + + @Override + public String getInitialEquation() { + String initialEquation = FormatUtils.replaceWhitespace(this.initialEquation); + // if start value is used, no initial equation is returned + if(useStartValue()) + return null; + // format the initial equation for modelica execution + String equation = FormatUtils.formatExpressionForModelica(parent, initialEquation, false); + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); + if(range == null) + range = ""; + return " " + parent.getModelicaName() + range + " = " + equation + ";\n"; + } + + + /** + * Return Double representation of the initial equation for given variable + * + * @param variable + * @return Double representing the initial equation or null if initial equation is not a double + */ + public Double getStartValue() { + Double value = null; + ArrayList expressions = parent.getExpressions(); + if(expressions.size() == 1) { + IExpression e = expressions.get(0); + if(e.getInitialEquation() == null) { + try { + value = Double.parseDouble(initialEquation); + } catch(NumberFormatException e1) { + + } + } + } + return value; + } + + + @Override + public String validateUnits(ReadGraph graph, SysdynModel model) { + String result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), parent.getUnit(), initialEquation); + if(result == null) { + String integralEquation = getEquation(false); + if(integralEquation.contains("=")) + result = UnitUtils.matchUnits( + graph, + model, + parent.getParentConfiguration(), + parent.getUnit(), + "(" + integralEquation.substring(integralEquation.indexOf("=") + 1, integralEquation.lastIndexOf(";")) +") * time"); + } + + return result; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java new file mode 100644 index 00000000..27c09439 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.io.StringWriter; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.data.xy.DefaultXYDataset; +import org.simantics.db.ReadGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.jfreechart.chart.ChartUtils; +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.spreadsheet.Range; +import org.simantics.spreadsheet.SheetVariables; +import org.simantics.spreadsheet.util.SpreadsheetUtils; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Model; +import org.simantics.sysdyn.representation.Sheet; +import org.simantics.sysdyn.representation.utils.FormatUtils; +import org.simantics.sysdyn.representation.utils.IndexUtils; +import org.simantics.sysdyn.representation.utils.SheetFormatUtils; +import org.simantics.sysdyn.representation.utils.UnitUtils; + +/** + * Representation of a withlookup expression + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +@GraphType(SysdynResource.URIs.WithLookupExpression) +public class WithLookupExpression extends Expression { + + @RelatedValue(SysdynResource.URIs.WithLookupExpression_lookup) + private String lookupTable; + @RelatedValue(SysdynResource.URIs.WithLookupExpression_expression) + private String equation; + + @Override + public String getEquation() { + String equation = FormatUtils.replaceWhitespace(this.equation); + equation = FormatUtils.formatExpressionForModelica(parent, equation); + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); + + return + " " + parent.getModelicaName() + (range.equals("[:]") ? "" : range) + " = interpolate(" + equation + ", " + SheetFormatUtils.reformatSheetReferences(parent, lookupTable) + ");\n"; + } + + @Override + public String getModelicaExpression() { + return "interpolate(" + FormatUtils.replaceWhitespace(equation) + ", " + lookupTable + ")"; + } + + @Override + public String getExpression() { + return "interpolate(" + equation + ", " + lookupTable + ")"; + } + + @Override + public String validateUnits(ReadGraph graph, SysdynModel model) { + if(parent.getUnit() == null) + return "Unit not defined for " + parent.getName(); + + String result = UnitUtils.expressionUnitsValid(graph, model, parent.getParentConfiguration(), equation); + if(result == null) { + result = UnitUtils.matchUnits(graph, model, parent.getParentConfiguration(), parent.getUnit(), lookupTable); + } + + return result; + } + + @Override + public String getDocumentationExpression(ReadGraph graph) throws DatabaseException { + String expression = super.getDocumentationExpression(graph); + + // assume lookup table has format: {{1,2},{3,4}} + String table = lookupTable; + + Sheet sheet = null; + if(table.matches("[a-zA-Z0-9]*\\([a-zA-Z0-9:]*\\)")) { + // try if it is a sheet reference + String name = table.substring(0, table.indexOf("(")); + String range = table.substring(table.indexOf("(") + 1, table.indexOf(")")); + IndependentVariable independentVariable = getParent(); + Configuration conf = independentVariable.getParentConfiguration(); + Model model = conf.getModel(); + + if(model == null) { + Object parent = conf.getModuleType().getParent(); + if(parent instanceof Model) { + model = (Model)parent; + } + } + + if(model != null) { + for(IElement e : model.getModelConfiguration().getElements()) { + if(e instanceof Sheet && name.equals(((Sheet)e).getName())) { + sheet = (Sheet)e; + Variable v = Variables.getVariable(graph, sheet.getResource()); + Variable rangeVariable = v.getChild(graph, range); + Range r = SpreadsheetUtils.decodeRange(range); + if(r.endColumn - r.startColumn == 1) { + String[][] rangeCells = rangeVariable.getPropertyValue(graph, SheetVariables.RANGE_CELL_NAMES); + StringBuilder sb = new StringBuilder(); + boolean firstRow = true; + for(int i = 0; i < rangeCells.length; i++) { + if(!firstRow) + sb.append(","); + firstRow = false; + + boolean firstColumn = true; + for(int j = 0; j < rangeCells[i].length; j++) { + if(!firstColumn) + sb.append(","); + firstColumn = false; + sb.append(sheet.getCells().get(rangeCells[i][j])); + } + } + table = sb.toString(); + + } + break; + } + } + } + + if(sheet != null) { + + } + } + + table = table.replace("{", ""); + table = table.replace("}", ""); + String[] split = table.split(","); + double[] x = new double[split.length / 2]; + double[] y = new double[split.length / 2]; + + try { + for(int i = 0; i < split.length / 2; i++) { + x[i] = Double.parseDouble(split[i*2]); + y[i] = Double.parseDouble(split[i*2+1]); + } + + DefaultXYDataset dataset = new DefaultXYDataset(); + dataset.addSeries("lookup", new double[][] {y, x}); + JFreeChart chart = ChartFactory.createXYLineChart( + "", // chart title + "", // domain axis label + "", // range axis label + dataset, // data + PlotOrientation.HORIZONTAL, // Orientation + false, // include legend + false, // tooltips + false // urls + ); + + StringWriter writer = new StringWriter(); + ChartUtils.writeSVG(chart, new Rectangle2D.Double(0, 0, 200, 100), writer); + writer.flush(); + String svg = writer.toString(); + writer.close(); + svg = svg.substring(svg.indexOf("" + svg + ""; + } catch (NumberFormatException e) { + + } catch (IOException e) { + } + + return expression; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/FormatUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/FormatUtils.java new file mode 100644 index 00000000..d05d9546 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/FormatUtils.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.utils; + +import java.io.StringReader; +import java.util.ArrayList; + +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Variability; +import org.simantics.sysdyn.representation.Variable; + +public class FormatUtils { + + /** + * Formats expressions for OpenModelica. Indexes are changed into numbers. + * @param variable Variable + * @param expression Expression + * @return Formatted expression + */ + public static String formatExpressionForModelica(Variable variable, String expression) { + return formatExpressionForModelica(variable, expression, true); + } + + /** + * Formats expressions for OpenModelica. Indexes are changed into numbers. + * + * @param variable Variable + * @param expression Expression + * @param gameAdditions Add game hacks? + * @return Formatted expression + */ + public static String formatExpressionForModelica(Variable variable, String expression, boolean gameAdditions) { + String modified = expression; + if(gameAdditions) + // FIXME: A hack. This is needed for fmu simulation to notice changes in parameters. + // OpenModelica supports FMI 1.0, which does not support tunable variables. Problem should be fixed with FMI 2.0 + modified = addGameExperimentAdditions(variable, modified); + modified = IndexUtils.equationRangesToIndexes(variable, modified); + modified = SheetFormatUtils.reformatSheetReferences(variable, modified); + return modified; + } + + + /** + * Adds hacks for variables to work with game experiments. + *

+ * The hack is as follows. If the expression contains a reference to a parameter, add the following around the + * expression: + *

+ * if initial() or parameter < 0 or parameter >= 0 then EXPRESSION else pre(variable) + *

+ * The hack is added only if there is a reference to a parameter. + * + * @param variable Variable + * @param expression Expression + * @return Expression with added hacks for game experiments + */ + private static String addGameExperimentAdditions(Variable variable, String expression) { + if(variable == null || !(variable instanceof IndependentVariable)) + return expression; + if(!RepresentationUtils.isPartOfGameExperiment(variable)) + return expression; + + if(Variability.getVariability((IndependentVariable)variable).equals(Variability.CONTINUOUS)) { + Variable reference = RepresentationUtils.getFirstGameVariableReference(variable, expression); + if(reference != null) { + String condition; + + boolean array = reference.getArrayIndexes() != null && + reference.getArrayIndexes() != null && + !reference.getArrayIndexes().isEmpty(); + + String refName = reference.getModelicaName(); + if(reference.getType().equals("Boolean")) { + condition= "if initial() or " + refName + " or not " + + refName + " then ("; + } else { + if(array) + refName = "sum(" + refName + ")"; + condition= "if " + refName + " < 0 or " + + refName + " >= 0 then ("; + } + + String conditionEnd = ") else " + getZeros(variable); + expression = condition + expression + conditionEnd; + } + + } + return expression; + } + + private static String getZeros(Variable variable) { + ArrayList enumerations = variable.getArrayIndexes(); + if(enumerations == null || enumerations.size() == 0) + return "0"; + else { + StringBuilder sb = new StringBuilder(); + sb.append("zeros("); + boolean first = true; + for(Enumeration e : enumerations) { + if(!first) + sb.append(", "); + first = false; + sb.append(e.getModelicaName() + ".size"); + } + sb.append(")"); + return sb.toString(); + } + } + + /** + * Replaces each whitespace sequence with a single underscore character ('_'). + * @param app String of which whitespace are replaced + * @return a new String with whitespace replaced + */ + public static String replaceWhitespace(String app) { + String equation = app; + //String equation = FormatUtils.formatExpressionForModelica(variable, app, false); + ExpressionParser parser = new ExpressionParser(new StringReader(equation)); + String modifiedEquation = new String(equation); + + try { + parser.expr(); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + // Collect all references + ArrayList allReferences = new ArrayList(); + allReferences.addAll(parser.getReferences().keySet()); + allReferences.addAll(parser.getFunctionCallReferences().keySet()); + allReferences.addAll(parser.getEnumerationReferences().keySet()); + + // Replace whitespace sequences with underscore characters + for (String reference : allReferences) { + String regex = reference.replaceAll(" ", "(_|\\\\s+)"); + String replacement = reference.replaceAll(" ", "_"); + modifiedEquation = modifiedEquation.replaceAll(regex, replacement); + } + + return modifiedEquation; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/IndexUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/IndexUtils.java new file mode 100644 index 00000000..cc79fda7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/IndexUtils.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.utils; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.StringTokenizer; + +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ExpressionParser.ForRange; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.expressionParser.Token; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.EnumerationIndex; +import org.simantics.sysdyn.representation.Variable; + +public class IndexUtils { + + public static int indexOf(Enumeration enumeration, String index) { + int result = -1; + ArrayList indexes = enumeration.getEnumerationIndexes(); + for(int i = 0; i < indexes.size(); i++) { + if(indexes.get(i).getName().equals(index)) { + result = i +1; + break; + } + } + return result; + } + + + public static String rangeToIndexes(Variable variable, String range) { + if(variable == null) + return range; + StringBuilder sb = new StringBuilder(); + if(variable.getArrayIndexes() == null || range == null) + return ""; + ArrayList enumerations = variable.getArrayIndexes(); + StringTokenizer st = new StringTokenizer(range, "[]:,", true); + int index = 0; + while(st.hasMoreTokens()) { + String rangeToken = st.nextToken().trim(); + if(rangeToken.matches("[\\[\\]:]")) { + sb.append(rangeToken); + } else if (rangeToken.equals(",")) { + sb.append(rangeToken); + index++; + } else if(index < enumerations.size()) { + if(rangeToken.equals(enumerations.get(index).getName())) { + sb.append(":"); + } else { + int i = indexOf(enumerations.get(index), rangeToken); + if(i >= 0) + sb.append(i); + else + sb.append(rangeToken); + } + } else { + sb.append(rangeToken); + } + } + return sb.toString(); + } + + private static String fixForRangeEnumerations(Variable variable, String equation) { + ExpressionParser parser = new ExpressionParser(new StringReader(equation)); + try { + parser.expr(); + for(ForRange forRange : parser.getForRanges()) { + // Concat the tokens that form the range, this is + // necessary for names that have whitespace. + String rangeString = new String(forRange.start.image); + Token temp = forRange.start; + while (!temp.equals(forRange.end)) { + temp = temp.next; + rangeString += " " + temp.image; + } + Variable v = RepresentationUtils.getVariable(variable.getParentConfiguration(), rangeString); + if(v instanceof Enumeration) { + equation = equation.replaceAll("in[\\s]*" + rangeString + "($|[^\\.])", + "in " + rangeString.replaceAll(" ", "_") + ".elements$1"); + } + } + } catch (ParseException e) { + e.printStackTrace(); + } + return equation; + } + + public static String equationRangesToIndexes(Variable variable, String equation) { + if(equation == null) return equation; + + if(equation.contains("[")) { + StringBuilder result = new StringBuilder(); + String delimiters = "+-*/(){}[],. "; + StringTokenizer st = new StringTokenizer(equation, delimiters, true); + String prevToken = st.nextToken(); + result.append(prevToken); + while (st.hasMoreTokens()) { + String nextToken = st.nextToken(); + if (nextToken.equals("[")) { + StringBuilder range = new StringBuilder(); + range.append("["); + String rangeToken = st.nextToken(); + while(!rangeToken.equals("]")) { + range.append(rangeToken); + rangeToken = st.nextToken(); + } + range.append("]"); + + Variable prevVar = RepresentationUtils.getVariable(variable.getParentConfiguration(), prevToken.trim()); + result.append(rangeToIndexes(prevVar, range.toString())); + } else { + result.append(nextToken); + } + prevToken = nextToken; + } + equation = fixForRangeEnumerations(variable, result.toString()); + } else if(equation.contains("{")){ + // Cases where there are {something for i in Enum} without [] brackets + equation = fixForRangeEnumerations(variable, equation); + } + + return equation; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/RepresentationUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/RepresentationUtils.java new file mode 100644 index 00000000..09a9a202 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/RepresentationUtils.java @@ -0,0 +1,197 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.utils; + +import java.io.StringReader; +import java.util.Set; + +import org.simantics.Simantics; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.manager.SysdynGameExperiment; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.Stock; +import org.simantics.sysdyn.representation.Variability; +import org.simantics.sysdyn.representation.Variable; + +public class RepresentationUtils { + + + /** + * Returns true, if there is an active experiment and the active experiment + * is a game experiment + * @return true, if there is an active experiment and the active experiment + * is a game experiment + */ + public static boolean isGameExperimentActive() { + // Find active experiment + IProject project = Simantics.peekProject(); + if (project == null) + return false; + + IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + + IExperiment active = manager.getActiveExperiment(); + if (active instanceof SysdynGameExperiment) + return true; + else + return false; + } + + /** + * Find out if a variable is part of a game configuration. (This means that the variable is a + * part of a game experiment) + * @param variable + * @return + */ + public static boolean isPartOfGameExperiment(Variable variable) { + Configuration conf = variable.getParentConfiguration(); + if(conf != null) + return conf.isGameConfiguration(); + else + return false; + } + + /** + * Find out if a module is part of a game configuration. (This means that the module is a + * part of a game experiment) + * @param variable + * @return + */ + public static boolean isPartOfGameExperiment(Module module) { + Configuration conf = module.getParentConfiguration(); + if(conf != null) + return conf.isGameConfiguration(); + else + return false; + } + + + /** + * Retrieves the first reference to a game variable (parameter variable) in the given + * expression or null if there is no reference to a game variable. + *

+ * Current requirements for a game variable: Variable contains only one parameter expression. + * @param variable Variable that has the expression + * @param expression Expression + * @return The name of the first referred game variable or null if there is no such reference + */ + public static Variable getFirstGameVariableReference(Variable variable, String expression) { + String equation = FormatUtils.formatExpressionForModelica(variable, expression, false); + ExpressionParser parser = new ExpressionParser(new StringReader(equation)); + Variable result = null; + try { + parser.expr(); + if(!parser.getReferences().isEmpty()) { + Set references = parser.getReferences().keySet(); + // Go through each reference + for(String reference : references) { + if((result = getGameVariableReference(variable, variable.getParentConfiguration(), reference)) != null) { + break; + } + } + } + } catch (ParseException e) { + } + return result; + } + + /** + * Test if a given reference is a game variable + * @param variable Variable that contains the reference + * @param configuration Configuration where the reference is searched in + * @param reference Reference variable name + * @return true if reference is a game variable, false otherwise + */ + private static Variable getGameVariableReference(Variable variable, Configuration configuration, String reference) { + + String r = reference.split("\\.")[0]; + for(IElement element : configuration.getElements()) { + if(element instanceof Module) { + Module m = (Module)element; + if(r.equals(m.getName())) { + if(!reference.contains(".")) { + // The reference contains only modules, implementation feature for the expression parser + return null; + } + Configuration moduleConfiguration = m.getType().getConfiguration(); + return getGameVariableReference(variable, moduleConfiguration, reference.substring(reference.indexOf(".") + 1)); + } + } else if(element instanceof IndependentVariable && !(element instanceof Stock)) { + IndependentVariable v = (IndependentVariable)element; + if(r.equals(v.getName())) { + if(v.getName().equals(variable.getName())) { + return null;// Reference to self. + } else { + if(Variability.PARAMETER.equals(Variability.getVariability(v, false, null))) { + return v; + } else { + return null; + } + + /* + if(v.getExpressions() == null || v.getExpressions().getExpressions().size() > 1) + return null; + + IExpression e = v.getExpressions().getExpressions().get(0); + + if(e instanceof ParameterExpression) + return v; + */ + } + } + } + } + return null; + } + + + public static Variable getVariable(Configuration configuration, String name) { + Configuration conf = configuration; + // This function seems to be used with both whitespaced and + // underscored versions of the variable name. + String whitespacedName = name.replace('_', ' '); + String[] components = whitespacedName.split("\\."); + + for(String component : components) { + + Configuration newConf = null; + + for(IElement element : conf.getElements()) { + if(element instanceof Variable) { + Variable variable = (Variable) element; + if(variable.getName().equals(component)) { + return variable; + } + } else if(element instanceof Module) { + Module m = (Module)element; + if(m.getName().equals(component)) { + newConf = m.getType().getConfiguration(); + } + } + } + + // If variable or configuration has not been found, return null + if(newConf == null) + return null; + } + + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/SheetFormatUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/SheetFormatUtils.java new file mode 100644 index 00000000..19b14ce8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/SheetFormatUtils.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.utils; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ParseException; +import org.simantics.sysdyn.expressionParser.Token; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Model; +import org.simantics.sysdyn.representation.ModuleType; +import org.simantics.sysdyn.representation.Sheet; +import org.simantics.sysdyn.representation.Variable; + +public class SheetFormatUtils { + + public static String reformatSheetReferences(Variable v, String expression) { + if(expression == null || !expression.contains("(")) + return expression; + ExpressionParser parser = new ExpressionParser(new StringReader(expression)); + try { + parser.expr(); + + HashMap> functionCalls = parser.getFunctionCallReferences(); + for(String key : functionCalls.keySet()) { + String[] parts = key.split("\\."); + Object current = v.getParentConfiguration(); + + // Hack. Sheets can currently exist only in models, not in module types. + ModuleType moduleType= ((Configuration)current).getModuleType(); + if(moduleType != null) { + if(moduleType.getParent() != null && moduleType.getParent() instanceof Model) + current = ((Model)moduleType.getParent()).getModelConfiguration(); + } + // end Hack. + + Object found = null; + for(int i = 0; i < parts.length && current != null; i++) { + found = null; + if(current instanceof Configuration) { + for(IElement e : ((Configuration)current).getElements()) { + if(e instanceof Configuration && + ((Variable)e).getName().equals(parts[i])) { + found = e; + break; + } else if(e instanceof Variable && + ((Variable)e).getName().equals(parts[i])) { + found = e; + break; + } + } + } + current = found; + } + + if(current != null && current instanceof Sheet) { + + String tmp = ""; + int start = 0, end = 0, call = 0; + String cellOrRange = null; + while((call = expression.indexOf(key + "(", end)) >= 0) { + start = expression.indexOf("(", call); + + tmp += expression.substring(end, start); + + end = expression.indexOf(")", start) + 1; + if(start < 0 || end < 0 || end < start) { + break; + } + cellOrRange = expression.substring(start, end); + cellOrRange = cellOrRange.substring(1, cellOrRange.length() - 1); + cellOrRange = cellOrRange.trim(); + cellOrRange = cellOrRange.replace(" ", ""); + + Pattern p = Pattern.compile("[-\\+\\*\\/\\(\\)\\{\\}\\[\\],\\.\\t\\n\\r\\f]"); + Matcher m = p.matcher(cellOrRange); + if (m.find() || cellOrRange.split(":").length > 2 || cellOrRange.length() == 0) { + continue; + } + + // Use the cell or range in the sheet. + ((Sheet)current).use(cellOrRange); + + cellOrRange = cellOrRange.replace(":", "_"); + + tmp += "." + cellOrRange; + } + tmp += expression.substring(end, expression.length()); + expression = tmp; + } + } + + } catch (ParseException e) { + } + return expression; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java new file mode 100644 index 00000000..d74b5934 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java @@ -0,0 +1,253 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.representation.utils; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.layer0.request.PossibleModel; +import org.simantics.operation.Layer0X; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.Variable; +import org.simantics.sysdyn.unitParser.ParseException; +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.UnitParser; +import org.simantics.sysdyn.unitParser.nodes.ComponentReferenceFull; +import org.simantics.sysdyn.unitParser.nodes.UnitResult; +import org.simantics.sysdyn.utils.Function; + +public class UnitUtils { + + public static String expressionUnitsValid(ReadGraph graph, SysdynModel model, Configuration configuration, String expression) { + try { + StringReader reader = new StringReader(expression); + UnitParser parser = new UnitParser(reader); + System.out.println("expression " + expression); + UnitCheckingNode node = (UnitCheckingNode) parser.expr(); + reader.close(); + Set components = UnitUtils.findComponents(node); + HashMap units = UnitUtils.findUnits(graph, model, configuration, components); + + try { + node.getUnits(units, Function.getAllBuiltInFunctions(graph), allowEquivalents(graph, model)); + } catch (UnitCheckingException e) { + return e.getMessage(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } catch (ParseException e) { + return "Cannot validate units: Syntax error in expression."; + } + return null; + } + + /** + * Determine if the Unit Equivalents checkbox is selected + * @param graph + * @param model SysdynModel of which configuration is queried + * @return true iff equivalent units are allowed + * @throws DatabaseException + */ + public static boolean allowEquivalents(ReadGraph graph, SysdynModel model) throws DatabaseException { + Resource modelResource = graph.syncRequest(new PossibleModel(model.getConfigurationResource())); + SysdynResource sr = SysdynResource.getInstance(graph); + Resource unitIssueSource = graph.syncRequest( + new PossibleObjectWithType(modelResource, + Layer0X.getInstance(graph).Activates, + sr.Validations_Units_UnitIssueSource)); + if(unitIssueSource == null) + return false; + + Boolean result = graph.getPossibleRelatedValue(unitIssueSource, sr.Validations_Units_UnitIssueSource_allowEquivalents, Bindings.BOOLEAN); + if(result == null) + result = false; + + return result; + } + + public static String matchUnits(ReadGraph graph, SysdynModel model, Configuration configuration, String unit, String expression) { + if(unit == null) + return "Unit not defined"; + + try { + StringReader rightReader = new StringReader(expression); + UnitParser rightParser = new UnitParser(rightReader); + UnitCheckingNode right = (UnitCheckingNode) rightParser.expr(); + rightReader.close(); + Set components = findComponents(right); + HashMap units = findUnits(graph, model, configuration, components); + + try { + StringReader leftReader = new StringReader(unit); + UnitParser leftParser = new UnitParser(leftReader); + UnitCheckingNode left = (UnitCheckingNode) leftParser.expr(); + leftReader.close(); + + try { + ArrayList functions = Function.getAllBuiltInFunctions(graph); + boolean allowEquivalents = allowEquivalents(graph, model); + UnitResult rightUnits = right.getUnits(units, functions, allowEquivalents); + UnitResult leftUnits = left.getUnits(null, functions, allowEquivalents); + + if(!rightUnits.equals(leftUnits)) + return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit(); + } catch (UnitCheckingException e) { + return e.getMessage(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } catch (ParseException e) { + return "Syntax error in defined unit."; + } + } catch (ParseException e) { + return "Cannot validate units: Syntax error in expression."; + } + return null; + } + + + public static HashMap findUnits(ReadGraph graph, SysdynModel model, Configuration configuration, Set components) { + HashMap units = new HashMap(); + for(String component : components) { + Variable var = getElement(configuration, component); + if(var != null) { + + // Support listening, if graph and mapping exists + if(graph != null && model != null) { + Resource varResource = model.getMapping().inverseGet(var); + if(varResource != null) { + try { + String unit = graph.getPossibleRelatedValue(varResource, SysdynResource.getInstance(graph).Variable_unit); + if(unit != null) { + units.put(component, unit); + } + } catch (ManyObjectsForFunctionalRelationException e) { + e.printStackTrace(); + } catch (ServiceException e) { + e.printStackTrace(); + } + } + } + } + } + + units.put("time", getTimeUnit(graph, model)); + + return units; + } + + public static String getTimeUnit(ReadGraph graph, SysdynModel model) { + try { + Resource modelResource = graph.syncRequest(new PossibleModel(model.getConfigurationResource())); + if(modelResource != null) { + String timeUnit = graph.getPossibleRelatedValue(modelResource, SysdynResource.getInstance(graph).SysdynModel_timeUnit); + if(timeUnit == null) + timeUnit = "month"; + return timeUnit; + } + } catch (ManyObjectsForFunctionalRelationException e) { + e.printStackTrace(); + } catch (ServiceException e) { + e.printStackTrace(); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + return null; + } + + private static Variable getElement(Configuration configuration, String name) { + String[] elements = name.split("\\."); + String element = elements[0]; + for(IElement e : configuration.getElements()) { + if(e instanceof Variable) { + Variable var = (Variable)e; + if(var.getName().equals(element)) + return var; + } else if(e instanceof Module && elements.length > 1) { + Module mod = (Module)e; + if(mod.getName().equals(element)) { + return getElement(mod.getType().getConfiguration(), name.substring(name.indexOf(".") + 1)); + } + } + } + return null; + } + + public static Set findComponents(UnitCheckingNode node) { + HashSet components = new HashSet(); + addComponents(node, components); + return components; + + } + + private static void addComponents(UnitCheckingNode node, HashSet components) { + if(node instanceof ComponentReferenceFull) { + components.add(node.printNode()); + } else { + for(int i = 0; i < node.jjtGetNumChildren(); i++) { + addComponents((UnitCheckingNode)node.jjtGetChild(i), components); + } + } + } + + + public static String matchUnits(String left, String right, ArrayList functions, boolean allowEquivalents) throws DatabaseException { + if(left == null || right == null || left.isEmpty() || right.isEmpty()) + return "No unit defined"; + + try { + StringReader leftReader = new StringReader(left); + UnitParser leftParser = new UnitParser(leftReader); + UnitCheckingNode leftNode = (UnitCheckingNode) leftParser.expr(); + leftReader.close(); + try { + StringReader rightReader = new StringReader(right); + UnitParser rightParser = new UnitParser(rightReader); + UnitCheckingNode rightNode = (UnitCheckingNode) rightParser.expr(); + rightReader.close(); + + try { + UnitResult leftUnits = leftNode.getUnits(null, functions, allowEquivalents); + UnitResult rightUnits = rightNode.getUnits(null, functions, allowEquivalents); + + if(!rightUnits.equals(leftUnits)) + return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit(); + } catch (UnitCheckingException e) { + return e.getMessage(); + } + } catch (ParseException e) { + return "Cannot validate units: Syntax error in expression."; + } + } catch (ParseException e) { + return "Syntax error in defined unit."; + } + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/ElementVisitorVoidAdapter.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/ElementVisitorVoidAdapter.java new file mode 100644 index 00000000..6b5465a9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/ElementVisitorVoidAdapter.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.visitors; + +import org.simantics.sysdyn.representation.Auxiliary; +import org.simantics.sysdyn.representation.Book; +import org.simantics.sysdyn.representation.Cloud; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.Dependency; +import org.simantics.sysdyn.representation.DiagramContainerDummy; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.Flow; +import org.simantics.sysdyn.representation.Input; +import org.simantics.sysdyn.representation.LibraryDummy; +import org.simantics.sysdyn.representation.Loop; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.Stock; +import org.simantics.sysdyn.representation.Valve; +import org.simantics.sysdyn.representation.Variable; + +public class ElementVisitorVoidAdapter implements IElementVisitorVoid { + + @Override + public void visit(Auxiliary auxiliary) { + } + + @Override + public void visit(Stock stock) { + } + + @Override + public void visit(Valve valve) { + } + + @Override + public void visit(Cloud cloud) { + } + + @Override + public void visit(Input input) { + } + + @Override + public void visit(Dependency dependency) { + } + + @Override + public void visit(Flow flow) { + } + + @Override + public void visit(Module module) { + } + + @Override + public void visit(Configuration configuration) { + } + + @Override + public void visit(Enumeration enumeration) { + } + + @Override + public void visit(LibraryDummy libraryDummy) { + } + + @Override + public void visit(Book sheet) { + } + + @Override + public void visit(DiagramContainerDummy container) { + } + + @Override + public void visit(Variable variable) { + } + + @Override + public void visit(Loop loop) { + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/IElementVisitorVoid.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/IElementVisitorVoid.java new file mode 100644 index 00000000..3b282583 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/visitors/IElementVisitorVoid.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.visitors; + +import org.simantics.sysdyn.representation.Auxiliary; +import org.simantics.sysdyn.representation.Book; +import org.simantics.sysdyn.representation.Cloud; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.Dependency; +import org.simantics.sysdyn.representation.DiagramContainerDummy; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.Flow; +import org.simantics.sysdyn.representation.Input; +import org.simantics.sysdyn.representation.LibraryDummy; +import org.simantics.sysdyn.representation.Loop; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.Stock; +import org.simantics.sysdyn.representation.Valve; +import org.simantics.sysdyn.representation.Variable; + +public interface IElementVisitorVoid { + + void visit(Auxiliary auxiliary); + void visit(Stock stock); + void visit(Valve valve); + void visit(Cloud cloud); + void visit(Input input); + void visit(Dependency dependency); + void visit(Flow flow); + void visit(Module module); + void visit(Configuration configuration); + void visit(Enumeration enumeration); + void visit(LibraryDummy libraryDummy); + void visit(Book sheet); + void visit(DiagramContainerDummy container); + void visit(Variable variable); + void visit(Loop loop); + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/simulation/SimulationJob.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/simulation/SimulationJob.java new file mode 100644 index 00000000..92e8c99e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/simulation/SimulationJob.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2010, 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.simulation; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ui.PlatformUI; +import org.simantics.modelica.IModelicaMonitor; +import org.simantics.sysdyn.manager.OldSysdynExperiment; +import org.simantics.sysdyn.manager.SysdynConsole; +import org.simantics.sysdyn.manager.SysdynModel; + +public class SimulationJob extends Job { + + private SysdynModel model; + private OldSysdynExperiment experiment; + private IModelicaMonitor monitor; + + public SimulationJob(SysdynModel model, OldSysdynExperiment experiment) { + super("Simulate " + model.getConfiguration().getLabel()); + this.model = model; + this.experiment = experiment; + if(PlatformUI.isWorkbenchRunning()) { + this.monitor = SysdynConsole.INSTANCE; + } else { + // Fallback to headless + this.monitor = new HeadlessModelicaMonitor(); + } + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask("Simulate " + model.getConfiguration().getLabel(), experiment.numberOfSimulationRunSteps()); + try { + model.update(); + if(experiment instanceof OldSysdynExperiment) { + ((OldSysdynExperiment)experiment).simulate(this.monitor, monitor, model.getConfiguration().getLabel()); + model.setStructureModified(false); + } + } catch (Exception e) { + e.printStackTrace(); + this.monitor.showConsole(); + return new Status( + Status.ERROR, + "org.simantics.sysdyn.ui", + "Simulation failed: \n" + e.getMessage()); + } + this.monitor.message("\n"); + monitor.done(); + return Status.OK_STATUS; + } + + @Override + public boolean belongsTo(Object family) { + return "SimulationJob".equals(family); + } + + private class HeadlessModelicaMonitor implements IModelicaMonitor { + public HeadlessModelicaMonitor() { + } + + @Override + public void message(String message) { + message(message, "hh:mm:ss"); + } + + /** + * Print message to a console with a specified time stamp format + * + * @param message the message to be printed + * @param timeStampFormat simpledateformat timestamp format. null if no timestamp wanted + */ + public void message(String message, String timeStampFormat) { + Calendar cal = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat(timeStampFormat); + String time = sdf.format(cal.getTime()); + + System.out.println("[" + time +"] " + message); + } + + public void clearConsole() { + } + + public void showConsole() { + } + + } + + @Override + protected void canceling() { + + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/simulation/SimulationScheduler.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/simulation/SimulationScheduler.java new file mode 100644 index 00000000..bd4d7d69 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/simulation/SimulationScheduler.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.simulation; + +import org.simantics.sysdyn.manager.OldSysdynExperiment; +import org.simantics.sysdyn.manager.SysdynModel; + +public class SimulationScheduler { + SysdynModel model; + OldSysdynExperiment experiment; + SimulationJob job; + + private SimulationScheduler(SysdynModel model, OldSysdynExperiment experiment) { + this.model = model; + this.experiment = experiment; + this.job = new SimulationJob(model, experiment); + } + + private void start() { + job.schedule(); + } + + public static synchronized SimulationScheduler start(SysdynModel model, OldSysdynExperiment experiment) { + SimulationScheduler scheduler = model.getService(SimulationScheduler.class); + if(scheduler == null || !scheduler.experiment.equals(experiment)) { + scheduler = new SimulationScheduler(model, experiment); + model.addService(SimulationScheduler.class, scheduler); + scheduler.start(); + } else { + scheduler.start(); + } + return scheduler; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolver.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolver.java new file mode 100644 index 00000000..d52a67c7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolver.java @@ -0,0 +1,13 @@ +package org.simantics.sysdyn.solver; + +import org.simantics.sysdyn.solver.SolverSettings.SolverType; + +public interface ISolver { + + public void initialize() throws Exception; + public void buildModel() throws Exception; + public void runSolver() throws Exception; + public void updateResults() throws Exception; + public SolverType getType(); + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolverMonitor.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolverMonitor.java new file mode 100644 index 00000000..9df8735e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/ISolverMonitor.java @@ -0,0 +1,9 @@ +package org.simantics.sysdyn.solver; + +import org.simantics.modelica.IModelicaMonitor; + +public interface ISolverMonitor extends IModelicaMonitor { + public void message(String message); + public void clearConsole(); + public void showConsole(); +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java new file mode 100644 index 00000000..4c00a72e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java @@ -0,0 +1,136 @@ +package org.simantics.sysdyn.solver; + +import java.util.HashMap; + +import org.simantics.modelica.ModelicaManager; +import org.simantics.modelica.SimulationLocation; +import org.simantics.sysdyn.manager.FunctionUtils; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.manager.SysdynExperiment; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.modelica.ModelicaWriter; +import org.simantics.sysdyn.representation.Model; +import org.simantics.sysdyn.solver.SolverSettings.SolverType; + +import fi.semantum.sysdyn.solver.Solver; + +public class InternalSolver implements ISolver { + + private SysdynExperiment experiment; + private SysdynModel model; + private ISolverMonitor monitor; + private Solver solver; + + private double start; + private double stop; + private double step; + private double interval; + + private SimulationLocation location; + + private HashMap results; + + public InternalSolver(SysdynExperiment experiment, SysdynModel model, ISolverMonitor monitor) { + this.experiment = experiment; + this.model = model; + this.monitor = monitor; + + solver = new Solver(); + + // default values + start = 0; + stop = 500; + step = 0.1; + interval = step; + } + + @Override + public void initialize() throws Exception { + String omVersion = ModelicaManager.getDefaultOMVersion(); + String modelContent = ModelicaWriter.write(model.getModules(), false, omVersion); + + // update some stuff + FunctionUtils.updateFunctionFilesForExperiment(experiment); + + location = ModelicaManager.createSimulationLocation(experiment.getExperimentDir(), + model.getConfiguration().getLabel(), modelContent); + + // set solver parameters + Model representation = model.getConfiguration().getModel(); + // TODO: should probably check that the values actually make sense + // i.e. start and stop >= 0, start <= stop, stop - start >= step + if (representation.getStartTime() != null) + start = representation.getStartTime(); + if (representation.getStopTime() != null) + stop = representation.getStopTime(); + + if (representation.getSimulationStepLength() != null) + step = representation.getSimulationStepLength(); + else + step = (stop - start) / 500; + + if (representation.getOutputInterval() != null) + interval = representation.getOutputInterval(); + else + interval = step; + + solver.setStep(step); + solver.setStart(start); + } + + @Override + public void buildModel() throws Exception { + String flat = ModelicaManager.getFlatModelText(location, monitor, FunctionUtils.getLibraryPathsForModelica(experiment)); + solver.prepare(flat); + } + + @Override + public void runSolver() throws Exception { + // the number of result intervals in the simulation (account for initial values) + int count = (int)((stop - start) / interval) + 1; + // the number of steps in one result interval + int steps = (int)(interval / step); + + // an array containing an accurate time stamp for each interval + double[] times = new double[count]; + // a map containing values of all variables for each interval + HashMap values = new HashMap(); + // initialize the temporary data structures + times[0] = start; + HashMap tmp = solver.values(); + for (String key : tmp.keySet()) { + values.put(key, new double[count]); + values.get(key)[0] = tmp.get(key); + } + + // run the simulation + for (int interval = 1; interval < count; interval++) { + for (int i = 0; i < steps; i++) { + solver.step(); + } + times[interval] = times[interval-1] + steps * step; + tmp = solver.values(); + for (String key : tmp.keySet()) { + values.get(key)[interval] = tmp.get(key); + } + } + + results = new HashMap(); + for (String name : values.keySet()) { + results.put(name, new SysdynDataSet(name, null, times, values.get(name))); + } + } + + @Override + public void updateResults() throws Exception { + InternalSolverResult result = new InternalSolverResult(null, results); + experiment.setCurrentResult(result); + experiment.resultsChanged(); + } + + @Override + public SolverType getType() { + return SolverType.INTERNAL; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolverResult.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolverResult.java new file mode 100644 index 00000000..b630012a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolverResult.java @@ -0,0 +1,29 @@ +package org.simantics.sysdyn.solver; + +import java.io.File; +import java.util.HashMap; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.simantics.sysdyn.manager.SysdynDataSet; +import org.simantics.sysdyn.manager.SysdynResult; + +public class InternalSolverResult extends SysdynResult { + + private HashMap results; + + public InternalSolverResult(String resultName, HashMap results) { + super(resultName); + this.results = results; + } + + @Override + public SysdynDataSet getDataSet(String variable) { + return results.get(variable); + } + + @Override + public void saveToFile(File file, IProgressMonitor progressMonitor) { + // not implemented + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SolverParameters.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SolverParameters.java new file mode 100644 index 00000000..ec32dab5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SolverParameters.java @@ -0,0 +1,13 @@ +package org.simantics.sysdyn.solver; + +public class SolverParameters { + public static final String START_VALUE = "startTime"; + public static final String STOP_VALUE = "stopTime"; + public static final String OUTPUT_FORMAT = "outputFormat"; + public static final String STEP_VALUE = "stepSize"; + public static final String NUMBER_OF_INTERVALS = "numberOfIntervals"; + public static final String METHOD = "method"; + public static final String TOLERANCE = "tolerance"; + public static final String VARIABLE_FILTER = "variableFilter"; + public static final String OUTPUT_INTERVAL = "outputInterval"; +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SolverSettings.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SolverSettings.java new file mode 100644 index 00000000..b3e8fb06 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SolverSettings.java @@ -0,0 +1,34 @@ +package org.simantics.sysdyn.solver; + +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.osgi.service.prefs.Preferences; + +public class SolverSettings { + + public enum SolverType { + INTERNAL, OPENMODELICA, UNKNOWN + } + + public static final String QUALIFIER = "org.simantics.sysdyn.solver.preferences"; + + public static final String SOLVER_TYPE = "SOLVER_TYPE"; + public static final String SOLVER_TYPE_INTERNAL = "INTERNAL"; + public static final String SOLVER_TYPE_OPENMODELICA = "OPENMODELICA"; + + public static SolverType getSelectedSolverType() { + Preferences preferences = ConfigurationScope.INSTANCE.getNode(SolverSettings.QUALIFIER); + // default to internal solver + String type = preferences.get(SolverSettings.SOLVER_TYPE, SolverSettings.SOLVER_TYPE_INTERNAL); + + if (SOLVER_TYPE_INTERNAL.equals(type)) { + return SolverType.INTERNAL; + } + else if (SOLVER_TYPE_OPENMODELICA.equals(type)) { + return SolverType.OPENMODELICA; + } + else { + return SolverType.UNKNOWN; + } + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SysdynSimulationJob.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SysdynSimulationJob.java new file mode 100644 index 00000000..9c804322 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SysdynSimulationJob.java @@ -0,0 +1,97 @@ +package org.simantics.sysdyn.solver; + +import gnu.trove.map.TObjectIntMap; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.simantics.db.exception.DatabaseException; +import org.simantics.Simantics; +import org.simantics.issues.Severity; +import org.simantics.issues.common.CountModelIssuesBySeverity; +import org.simantics.sysdyn.manager.SysdynConsole; +import org.simantics.sysdyn.manager.SysdynExperiment; +import org.simantics.sysdyn.solver.SolverSettings.SolverType; + +public class SysdynSimulationJob extends Job { + + private static final String pluginId = "unknown"; + + protected String name; + protected SysdynExperiment experiment; + protected ISolver solver; + + public SysdynSimulationJob(String name, SysdynExperiment experiment) { + super(name); + this.name = name; + this.experiment = experiment; + this.solver = null; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask("Simulate " + name, 4); + + // model update is necessary as it upgrades the isStructureModifier + // flag, could possibly be done differently if avoiding the graph + // operation is desired + try { + experiment.sysdynModel.update(); + } + catch (DatabaseException e) { + return new Status(Status.ERROR, pluginId, "Could not update model", e); + } + + // do not simulate if there are errors in the model + try { + TObjectIntMap severeties = + Simantics.sync(new CountModelIssuesBySeverity(experiment.getModel(), true, Severity.ERROR)); + if (severeties.get(Severity.ERROR) > 0) { + return new Status(Status.ERROR, pluginId, "There are unresolved errors in the model"); + } + } + catch (DatabaseException e) { + return new Status(Status.ERROR, pluginId, "Could not obtain issue count from model", e); + } + + SolverType type = experiment.getSolverType(); + // if the solver has not been created yet or the type of the solver + // has changed, a new solver must be created + if (solver == null || !solver.getType().equals(type)) { + if (SolverType.INTERNAL.equals(type)) { + solver = new InternalSolver(experiment, experiment.sysdynModel, SysdynConsole.INSTANCE); + } + else if (SolverType.OPENMODELICA.equals(type)) { + return new Status(Status.ERROR, pluginId, "The experiment should be reloaded"); + } + } + + // TODO: this should be broken down + + try { + monitor.subTask("generating model..."); + solver.initialize(); + monitor.worked(1); + + monitor.subTask("building model..."); + solver.buildModel(); + monitor.worked(1); + + monitor.subTask("running solver..."); + solver.runSolver(); + monitor.worked(1); + + monitor.subTask("getting results..."); + solver.updateResults(); + monitor.worked(1); + } + catch (Exception e) { + return new Status(Status.ERROR, pluginId, "Simulation failed", e); + } + + monitor.done(); + return Status.OK_STATUS; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/ParseException.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/ParseException.java new file mode 100644 index 00000000..57f889b6 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/ParseException.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */ +/* JavaCCOptions:KEEP_LINE_COL=null */ +package org.simantics.sysdyn.tableParser; + +/** + * This exception is thrown when parse errors are encountered. + * You can explicitly create objects of this exception type by + * calling the method generateParseException in the generated + * parser. + * + * You can modify this class to customize your error reporting + * mechanisms so long as you retain the public fields. + */ +public class ParseException extends Exception { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * This constructor is used by the method "generateParseException" + * in the generated parser. Calling this constructor generates + * a new object of this type with the fields "currentToken", + * "expectedTokenSequences", and "tokenImage" set. + */ + public ParseException(Token currentTokenVal, + int[][] expectedTokenSequencesVal, + String[] tokenImageVal + ) + { + super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal)); + currentToken = currentTokenVal; + expectedTokenSequences = expectedTokenSequencesVal; + tokenImage = tokenImageVal; + } + + /** + * The following constructors are for use by you for whatever + * purpose you can think of. Constructing the exception in this + * manner makes the exception behave in the normal way - i.e., as + * documented in the class "Throwable". The fields "errorToken", + * "expectedTokenSequences", and "tokenImage" do not contain + * relevant information. The JavaCC generated code does not use + * these constructors. + */ + + public ParseException() { + super(); + } + + /** Constructor with message. */ + public ParseException(String message) { + super(message); + } + + + /** + * This is the last token that has been consumed successfully. If + * this object has been created due to a parse error, the token + * followng this token will (therefore) be the first error token. + */ + public Token currentToken; + + /** + * Each entry in this array is an array of integers. Each array + * of integers represents a sequence of tokens (by their ordinal + * values) that is expected at this point of the parse. + */ + public int[][] expectedTokenSequences; + + /** + * This is a reference to the "tokenImage" array of the generated + * parser within which the parse error occurred. This array is + * defined in the generated ...Constants interface. + */ + public String[] tokenImage; + + /** + * It uses "currentToken" and "expectedTokenSequences" to generate a parse + * error message and returns it. If this object has been created + * due to a parse error, and you do not catch it (it gets thrown + * from the parser) the correct error message + * gets displayed. + */ + private static String initialise(Token currentToken, + int[][] expectedTokenSequences, + String[] tokenImage) { + String eol = System.getProperty("line.separator", "\n"); + StringBuffer expected = new StringBuffer(); + int maxSize = 0; + for (int i = 0; i < expectedTokenSequences.length; i++) { + if (maxSize < expectedTokenSequences[i].length) { + maxSize = expectedTokenSequences[i].length; + } + for (int j = 0; j < expectedTokenSequences[i].length; j++) { + expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); + } + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + expected.append("..."); + } + expected.append(eol).append(" "); + } + String retval = "Encountered \""; + Token tok = currentToken.next; + for (int i = 0; i < maxSize; i++) { + if (i != 0) retval += " "; + if (tok.kind == 0) { + retval += tokenImage[0]; + break; + } + retval += " " + tokenImage[tok.kind]; + retval += " \""; + retval += add_escapes(tok.image); + retval += " \""; + tok = tok.next; + } + retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; + retval += "." + eol; + if (expectedTokenSequences.length == 1) { + retval += "Was expecting:" + eol + " "; + } else { + retval += "Was expecting one of:" + eol + " "; + } + retval += expected.toString(); + return retval; + } + + /** + * The end of line string for this machine. + */ + protected String eol = System.getProperty("line.separator", "\n"); + + /** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal. + */ + static String add_escapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + +} +/* JavaCC - OriginalChecksum=812397ddfc370286eccefa2f873e20e3 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/SimpleCharStream.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/SimpleCharStream.java new file mode 100644 index 00000000..70ba9d99 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/SimpleCharStream.java @@ -0,0 +1,482 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */ +/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package org.simantics.sysdyn.tableParser; + +/** + * An implementation of interface CharStream, where the stream is assumed to + * contain only ASCII characters (without unicode processing). + */ + +public class SimpleCharStream +{ +/** Whether parser is static. */ + public static final boolean staticFlag = false; + int bufsize; + int available; + int tokenBegin; +/** Position in buffer. */ + public int bufpos = -1; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int inBuf = 0; + protected int tabSize = 8; + + protected void setTabSize(int i) { tabSize = i; } + protected int getTabSize(int i) { return tabSize; } + + + protected void ExpandBuff(boolean wrapAround) + { + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try + { + if (wrapAround) + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos += (bufsize - tokenBegin)); + } + else + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos -= tokenBegin); + } + } + catch (Throwable t) + { + throw new Error(t.getMessage()); + } + + + bufsize += 2048; + available = bufsize; + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException + { + if (maxNextCharInd == available) + { + if (available == bufsize) + { + if (tokenBegin > 2048) + { + bufpos = maxNextCharInd = 0; + available = tokenBegin; + } + else if (tokenBegin < 0) + bufpos = maxNextCharInd = 0; + else + ExpandBuff(false); + } + else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + int i; + try { + if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1) + { + inputStream.close(); + throw new java.io.IOException(); + } + else + maxNextCharInd += i; + return; + } + catch(java.io.IOException e) { + --bufpos; + backup(0); + if (tokenBegin == -1) + tokenBegin = bufpos; + throw e; + } + } + +/** Start. */ + public char BeginToken() throws java.io.IOException + { + tokenBegin = -1; + char c = readChar(); + tokenBegin = bufpos; + + return c; + } + + protected void UpdateLineColumn(char c) + { + column++; + + if (prevCharIsLF) + { + prevCharIsLF = false; + line += (column = 1); + } + else if (prevCharIsCR) + { + prevCharIsCR = false; + if (c == '\n') + { + prevCharIsLF = true; + } + else + line += (column = 1); + } + + switch (c) + { + case '\r' : + prevCharIsCR = true; + break; + case '\n' : + prevCharIsLF = true; + break; + case '\t' : + column--; + column += (tabSize - (column % tabSize)); + break; + default : + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + +/** Read a character. */ + public char readChar() throws java.io.IOException + { + if (inBuf > 0) + { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + if (++bufpos >= maxNextCharInd) + FillBuff(); + + char c = buffer[bufpos]; + + UpdateLineColumn(c); + return c; + } + + @Deprecated + /** + * @deprecated + * @see #getEndColumn + */ + + public int getColumn() { + return bufcolumn[bufpos]; + } + + @Deprecated + /** + * @deprecated + * @see #getEndLine + */ + + public int getLine() { + return bufline[bufpos]; + } + + /** Get token end column number. */ + public int getEndColumn() { + return bufcolumn[bufpos]; + } + + /** Get token end line number. */ + public int getEndLine() { + return bufline[bufpos]; + } + + /** Get token beginning column number. */ + public int getBeginColumn() { + return bufcolumn[tokenBegin]; + } + + /** Get token beginning line number. */ + public int getBeginLine() { + return bufline[tokenBegin]; + } + +/** Backup a number of characters. */ + public void backup(int amount) { + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length) + { + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + bufpos = -1; + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, 1, 1, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, startline, startcolumn, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + /** Get token literal value. */ + public String GetImage() + { + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + else + return new String(buffer, tokenBegin, bufsize - tokenBegin) + + new String(buffer, 0, bufpos + 1); + } + + /** Get the suffix. */ + public char[] GetSuffix(int len) + { + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else + { + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, + len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + /** Reset buffer when finished. */ + public void Done() + { + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + */ + public void adjustBeginLineColumn(int newLine, int newCol) + { + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin) + { + len = bufpos - tokenBegin + inBuf + 1; + } + else + { + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k = 0; + int nextColDiff = 0, columnDiff = 0; + + while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) + { + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len) + { + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while (i++ < len) + { + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + +} +/* JavaCC - OriginalChecksum=6ae427b43f697d2e9732f56763450bf7 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParser.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParser.java new file mode 100644 index 00000000..a8f1dd22 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParser.java @@ -0,0 +1,303 @@ +/* Generated By:JavaCC: Do not edit this line. TableParser.java */ +package org.simantics.sysdyn.tableParser; + +import java.util.ArrayList; + +public class TableParser implements TableParserConstants { + ArrayList xTokens = new ArrayList(); + ArrayList yTokens = new ArrayList(); + + public ArrayList getXTokens() { + return xTokens; + } + + public ArrayList getYTokens() { + return yTokens; + } + +/*** Parser ********************************************************/ + final public void table() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 64: + case 66: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 64: + curlyTable(); + break; + case 66: + bracketTable(); + break; + default: + jj_la1[0] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[1] = jj_gen; + ; + } + jj_consume_token(0); + } + + final public void curlyTable() throws ParseException { + jj_consume_token(64); + jj_consume_token(64); + table_element(); + jj_consume_token(65); + label_1: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 71: + ; + break; + default: + jj_la1[2] = jj_gen; + break label_1; + } + jj_consume_token(71); + jj_consume_token(64); + table_element(); + jj_consume_token(65); + } + jj_consume_token(65); + } + + final public void bracketTable() throws ParseException { + jj_consume_token(66); + table_element(); + label_2: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 70: + ; + break; + default: + jj_la1[3] = jj_gen; + break label_2; + } + jj_consume_token(70); + table_element(); + } + jj_consume_token(67); + } + + final public void table_element() throws ParseException { + x_value(); + jj_consume_token(71); + y_value(); + } + + final public void x_value() throws ParseException { + signed_number(); + xTokens.add(token); + } + + final public void y_value() throws ParseException { + signed_number(); + yTokens.add(token); + } + + final public void signed_number() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case UNSIGNED_INTEGER: + jj_consume_token(UNSIGNED_INTEGER); + break; + case UNSIGNED_NUMBER: + jj_consume_token(UNSIGNED_NUMBER); + break; + case SIGNED_NUMBER: + jj_consume_token(SIGNED_NUMBER); + break; + default: + jj_la1[4] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + + /** Generated Token Manager. */ + public TableParserTokenManager token_source; + SimpleCharStream jj_input_stream; + /** Current token. */ + public Token token; + /** Next token. */ + public Token jj_nt; + private int jj_ntk; + private int jj_gen; + final private int[] jj_la1 = new int[5]; + static private int[] jj_la1_0; + static private int[] jj_la1_1; + static private int[] jj_la1_2; + static { + jj_la1_init_0(); + jj_la1_init_1(); + jj_la1_init_2(); + } + private static void jj_la1_init_0() { + jj_la1_0 = new int[] {0x0,0x0,0x0,0x0,0x0,}; + } + private static void jj_la1_init_1() { + jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,}; + } + private static void jj_la1_init_2() { + jj_la1_2 = new int[] {0x5,0x5,0x80,0x40,0x70000000,}; + } + + /** Constructor with InputStream. */ + public TableParser(java.io.InputStream stream) { + this(stream, null); + } + /** Constructor with InputStream and supplied encoding */ + public TableParser(java.io.InputStream stream, String encoding) { + try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source = new TableParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 5; i++) jj_la1[i] = -1; + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream, String encoding) { + try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 5; i++) jj_la1[i] = -1; + } + + /** Constructor. */ + public TableParser(java.io.Reader stream) { + jj_input_stream = new SimpleCharStream(stream, 1, 1); + token_source = new TableParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 5; i++) jj_la1[i] = -1; + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 5; i++) jj_la1[i] = -1; + } + + /** Constructor with generated Token Manager. */ + public TableParser(TableParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 5; i++) jj_la1[i] = -1; + } + + /** Reinitialise. */ + public void ReInit(TableParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 5; i++) jj_la1[i] = -1; + } + + private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + jj_gen++; + return token; + } + token = oldToken; + jj_kind = kind; + throw generateParseException(); + } + + +/** Get the next Token. */ + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; + } + +/** Get the specific Token. */ + final public Token getToken(int index) { + Token t = token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + private int jj_ntk() { + if ((jj_nt=token.next) == null) + return (jj_ntk = (token.next=token_source.getNextToken()).kind); + else + return (jj_ntk = jj_nt.kind); + } + + private java.util.List jj_expentries = new java.util.ArrayList(); + private int[] jj_expentry; + private int jj_kind = -1; + + /** Generate ParseException. */ + public ParseException generateParseException() { + jj_expentries.clear(); + boolean[] la1tokens = new boolean[95]; + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int i = 0; i < 5; i++) { + if (jj_la1[i] == jj_gen) { + for (int j = 0; j < 32; j++) { + if ((jj_la1_0[i] & (1< xTokens = new ArrayList(); + ArrayList yTokens = new ArrayList(); + + public ArrayList getXTokens() { + return xTokens; + } + + public ArrayList getYTokens() { + return yTokens; + } + + +} +PARSER_END(TableParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ +"algorithm" | "discrete" | "false" | "model" | "redeclare" +| "and" | "each" | "final" | "not" | "replaceable" +| "annotation" | "else" | "flow" | "operator" | "return" +|"assert" | "elseif" | "for" | "or" | "stream" +| "block" | "elsewhen" | "function" | "outer" | "then" +| "break" | "encapsulated" | "if" | "output" | "true" +| "class" | "end" | "import" | "package" | "type" +| "connect" | "enumeration" | "in" | "parameter" | "when" +| "connector" | "equation" | "initial" | "partial" | "while" +| "constant" | "expandable" | "inner" | "protected" | "within" +| "constrainedby" | "extends" | "input" | "public" +| "der" | "external" | "loop" | "record" +| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | "," +| "<" | "<=" | ">" | ">=" | "==" | "<>" +| "+" | "-" | ".+" | ".-" +| "*" | "/" | ".*" | "./" +| "^" | ".^" +| "=" | ":=" +| +| + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +| +| "." ()? (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +| | ))> +} + +/*** Parser ********************************************************/ + +void table() : { +} { + ( curlyTable() | bracketTable())? +} + +void curlyTable() : { } { + ( "{" "{" table_element() "}" ( "," "{" table_element() "}" )* "}" ) +} +void bracketTable() : { } { + ( "[" table_element() ( ";" table_element() )* "]" ) +} + +void table_element() : { +} { + (x_value() "," y_value()) +} + +void x_value() : { +} { + + signed_number() { + xTokens.add(token); + } +} + +void y_value() : { +} { + signed_number() { + yTokens.add(token); + } +} + +void signed_number() : { +} { + ( | | ) +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParserConstants.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParserConstants.java new file mode 100644 index 00000000..6b5f0838 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParserConstants.java @@ -0,0 +1,132 @@ +/* Generated By:JavaCC: Do not edit this line. TableParserConstants.java */ +package org.simantics.sysdyn.tableParser; + + +/** + * Token literal values and constants. + * Generated by org.javacc.parser.OtherFilesGen#start() + */ +public interface TableParserConstants { + + /** End of File. */ + int EOF = 0; + /** RegularExpression Id. */ + int WHITESPACE = 1; + /** RegularExpression Id. */ + int COMMENT1 = 2; + /** RegularExpression Id. */ + int COMMENT2 = 3; + /** RegularExpression Id. */ + int IDENT = 90; + /** RegularExpression Id. */ + int STRING = 91; + /** RegularExpression Id. */ + int UNSIGNED_INTEGER = 92; + /** RegularExpression Id. */ + int UNSIGNED_NUMBER = 93; + /** RegularExpression Id. */ + int SIGNED_NUMBER = 94; + + /** Lexical state. */ + int DEFAULT = 0; + + /** Literal token values. */ + String[] tokenImage = { + "", + "", + "", + "", + "\"algorithm\"", + "\"discrete\"", + "\"false\"", + "\"model\"", + "\"redeclare\"", + "\"and\"", + "\"each\"", + "\"final\"", + "\"not\"", + "\"replaceable\"", + "\"annotation\"", + "\"else\"", + "\"flow\"", + "\"operator\"", + "\"return\"", + "\"assert\"", + "\"elseif\"", + "\"for\"", + "\"or\"", + "\"stream\"", + "\"block\"", + "\"elsewhen\"", + "\"function\"", + "\"outer\"", + "\"then\"", + "\"break\"", + "\"encapsulated\"", + "\"if\"", + "\"output\"", + "\"true\"", + "\"class\"", + "\"end\"", + "\"import\"", + "\"package\"", + "\"type\"", + "\"connect\"", + "\"enumeration\"", + "\"in\"", + "\"parameter\"", + "\"when\"", + "\"connector\"", + "\"equation\"", + "\"initial\"", + "\"partial\"", + "\"while\"", + "\"constant\"", + "\"expandable\"", + "\"inner\"", + "\"protected\"", + "\"within\"", + "\"constrainedby\"", + "\"extends\"", + "\"input\"", + "\"public\"", + "\"der\"", + "\"external\"", + "\"loop\"", + "\"record\"", + "\"(\"", + "\")\"", + "\"{\"", + "\"}\"", + "\"[\"", + "\"]\"", + "\".\"", + "\":\"", + "\";\"", + "\",\"", + "\"<\"", + "\"<=\"", + "\">\"", + "\">=\"", + "\"==\"", + "\"<>\"", + "\"+\"", + "\"-\"", + "\".+\"", + "\".-\"", + "\"*\"", + "\"/\"", + "\".*\"", + "\"./\"", + "\"^\"", + "\".^\"", + "\"=\"", + "\":=\"", + "", + "", + "", + "", + "", + }; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParserTokenManager.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParserTokenManager.java new file mode 100644 index 00000000..3de87d4f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TableParserTokenManager.java @@ -0,0 +1,1436 @@ +/* Generated By:JavaCC: Do not edit this line. TableParserTokenManager.java */ +package org.simantics.sysdyn.tableParser; + +/** Token Manager. */ +public class TableParserTokenManager implements TableParserConstants +{ + + /** Debug output. */ + public java.io.PrintStream debugStream = System.out; + /** Set debug output. */ + public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } +private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1) +{ + switch (pos) + { + case 0: + if ((active1 & 0x80000L) != 0L) + return 24; + if ((active0 & 0x3ffffffffffffff0L) != 0L) + { + jjmatchedKind = 90; + return 2; + } + if ((active1 & 0xb30010L) != 0L) + return 46; + if ((active1 & 0x8000L) != 0L) + return 9; + return -1; + case 1: + if ((active0 & 0x108420080400000L) != 0L) + return 2; + if ((active0 & 0x3ef7bdff7fbffff0L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 90; + jjmatchedPos = 1; + } + return 2; + } + return -1; + case 2: + if ((active0 & 0x400000800201200L) != 0L) + return 2; + if ((active0 & 0x3bfffdf77f9fedf0L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 2; + return 2; + } + return -1; + case 3: + if ((active0 & 0x1000084212118400L) != 0L) + return 2; + if ((active0 & 0x2bfff5b56d8e69f0L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 90; + jjmatchedPos = 3; + } + return 2; + } + return -1; + case 4: + if ((active0 & 0x1090004290008c0L) != 0L) + return 2; + if ((active0 & 0x2af6f5b1469e6130L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 4; + return 2; + } + return -1; + case 5: + if ((active0 & 0x22200011009c0000L) != 0L) + return 2; + if ((active0 & 0x8d6f5a046026130L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 5; + return 2; + } + return -1; + case 6: + if ((active0 & 0x80d0a000000000L) != 0L) + return 2; + if ((active0 & 0x856250046026130L) != 0L) + { + if (jjmatchedPos != 6) + { + jjmatchedKind = 90; + jjmatchedPos = 6; + } + return 2; + } + return -1; + case 7: + if ((active0 & 0x54150040006110L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 7; + return 2; + } + if ((active0 & 0x802200006020020L) != 0L) + return 2; + return -1; + case 8: + if ((active0 & 0x10140000000110L) != 0L) + return 2; + if ((active0 & 0x44010040006000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 8; + return 2; + } + return -1; + case 9: + if ((active0 & 0x40010040002000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 9; + return 2; + } + if ((active0 & 0x4000000004000L) != 0L) + return 2; + return -1; + case 10: + if ((active0 & 0x10000002000L) != 0L) + return 2; + if ((active0 & 0x40000040000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 10; + return 2; + } + return -1; + case 11: + if ((active0 & 0x40000000L) != 0L) + return 2; + if ((active0 & 0x40000000000000L) != 0L) + { + jjmatchedKind = 90; + jjmatchedPos = 11; + return 2; + } + return -1; + default : + return -1; + } +} +private final int jjStartNfa_0(int pos, long active0, long active1) +{ + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1); +} +private int jjStopAtPos(int pos, int kind) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} +private int jjMoveStringLiteralDfa0_0() +{ + switch(curChar) + { + case 40: + return jjStopAtPos(0, 62); + case 41: + return jjStopAtPos(0, 63); + case 42: + return jjStopAtPos(0, 82); + case 43: + return jjStopAtPos(0, 78); + case 44: + return jjStopAtPos(0, 71); + case 45: + return jjStartNfaWithStates_0(0, 79, 9); + case 46: + jjmatchedKind = 68; + return jjMoveStringLiteralDfa1_0(0x0L, 0xb30000L); + case 47: + return jjStartNfaWithStates_0(0, 83, 24); + case 58: + jjmatchedKind = 69; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2000000L); + case 59: + return jjStopAtPos(0, 70); + case 60: + jjmatchedKind = 72; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2200L); + case 61: + jjmatchedKind = 88; + return jjMoveStringLiteralDfa1_0(0x0L, 0x1000L); + case 62: + jjmatchedKind = 74; + return jjMoveStringLiteralDfa1_0(0x0L, 0x800L); + case 91: + return jjStopAtPos(0, 66); + case 93: + return jjStopAtPos(0, 67); + case 94: + return jjStopAtPos(0, 86); + case 97: + return jjMoveStringLiteralDfa1_0(0x84210L, 0x0L); + case 98: + return jjMoveStringLiteralDfa1_0(0x21000000L, 0x0L); + case 99: + return jjMoveStringLiteralDfa1_0(0x42108400000000L, 0x0L); + case 100: + return jjMoveStringLiteralDfa1_0(0x400000000000020L, 0x0L); + case 101: + return jjMoveStringLiteralDfa1_0(0x884210842108400L, 0x0L); + case 102: + return jjMoveStringLiteralDfa1_0(0x4210840L, 0x0L); + case 105: + return jjMoveStringLiteralDfa1_0(0x108421080000000L, 0x0L); + case 108: + return jjMoveStringLiteralDfa1_0(0x1000000000000000L, 0x0L); + case 109: + return jjMoveStringLiteralDfa1_0(0x80L, 0x0L); + case 110: + return jjMoveStringLiteralDfa1_0(0x1000L, 0x0L); + case 111: + return jjMoveStringLiteralDfa1_0(0x108420000L, 0x0L); + case 112: + return jjMoveStringLiteralDfa1_0(0x210842000000000L, 0x0L); + case 114: + return jjMoveStringLiteralDfa1_0(0x2000000000042100L, 0x0L); + case 115: + return jjMoveStringLiteralDfa1_0(0x800000L, 0x0L); + case 116: + return jjMoveStringLiteralDfa1_0(0x4210000000L, 0x0L); + case 119: + return jjMoveStringLiteralDfa1_0(0x21080000000000L, 0x0L); + case 123: + return jjStopAtPos(0, 64); + case 125: + return jjStopAtPos(0, 65); + default : + return jjMoveNfa_0(0, 0); + } +} +private int jjMoveStringLiteralDfa1_0(long active0, long active1) +{ + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(0, active0, active1); + return 1; + } + switch(curChar) + { + case 42: + if ((active1 & 0x100000L) != 0L) + return jjStopAtPos(1, 84); + break; + case 43: + if ((active1 & 0x10000L) != 0L) + return jjStopAtPos(1, 80); + break; + case 45: + if ((active1 & 0x20000L) != 0L) + return jjStopAtPos(1, 81); + break; + case 47: + if ((active1 & 0x200000L) != 0L) + return jjStopAtPos(1, 85); + break; + case 61: + if ((active1 & 0x200L) != 0L) + return jjStopAtPos(1, 73); + else if ((active1 & 0x800L) != 0L) + return jjStopAtPos(1, 75); + else if ((active1 & 0x1000L) != 0L) + return jjStopAtPos(1, 76); + else if ((active1 & 0x2000000L) != 0L) + return jjStopAtPos(1, 89); + break; + case 62: + if ((active1 & 0x2000L) != 0L) + return jjStopAtPos(1, 77); + break; + case 94: + if ((active1 & 0x800000L) != 0L) + return jjStopAtPos(1, 87); + break; + case 97: + return jjMoveStringLiteralDfa2_0(active0, 0x842000000440L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa2_0(active0, 0x2400000000042100L, active1, 0L); + case 102: + if ((active0 & 0x80000000L) != 0L) + return jjStartNfaWithStates_0(1, 31, 2); + break; + case 104: + return jjMoveStringLiteralDfa2_0(active0, 0x1080010000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa2_0(active0, 0x20000000000820L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa2_0(active0, 0x403118010L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa2_0(active0, 0x1000000000L, active1, 0L); + case 110: + if ((active0 & 0x20000000000L) != 0L) + { + jjmatchedKind = 41; + jjmatchedPos = 1; + } + return jjMoveStringLiteralDfa2_0(active0, 0x108410840004200L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa2_0(active0, 0x1042108000201080L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa2_0(active0, 0x20000L, active1, 0L); + case 113: + return jjMoveStringLiteralDfa2_0(active0, 0x200000000000L, active1, 0L); + case 114: + if ((active0 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(1, 22, 2); + return jjMoveStringLiteralDfa2_0(active0, 0x10000220000000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa2_0(active0, 0x80000L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa2_0(active0, 0x800000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa2_0(active0, 0x20000010c000000L, active1, 0L); + case 120: + return jjMoveStringLiteralDfa2_0(active0, 0x884000000000000L, active1, 0L); + case 121: + return jjMoveStringLiteralDfa2_0(active0, 0x4000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(0, active0, active1); +} +private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(0, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(1, active0, 0L); + return 2; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa3_0(active0, 0x400000000L); + case 98: + return jjMoveStringLiteralDfa3_0(active0, 0x200000000000000L); + case 99: + return jjMoveStringLiteralDfa3_0(active0, 0x2000002040000400L); + case 100: + if ((active0 & 0x200L) != 0L) + return jjStartNfaWithStates_0(2, 9, 2); + else if ((active0 & 0x800000000L) != 0L) + return jjStartNfaWithStates_0(2, 35, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x180L); + case 101: + return jjMoveStringLiteralDfa3_0(active0, 0x80030020000L); + case 103: + return jjMoveStringLiteralDfa3_0(active0, 0x10L); + case 105: + return jjMoveStringLiteralDfa3_0(active0, 0x1400000000000L); + case 108: + return jjMoveStringLiteralDfa3_0(active0, 0x40L); + case 110: + return jjMoveStringLiteralDfa3_0(active0, 0x4a108004004800L); + case 111: + return jjMoveStringLiteralDfa3_0(active0, 0x1010000001010000L); + case 112: + return jjMoveStringLiteralDfa3_0(active0, 0x104005000002000L); + case 114: + if ((active0 & 0x200000L) != 0L) + return jjStartNfaWithStates_0(2, 21, 2); + else if ((active0 & 0x400000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 58, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x840000800000L); + case 115: + return jjMoveStringLiteralDfa3_0(active0, 0x2188020L); + case 116: + if ((active0 & 0x1000L) != 0L) + return jjStartNfaWithStates_0(2, 12, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x8a0000108040000L); + case 117: + return jjMoveStringLiteralDfa3_0(active0, 0x210200000000L); + default : + break; + } + return jjStartNfa_0(1, active0, 0L); +} +private int jjMoveStringLiteralDfa3_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(1, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(2, active0, 0L); + return 3; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa4_0(active0, 0x4240060000800L); + case 99: + return jjMoveStringLiteralDfa4_0(active0, 0x5000020L); + case 101: + if ((active0 & 0x8000L) != 0L) + { + jjmatchedKind = 15; + jjmatchedPos = 3; + } + else if ((active0 & 0x200000000L) != 0L) + return jjStartNfaWithStates_0(3, 33, 2); + else if ((active0 & 0x4000000000L) != 0L) + return jjStartNfaWithStates_0(3, 38, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x88800000a980180L); + case 104: + if ((active0 & 0x400L) != 0L) + return jjStartNfaWithStates_0(3, 10, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x20000000000000L); + case 107: + return jjMoveStringLiteralDfa4_0(active0, 0x2000000000L); + case 108: + return jjMoveStringLiteralDfa4_0(active0, 0x201000000002000L); + case 109: + return jjMoveStringLiteralDfa4_0(active0, 0x10000000000L); + case 110: + if ((active0 & 0x10000000L) != 0L) + return jjStartNfaWithStates_0(3, 28, 2); + else if ((active0 & 0x80000000000L) != 0L) + return jjStartNfaWithStates_0(3, 43, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x108000000000L); + case 111: + return jjMoveStringLiteralDfa4_0(active0, 0x2000001000004010L); + case 112: + if ((active0 & 0x1000000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 60, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x100000000L); + case 114: + return jjMoveStringLiteralDfa4_0(active0, 0x20000L); + case 115: + return jjMoveStringLiteralDfa4_0(active0, 0x42000400000040L); + case 116: + return jjMoveStringLiteralDfa4_0(active0, 0x10c00000000000L); + case 117: + return jjMoveStringLiteralDfa4_0(active0, 0x100000000040000L); + case 119: + if ((active0 & 0x10000L) != 0L) + return jjStartNfaWithStates_0(3, 16, 2); + break; + default : + break; + } + return jjStartNfa_0(2, active0, 0L); +} +private int jjMoveStringLiteralDfa4_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(2, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(3, active0, 0L); + return 4; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa5_0(active0, 0x2000822000L); + case 99: + return jjMoveStringLiteralDfa5_0(active0, 0x100L); + case 101: + if ((active0 & 0x40L) != 0L) + return jjStartNfaWithStates_0(4, 6, 2); + else if ((active0 & 0x1000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 48, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x10118000000000L); + case 105: + return jjMoveStringLiteralDfa5_0(active0, 0x220c00000100000L); + case 107: + if ((active0 & 0x1000000L) != 0L) + return jjStartNfaWithStates_0(4, 24, 2); + else if ((active0 & 0x20000000L) != 0L) + return jjStartNfaWithStates_0(4, 29, 2); + break; + case 108: + if ((active0 & 0x80L) != 0L) + return jjStartNfaWithStates_0(4, 7, 2); + else if ((active0 & 0x800L) != 0L) + return jjStartNfaWithStates_0(4, 11, 2); + break; + case 109: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L); + case 110: + return jjMoveStringLiteralDfa5_0(active0, 0x84000000000000L); + case 112: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000L); + case 114: + if ((active0 & 0x8000000L) != 0L) + return jjStartNfaWithStates_0(4, 27, 2); + else if ((active0 & 0x8000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 51, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x28000010000c0030L); + case 115: + if ((active0 & 0x400000000L) != 0L) + return jjStartNfaWithStates_0(4, 34, 2); + break; + case 116: + if ((active0 & 0x100000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 56, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x42200004004000L); + case 117: + return jjMoveStringLiteralDfa5_0(active0, 0x100000000L); + case 119: + return jjMoveStringLiteralDfa5_0(active0, 0x2000000L); + default : + break; + } + return jjStartNfa_0(3, active0, 0L); +} +private int jjMoveStringLiteralDfa5_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(3, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(4, active0, 0L); + return 5; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa6_0(active0, 0x2c00000004000L); + case 99: + if ((active0 & 0x200000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 57, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x10108000002000L); + case 100: + if ((active0 & 0x2000000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 61, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x84000000000000L); + case 101: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000020L); + case 102: + if ((active0 & 0x100000L) != 0L) + return jjStartNfaWithStates_0(5, 20, 2); + break; + case 103: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000000L); + case 104: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000L); + case 105: + return jjMoveStringLiteralDfa6_0(active0, 0x200004000010L); + case 108: + return jjMoveStringLiteralDfa6_0(active0, 0x100L); + case 109: + if ((active0 & 0x800000L) != 0L) + return jjStartNfaWithStates_0(5, 23, 2); + break; + case 110: + if ((active0 & 0x40000L) != 0L) + return jjStartNfaWithStates_0(5, 18, 2); + else if ((active0 & 0x20000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 53, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x800000000000000L); + case 114: + return jjMoveStringLiteralDfa6_0(active0, 0x40010000000000L); + case 115: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000L); + case 116: + if ((active0 & 0x80000L) != 0L) + return jjStartNfaWithStates_0(5, 19, 2); + else if ((active0 & 0x100000000L) != 0L) + return jjStartNfaWithStates_0(5, 32, 2); + else if ((active0 & 0x1000000000L) != 0L) + return jjStartNfaWithStates_0(5, 36, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x20000L); + default : + break; + } + return jjStartNfa_0(4, active0, 0L); +} +private int jjMoveStringLiteralDfa6_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(4, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(5, active0, 0L); + return 6; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa7_0(active0, 0x844010000000100L); + case 101: + if ((active0 & 0x2000000000L) != 0L) + return jjStartNfaWithStates_0(6, 37, 2); + return jjMoveStringLiteralDfa7_0(active0, 0x2002000L); + case 108: + if ((active0 & 0x400000000000L) != 0L) + return jjStartNfaWithStates_0(6, 46, 2); + else if ((active0 & 0x800000000000L) != 0L) + return jjStartNfaWithStates_0(6, 47, 2); + break; + case 110: + return jjMoveStringLiteralDfa7_0(active0, 0x2000000000000L); + case 111: + return jjMoveStringLiteralDfa7_0(active0, 0x200004020000L); + case 115: + if ((active0 & 0x80000000000000L) != 0L) + return jjStartNfaWithStates_0(6, 55, 2); + break; + case 116: + if ((active0 & 0x8000000000L) != 0L) + { + jjmatchedKind = 39; + jjmatchedPos = 6; + } + return jjMoveStringLiteralDfa7_0(active0, 0x10140000004030L); + case 117: + return jjMoveStringLiteralDfa7_0(active0, 0x40000000L); + default : + break; + } + return jjStartNfa_0(5, active0, 0L); +} +private int jjMoveStringLiteralDfa7_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(5, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(6, active0, 0L); + return 7; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa8_0(active0, 0x2000L); + case 98: + return jjMoveStringLiteralDfa8_0(active0, 0x4000000000000L); + case 101: + if ((active0 & 0x20L) != 0L) + return jjStartNfaWithStates_0(7, 5, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x10040000000000L); + case 104: + return jjMoveStringLiteralDfa8_0(active0, 0x10L); + case 105: + return jjMoveStringLiteralDfa8_0(active0, 0x40000000004000L); + case 108: + if ((active0 & 0x800000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 59, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x40000000L); + case 110: + if ((active0 & 0x2000000L) != 0L) + return jjStartNfaWithStates_0(7, 25, 2); + else if ((active0 & 0x4000000L) != 0L) + return jjStartNfaWithStates_0(7, 26, 2); + else if ((active0 & 0x200000000000L) != 0L) + return jjStartNfaWithStates_0(7, 45, 2); + break; + case 111: + return jjMoveStringLiteralDfa8_0(active0, 0x100000000000L); + case 114: + if ((active0 & 0x20000L) != 0L) + return jjStartNfaWithStates_0(7, 17, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x100L); + case 116: + if ((active0 & 0x2000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 49, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x10000000000L); + default : + break; + } + return jjStartNfa_0(6, active0, 0L); +} +private int jjMoveStringLiteralDfa8_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(6, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(7, active0, 0L); + return 8; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa9_0(active0, 0x40000000L); + case 98: + return jjMoveStringLiteralDfa9_0(active0, 0x2000L); + case 100: + if ((active0 & 0x10000000000000L) != 0L) + return jjStartNfaWithStates_0(8, 52, 2); + break; + case 101: + if ((active0 & 0x100L) != 0L) + return jjStartNfaWithStates_0(8, 8, 2); + break; + case 105: + return jjMoveStringLiteralDfa9_0(active0, 0x10000000000L); + case 108: + return jjMoveStringLiteralDfa9_0(active0, 0x4000000000000L); + case 109: + if ((active0 & 0x10L) != 0L) + return jjStartNfaWithStates_0(8, 4, 2); + break; + case 110: + return jjMoveStringLiteralDfa9_0(active0, 0x40000000000000L); + case 111: + return jjMoveStringLiteralDfa9_0(active0, 0x4000L); + case 114: + if ((active0 & 0x40000000000L) != 0L) + return jjStartNfaWithStates_0(8, 42, 2); + else if ((active0 & 0x100000000000L) != 0L) + return jjStartNfaWithStates_0(8, 44, 2); + break; + default : + break; + } + return jjStartNfa_0(7, active0, 0L); +} +private int jjMoveStringLiteralDfa9_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(7, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(8, active0, 0L); + return 9; + } + switch(curChar) + { + case 101: + if ((active0 & 0x4000000000000L) != 0L) + return jjStartNfaWithStates_0(9, 50, 2); + return jjMoveStringLiteralDfa10_0(active0, 0x40000000000000L); + case 108: + return jjMoveStringLiteralDfa10_0(active0, 0x2000L); + case 110: + if ((active0 & 0x4000L) != 0L) + return jjStartNfaWithStates_0(9, 14, 2); + break; + case 111: + return jjMoveStringLiteralDfa10_0(active0, 0x10000000000L); + case 116: + return jjMoveStringLiteralDfa10_0(active0, 0x40000000L); + default : + break; + } + return jjStartNfa_0(8, active0, 0L); +} +private int jjMoveStringLiteralDfa10_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(8, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(9, active0, 0L); + return 10; + } + switch(curChar) + { + case 100: + return jjMoveStringLiteralDfa11_0(active0, 0x40000000000000L); + case 101: + if ((active0 & 0x2000L) != 0L) + return jjStartNfaWithStates_0(10, 13, 2); + return jjMoveStringLiteralDfa11_0(active0, 0x40000000L); + case 110: + if ((active0 & 0x10000000000L) != 0L) + return jjStartNfaWithStates_0(10, 40, 2); + break; + default : + break; + } + return jjStartNfa_0(9, active0, 0L); +} +private int jjMoveStringLiteralDfa11_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(9, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(10, active0, 0L); + return 11; + } + switch(curChar) + { + case 98: + return jjMoveStringLiteralDfa12_0(active0, 0x40000000000000L); + case 100: + if ((active0 & 0x40000000L) != 0L) + return jjStartNfaWithStates_0(11, 30, 2); + break; + default : + break; + } + return jjStartNfa_0(10, active0, 0L); +} +private int jjMoveStringLiteralDfa12_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(10, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(11, active0, 0L); + return 12; + } + switch(curChar) + { + case 121: + if ((active0 & 0x40000000000000L) != 0L) + return jjStartNfaWithStates_0(12, 54, 2); + break; + default : + break; + } + return jjStartNfa_0(11, active0, 0L); +} +private int jjStartNfaWithStates_0(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_0(state, pos + 1); +} +static final long[] jjbitVec0 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +private int jjMoveNfa_0(int startState, int curPos) +{ + int startsAt = 0; + jjnewStateCnt = 46; + int i = 1; + jjstateSet[0] = startState; + int kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + do + { + switch(jjstateSet[--i]) + { + case 24: + if (curChar == 47) + { + if (kind > 3) + kind = 3; + jjCheckNAdd(31); + } + else if (curChar == 42) + jjCheckNAddStates(0, 2); + break; + case 46: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 94) + kind = 94; + jjCheckNAddTwoStates(10, 11); + } + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(43, 44); + } + break; + case 9: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 94) + kind = 94; + jjCheckNAddStates(3, 7); + } + else if (curChar == 46) + jjCheckNAdd(10); + break; + case 0: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 92) + kind = 92; + jjCheckNAddStates(8, 17); + } + else if ((0x100002600L & l) != 0L) + { + if (kind > 1) + kind = 1; + } + else if (curChar == 46) + jjCheckNAddTwoStates(43, 10); + else if (curChar == 47) + jjAddStates(18, 19); + else if (curChar == 45) + jjAddStates(20, 21); + else if (curChar == 34) + jjCheckNAddStates(22, 24); + break; + case 2: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjstateSet[jjnewStateCnt++] = 2; + break; + case 3: + if (curChar == 34) + jjCheckNAddStates(22, 24); + break; + case 4: + if ((0xfffffffbfffffbffL & l) != 0L) + jjCheckNAddStates(22, 24); + break; + case 6: + if ((0xfffffffffffffbffL & l) != 0L) + jjCheckNAddStates(22, 24); + break; + case 7: + if (curChar == 34 && kind > 91) + kind = 91; + break; + case 8: + if (curChar == 45) + jjAddStates(20, 21); + break; + case 10: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 94) + kind = 94; + jjCheckNAddTwoStates(10, 11); + break; + case 12: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 94) + kind = 94; + jjstateSet[jjnewStateCnt++] = 12; + break; + case 13: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 94) + kind = 94; + jjCheckNAddStates(3, 7); + break; + case 14: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 94) + kind = 94; + jjCheckNAdd(14); + break; + case 15: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(15, 16); + break; + case 17: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 94) + kind = 94; + jjstateSet[jjnewStateCnt++] = 17; + break; + case 18: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(18, 19); + break; + case 19: + if (curChar != 46) + break; + if (kind > 94) + kind = 94; + jjCheckNAddTwoStates(20, 21); + break; + case 20: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 94) + kind = 94; + jjCheckNAddTwoStates(20, 21); + break; + case 22: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 94) + kind = 94; + jjstateSet[jjnewStateCnt++] = 22; + break; + case 23: + if (curChar == 47) + jjAddStates(18, 19); + break; + case 25: + if ((0xfffffbffffffffffL & l) != 0L) + jjCheckNAddStates(0, 2); + break; + case 26: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 27; + break; + case 27: + if ((0xffff7fffffffffffL & l) != 0L) + jjCheckNAddStates(0, 2); + break; + case 28: + if (curChar == 47 && kind > 2) + kind = 2; + break; + case 29: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 28; + break; + case 30: + if (curChar != 47) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(31); + break; + case 31: + if ((0xfffffffffffffbffL & l) == 0L) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(31); + break; + case 32: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjCheckNAddStates(8, 17); + break; + case 33: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 92) + kind = 92; + jjCheckNAdd(33); + break; + case 34: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(34, 35); + break; + case 35: + if (curChar != 46) + break; + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(36, 37); + break; + case 36: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(36, 37); + break; + case 38: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjstateSet[jjnewStateCnt++] = 38; + break; + case 39: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(39, 40); + break; + case 41: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjstateSet[jjnewStateCnt++] = 41; + break; + case 42: + if (curChar == 46) + jjCheckNAddTwoStates(43, 10); + break; + case 43: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjCheckNAddTwoStates(43, 44); + break; + case 45: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 93) + kind = 93; + jjstateSet[jjnewStateCnt++] = 45; + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 0: + case 2: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjCheckNAdd(2); + break; + case 4: + if ((0xffffffffefffffffL & l) != 0L) + jjCheckNAddStates(22, 24); + break; + case 5: + if (curChar == 92) + jjstateSet[jjnewStateCnt++] = 6; + break; + case 6: + jjCheckNAddStates(22, 24); + break; + case 11: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 12; + break; + case 16: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 17; + break; + case 21: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 22; + break; + case 25: + case 27: + jjCheckNAddStates(0, 2); + break; + case 31: + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 31; + break; + case 37: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 38; + break; + case 40: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 41; + break; + case 44: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 45; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 4: + case 6: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddStates(22, 24); + break; + case 25: + case 27: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddStates(0, 2); + break; + case 31: + if ((jjbitVec0[i2] & l2) == 0L) + break; + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 31; + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 46 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +static final int[] jjnextStates = { + 25, 26, 29, 14, 15, 16, 18, 19, 33, 34, 35, 39, 40, 14, 15, 16, + 18, 19, 24, 30, 9, 13, 4, 5, 7, +}; + +/** Token literal values. */ +public static final String[] jjstrLiteralImages = { +"", null, null, null, "\141\154\147\157\162\151\164\150\155", +"\144\151\163\143\162\145\164\145", "\146\141\154\163\145", "\155\157\144\145\154", +"\162\145\144\145\143\154\141\162\145", "\141\156\144", "\145\141\143\150", "\146\151\156\141\154", "\156\157\164", +"\162\145\160\154\141\143\145\141\142\154\145", "\141\156\156\157\164\141\164\151\157\156", "\145\154\163\145", +"\146\154\157\167", "\157\160\145\162\141\164\157\162", "\162\145\164\165\162\156", +"\141\163\163\145\162\164", "\145\154\163\145\151\146", "\146\157\162", "\157\162", +"\163\164\162\145\141\155", "\142\154\157\143\153", "\145\154\163\145\167\150\145\156", +"\146\165\156\143\164\151\157\156", "\157\165\164\145\162", "\164\150\145\156", "\142\162\145\141\153", +"\145\156\143\141\160\163\165\154\141\164\145\144", "\151\146", "\157\165\164\160\165\164", "\164\162\165\145", +"\143\154\141\163\163", "\145\156\144", "\151\155\160\157\162\164", "\160\141\143\153\141\147\145", +"\164\171\160\145", "\143\157\156\156\145\143\164", +"\145\156\165\155\145\162\141\164\151\157\156", "\151\156", "\160\141\162\141\155\145\164\145\162", "\167\150\145\156", +"\143\157\156\156\145\143\164\157\162", "\145\161\165\141\164\151\157\156", "\151\156\151\164\151\141\154", +"\160\141\162\164\151\141\154", "\167\150\151\154\145", "\143\157\156\163\164\141\156\164", +"\145\170\160\141\156\144\141\142\154\145", "\151\156\156\145\162", "\160\162\157\164\145\143\164\145\144", +"\167\151\164\150\151\156", "\143\157\156\163\164\162\141\151\156\145\144\142\171", +"\145\170\164\145\156\144\163", "\151\156\160\165\164", "\160\165\142\154\151\143", "\144\145\162", +"\145\170\164\145\162\156\141\154", "\154\157\157\160", "\162\145\143\157\162\144", "\50", "\51", "\173", "\175", +"\133", "\135", "\56", "\72", "\73", "\54", "\74", "\74\75", "\76", "\76\75", +"\75\75", "\74\76", "\53", "\55", "\56\53", "\56\55", "\52", "\57", "\56\52", "\56\57", +"\136", "\56\136", "\75", "\72\75", null, null, null, null, null, }; + +/** Lexer state names. */ +public static final String[] lexStateNames = { + "DEFAULT", +}; +static final long[] jjtoToken = { + 0xfffffffffffffff1L, 0x7fffffffL, +}; +static final long[] jjtoSkip = { + 0xeL, 0x0L, +}; +protected SimpleCharStream input_stream; +private final int[] jjrounds = new int[46]; +private final int[] jjstateSet = new int[92]; +private final StringBuilder jjimage = new StringBuilder(); +private StringBuilder image = jjimage; +private int jjimageLen; +private int lengthOfMatch; +protected char curChar; +/** Constructor. */ +public TableParserTokenManager(SimpleCharStream stream){ + if (SimpleCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + input_stream = stream; +} + +/** Constructor. */ +public TableParserTokenManager(SimpleCharStream stream, int lexState){ + this(stream); + SwitchTo(lexState); +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream) +{ + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); +} +private void ReInitRounds() +{ + int i; + jjround = 0x80000001; + for (i = 46; i-- > 0;) + jjrounds[i] = 0x80000000; +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream, int lexState) +{ + ReInit(stream); + SwitchTo(lexState); +} + +/** Switch to specified lex state. */ +public void SwitchTo(int lexState) +{ + if (lexState >= 1 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); + else + curLexState = lexState; +} + +protected Token jjFillToken() +{ + final Token t; + final String curTokenImage; + final int beginLine; + final int endLine; + final int beginColumn; + final int endColumn; + String im = jjstrLiteralImages[jjmatchedKind]; + curTokenImage = (im == null) ? input_stream.GetImage() : im; + beginLine = input_stream.getBeginLine(); + beginColumn = input_stream.getBeginColumn(); + endLine = input_stream.getEndLine(); + endColumn = input_stream.getEndColumn(); + t = Token.newToken(jjmatchedKind, curTokenImage); + + t.beginLine = beginLine; + t.endLine = endLine; + t.beginColumn = beginColumn; + t.endColumn = endColumn; + + return t; +} + +int curLexState = 0; +int defaultLexState = 0; +int jjnewStateCnt; +int jjround; +int jjmatchedPos; +int jjmatchedKind; + +/** Get the next Token. */ +public Token getNextToken() +{ + Token matchedToken; + int curPos = 0; + + EOFLoop : + for (;;) + { + try + { + curChar = input_stream.BeginToken(); + } + catch(java.io.IOException e) + { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + } + image = jjimage; + image.setLength(0); + jjimageLen = 0; + + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + if (jjmatchedKind != 0x7fffffff) + { + if (jjmatchedPos + 1 < curPos) + input_stream.backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) + { + matchedToken = jjFillToken(); + TokenLexicalActions(matchedToken); + return matchedToken; + } + else + { + continue EOFLoop; + } + } + int error_line = input_stream.getEndLine(); + int error_column = input_stream.getEndColumn(); + String error_after = null; + boolean EOFSeen = false; + try { input_stream.readChar(); input_stream.backup(1); } + catch (java.io.IOException e1) { + EOFSeen = true; + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + if (curChar == '\n' || curChar == '\r') { + error_line++; + error_column = 0; + } + else + error_column++; + } + if (!EOFSeen) { + input_stream.backup(1); + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + } + throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); + } +} + +void TokenLexicalActions(Token matchedToken) +{ + switch(jjmatchedKind) + { + case 91 : + image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); + matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); + break; + default : + break; + } +} +private void jjCheckNAdd(int state) +{ + if (jjrounds[state] != jjround) + { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } +} +private void jjAddStates(int start, int end) +{ + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); +} +private void jjCheckNAddTwoStates(int state1, int state2) +{ + jjCheckNAdd(state1); + jjCheckNAdd(state2); +} + +private void jjCheckNAddStates(int start, int end) +{ + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); +} + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/Token.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/Token.java new file mode 100644 index 00000000..e5636f30 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/Token.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */ +/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package org.simantics.sysdyn.tableParser; + +/** + * Describes the input token stream. + */ + +public class Token implements java.io.Serializable { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** The line number of the first character of this Token. */ + public int beginLine; + /** The column number of the first character of this Token. */ + public int beginColumn; + /** The line number of the last character of this Token. */ + public int endLine; + /** The column number of the last character of this Token. */ + public int endColumn; + + /** + * The string image of the token. + */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** + * An optional attribute value of the Token. + * Tokens which are not used as syntactic sugar will often contain + * meaningful values that will be used later on by the compiler or + * interpreter. This attribute value is often different from the image. + * Any subclass of Token that actually wants to return a non-null value can + * override this method as appropriate. + */ + public Object getValue() { + return null; + } + + /** + * No-argument constructor + */ + public Token() {} + + /** + * Constructs a new token for the specified Image. + */ + public Token(int kind) + { + this(kind, null); + } + + /** + * Constructs a new token for the specified Image and Kind. + */ + public Token(int kind, String image) + { + this.kind = kind; + this.image = image; + } + + /** + * Returns the image. + */ + public String toString() + { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simply add something like : + * + * case MyParserConstants.ID : return new IDToken(ofKind, image); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use sit in your lexical actions. + */ + public static Token newToken(int ofKind, String image) + { + switch(ofKind) + { + default : return new Token(ofKind, image); + } + } + + public static Token newToken(int ofKind) + { + return newToken(ofKind, null); + } + +} +/* JavaCC - OriginalChecksum=d63d0e2011f8ce7fbf4f8ee6fd4e3986 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TokenMgrError.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TokenMgrError.java new file mode 100644 index 00000000..49dbdbf9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/tableParser/TokenMgrError.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */ +/* JavaCCOptions: */ +package org.simantics.sysdyn.tableParser; + +/** Token Manager Error. */ +public class TokenMgrError extends Error +{ + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** + * Lexical error occurred. + */ + static final int LEXICAL_ERROR = 0; + + /** + * An attempt was made to create a second instance of a static token manager. + */ + static final int STATIC_LEXER_ERROR = 1; + + /** + * Tried to change to an invalid lexical state. + */ + static final int INVALID_LEXICAL_STATE = 2; + + /** + * Detected (and bailed out of) an infinite loop in the token manager. + */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + + /** + * Replaces unprintable characters by their escaped (or unicode escaped) + * equivalents in the given string + */ + protected static final String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + + /** + * Returns a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + * Parameters : + * EOFSeen : indicates if EOF caused the lexical error + * curLexState : lexical state in which this error occurred + * errorLine : line number when the error occurred + * errorColumn : column number when the error occurred + * errorAfter : prefix that was seen before this error occurred + * curchar : the offending character + * Note: You can customize the lexical error message by modifying this method. + */ + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { + return("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * + * "Internal Error : Please file a bug report .... " + * + * from this method for such cases in the release version of your parser. + */ + public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + /** No arg constructor. */ + public TokenMgrError() { + } + + /** Constructor with message and reason. */ + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + /** Full Constructor. */ + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); + } +} +/* JavaCC - OriginalChecksum=abb0cd060e347479552118d1e61a7e46 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/JJTUnitParserState.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/JJTUnitParserState.java new file mode 100644 index 00000000..9988da3e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/JJTUnitParserState.java @@ -0,0 +1,123 @@ +/* Generated By:JavaCC: Do not edit this line. JJTUnitParserState.java Version 5.0 */ +package org.simantics.sysdyn.unitParser; + +public class JJTUnitParserState { + private java.util.List nodes; + private java.util.List marks; + + private int sp; // number of nodes on stack + private int mk; // current mark + private boolean node_created; + + public JJTUnitParserState() { + nodes = new java.util.ArrayList(); + marks = new java.util.ArrayList(); + sp = 0; + mk = 0; + } + + /* Determines whether the current node was actually closed and + pushed. This should only be called in the final user action of a + node scope. */ + public boolean nodeCreated() { + return node_created; + } + + /* Call this to reinitialize the node stack. It is called + automatically by the parser's ReInit() method. */ + public void reset() { + nodes.clear(); + marks.clear(); + sp = 0; + mk = 0; + } + + /* Returns the root node of the AST. It only makes sense to call + this after a successful parse. */ + public Node rootNode() { + return nodes.get(0); + } + + /* Pushes a node on to the stack. */ + public void pushNode(Node n) { + nodes.add(n); + ++sp; + } + + /* Returns the node on the top of the stack, and remove it from the + stack. */ + public Node popNode() { + if (--sp < mk) { + mk = marks.remove(marks.size()-1); + } + return nodes.remove(nodes.size()-1); + } + + /* Returns the node currently on the top of the stack. */ + public Node peekNode() { + return nodes.get(nodes.size()-1); + } + + /* Returns the number of children on the stack in the current node + scope. */ + public int nodeArity() { + return sp - mk; + } + + + public void clearNodeScope(Node n) { + while (sp > mk) { + popNode(); + } + mk = marks.remove(marks.size()-1); + } + + + public void openNodeScope(Node n) { + marks.add(mk); + mk = sp; + n.jjtOpen(); + } + + + /* A definite node is constructed from a specified number of + children. That number of nodes are popped from the stack and + made the children of the definite node. Then the definite node + is pushed on to the stack. */ + public void closeNodeScope(Node n, int num) { + mk = marks.remove(marks.size()-1); + while (num-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, num); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } + + + /* A conditional node is constructed if its condition is true. All + the nodes that have been pushed since the node was opened are + made children of the conditional node, which is then pushed + on to the stack. If the condition is false the node is not + constructed and they are left on the stack. */ + public void closeNodeScope(Node n, boolean condition) { + if (condition) { + int a = nodeArity(); + mk = marks.remove(marks.size()-1); + while (a-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, a); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } else { + mk = marks.remove(marks.size()-1); + node_created = false; + } + } +} +/* JavaCC - OriginalChecksum=d0c8ac05372006e3b61e33c0a234ef07 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/Node.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/Node.java new file mode 100644 index 00000000..bb89e6ac --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/Node.java @@ -0,0 +1,36 @@ +/* Generated By:JJTree: Do not edit this line. Node.java Version 4.3 */ +/* JavaCCOptions:MULTI=false,NODE_USES_PARSER=false,VISITOR=false,TRACK_TOKENS=true,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=UnitCheckingNodeFactory,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package org.simantics.sysdyn.unitParser; + +/* All AST nodes must implement this interface. It provides basic + machinery for constructing the parent and child relationships + between nodes. */ + +public +interface Node { + + /** This method is called after the node has been made the current + node. It indicates that child nodes can now be added to it. */ + public void jjtOpen(); + + /** This method is called after all the child nodes have been + added. */ + public void jjtClose(); + + /** This pair of methods are used to inform the node of its + parent. */ + public void jjtSetParent(Node n); + public Node jjtGetParent(); + + /** This method tells the node to add its argument to the node's + list of children. */ + public void jjtAddChild(Node n, int i); + + /** This method returns a child node. The children are numbered + from zero, left to right. */ + public Node jjtGetChild(int i); + + /** Return the number of children the node has. */ + public int jjtGetNumChildren(); +} +/* JavaCC - OriginalChecksum=851e4a7b403fad4367cc9f6859ec9c32 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/ParseException.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/ParseException.java new file mode 100644 index 00000000..fa6de90b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/ParseException.java @@ -0,0 +1,187 @@ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */ +/* JavaCCOptions:KEEP_LINE_COL=null */ +package org.simantics.sysdyn.unitParser; + +/** + * This exception is thrown when parse errors are encountered. + * You can explicitly create objects of this exception type by + * calling the method generateParseException in the generated + * parser. + * + * You can modify this class to customize your error reporting + * mechanisms so long as you retain the public fields. + */ +public class ParseException extends Exception { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * This constructor is used by the method "generateParseException" + * in the generated parser. Calling this constructor generates + * a new object of this type with the fields "currentToken", + * "expectedTokenSequences", and "tokenImage" set. + */ + public ParseException(Token currentTokenVal, + int[][] expectedTokenSequencesVal, + String[] tokenImageVal + ) + { + super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal)); + currentToken = currentTokenVal; + expectedTokenSequences = expectedTokenSequencesVal; + tokenImage = tokenImageVal; + } + + /** + * The following constructors are for use by you for whatever + * purpose you can think of. Constructing the exception in this + * manner makes the exception behave in the normal way - i.e., as + * documented in the class "Throwable". The fields "errorToken", + * "expectedTokenSequences", and "tokenImage" do not contain + * relevant information. The JavaCC generated code does not use + * these constructors. + */ + + public ParseException() { + super(); + } + + /** Constructor with message. */ + public ParseException(String message) { + super(message); + } + + + /** + * This is the last token that has been consumed successfully. If + * this object has been created due to a parse error, the token + * followng this token will (therefore) be the first error token. + */ + public Token currentToken; + + /** + * Each entry in this array is an array of integers. Each array + * of integers represents a sequence of tokens (by their ordinal + * values) that is expected at this point of the parse. + */ + public int[][] expectedTokenSequences; + + /** + * This is a reference to the "tokenImage" array of the generated + * parser within which the parse error occurred. This array is + * defined in the generated ...Constants interface. + */ + public String[] tokenImage; + + /** + * It uses "currentToken" and "expectedTokenSequences" to generate a parse + * error message and returns it. If this object has been created + * due to a parse error, and you do not catch it (it gets thrown + * from the parser) the correct error message + * gets displayed. + */ + private static String initialise(Token currentToken, + int[][] expectedTokenSequences, + String[] tokenImage) { + String eol = System.getProperty("line.separator", "\n"); + StringBuffer expected = new StringBuffer(); + int maxSize = 0; + for (int i = 0; i < expectedTokenSequences.length; i++) { + if (maxSize < expectedTokenSequences[i].length) { + maxSize = expectedTokenSequences[i].length; + } + for (int j = 0; j < expectedTokenSequences[i].length; j++) { + expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' '); + } + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + expected.append("..."); + } + expected.append(eol).append(" "); + } + String retval = "Encountered \""; + Token tok = currentToken.next; + for (int i = 0; i < maxSize; i++) { + if (i != 0) retval += " "; + if (tok.kind == 0) { + retval += tokenImage[0]; + break; + } + retval += " " + tokenImage[tok.kind]; + retval += " \""; + retval += add_escapes(tok.image); + retval += " \""; + tok = tok.next; + } + retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; + retval += "." + eol; + if (expectedTokenSequences.length == 1) { + retval += "Was expecting:" + eol + " "; + } else { + retval += "Was expecting one of:" + eol + " "; + } + retval += expected.toString(); + return retval; + } + + /** + * The end of line string for this machine. + */ + protected String eol = System.getProperty("line.separator", "\n"); + + /** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal. + */ + static String add_escapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + +} +/* JavaCC - OriginalChecksum=4af9901dc6c68e7e4e08ab85f10baa96 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/SimpleCharStream.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/SimpleCharStream.java new file mode 100644 index 00000000..a7b4b80b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/SimpleCharStream.java @@ -0,0 +1,471 @@ +/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */ +/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package org.simantics.sysdyn.unitParser; + +/** + * An implementation of interface CharStream, where the stream is assumed to + * contain only ASCII characters (without unicode processing). + */ + +public class SimpleCharStream +{ +/** Whether parser is static. */ + public static final boolean staticFlag = false; + int bufsize; + int available; + int tokenBegin; +/** Position in buffer. */ + public int bufpos = -1; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int inBuf = 0; + protected int tabSize = 8; + + protected void setTabSize(int i) { tabSize = i; } + protected int getTabSize(int i) { return tabSize; } + + + protected void ExpandBuff(boolean wrapAround) + { + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try + { + if (wrapAround) + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos += (bufsize - tokenBegin)); + } + else + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos -= tokenBegin); + } + } + catch (Throwable t) + { + throw new Error(t.getMessage()); + } + + + bufsize += 2048; + available = bufsize; + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException + { + if (maxNextCharInd == available) + { + if (available == bufsize) + { + if (tokenBegin > 2048) + { + bufpos = maxNextCharInd = 0; + available = tokenBegin; + } + else if (tokenBegin < 0) + bufpos = maxNextCharInd = 0; + else + ExpandBuff(false); + } + else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + int i; + try { + if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1) + { + inputStream.close(); + throw new java.io.IOException(); + } + else + maxNextCharInd += i; + return; + } + catch(java.io.IOException e) { + --bufpos; + backup(0); + if (tokenBegin == -1) + tokenBegin = bufpos; + throw e; + } + } + +/** Start. */ + public char BeginToken() throws java.io.IOException + { + tokenBegin = -1; + char c = readChar(); + tokenBegin = bufpos; + + return c; + } + + protected void UpdateLineColumn(char c) + { + column++; + + if (prevCharIsLF) + { + prevCharIsLF = false; + line += (column = 1); + } + else if (prevCharIsCR) + { + prevCharIsCR = false; + if (c == '\n') + { + prevCharIsLF = true; + } + else + line += (column = 1); + } + + switch (c) + { + case '\r' : + prevCharIsCR = true; + break; + case '\n' : + prevCharIsLF = true; + break; + case '\t' : + column--; + column += (tabSize - (column % tabSize)); + break; + default : + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + +/** Read a character. */ + public char readChar() throws java.io.IOException + { + if (inBuf > 0) + { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + if (++bufpos >= maxNextCharInd) + FillBuff(); + + char c = buffer[bufpos]; + + UpdateLineColumn(c); + return c; + } + + @Deprecated + /** + * @deprecated + * @see #getEndColumn + */ + + public int getColumn() { + return bufcolumn[bufpos]; + } + + @Deprecated + /** + * @deprecated + * @see #getEndLine + */ + + public int getLine() { + return bufline[bufpos]; + } + + /** Get token end column number. */ + public int getEndColumn() { + return bufcolumn[bufpos]; + } + + /** Get token end line number. */ + public int getEndLine() { + return bufline[bufpos]; + } + + /** Get token beginning column number. */ + public int getBeginColumn() { + return bufcolumn[tokenBegin]; + } + + /** Get token beginning line number. */ + public int getBeginLine() { + return bufline[tokenBegin]; + } + +/** Backup a number of characters. */ + public void backup(int amount) { + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.Reader dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length) + { + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + bufpos = -1; + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, 1, 1, 4096); + } + + /** Constructor. */ + public SimpleCharStream(java.io.InputStream dstream) + { + this(dstream, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, 1, 1, 4096); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream) + { + ReInit(dstream, 1, 1, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, startline, startcolumn, 4096); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + /** Get token literal value. */ + public String GetImage() + { + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + else + return new String(buffer, tokenBegin, bufsize - tokenBegin) + + new String(buffer, 0, bufpos + 1); + } + + /** Get the suffix. */ + public char[] GetSuffix(int len) + { + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else + { + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, + len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + /** Reset buffer when finished. */ + public void Done() + { + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + */ + public void adjustBeginLineColumn(int newLine, int newCol) + { + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin) + { + len = bufpos - tokenBegin + inBuf + 1; + } + else + { + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k = 0; + int nextColDiff = 0, columnDiff = 0; + + while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) + { + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len) + { + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while (i++ < len) + { + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + +} +/* JavaCC - OriginalChecksum=e3053baa4fc0756909ee8daa9c548c97 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/SimpleNode.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/SimpleNode.java new file mode 100644 index 00000000..0eab39ad --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/SimpleNode.java @@ -0,0 +1,94 @@ +/* Generated By:JJTree: Do not edit this line. SimpleNode.java Version 4.3 */ +/* JavaCCOptions:MULTI=false,NODE_USES_PARSER=false,VISITOR=false,TRACK_TOKENS=true,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=UnitCheckingNodeFactory,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package org.simantics.sysdyn.unitParser; + +public +class SimpleNode implements Node { + + protected Node parent; + protected Node[] children; + protected int id; + protected Object value; + protected UnitParser parser; + protected Token firstToken; + protected Token lastToken; + + public SimpleNode(int i) { + id = i; + } + + public SimpleNode(UnitParser p, int i) { + this(i); + parser = p; + } + + public static Node jjtCreate(int id) { + return new SimpleNode(id); + } + + public static Node jjtCreate(UnitParser p, int id) { + return new SimpleNode(p, id); + } + + public void jjtOpen() { + } + + public void jjtClose() { + } + + public void jjtSetParent(Node n) { parent = n; } + public Node jjtGetParent() { return parent; } + + public void jjtAddChild(Node n, int i) { + if (children == null) { + children = new Node[i + 1]; + } else if (i >= children.length) { + Node c[] = new Node[i + 1]; + System.arraycopy(children, 0, c, 0, children.length); + children = c; + } + children[i] = n; + } + + public Node jjtGetChild(int i) { + return children[i]; + } + + public int jjtGetNumChildren() { + return (children == null) ? 0 : children.length; + } + + public void jjtSetValue(Object value) { this.value = value; } + public Object jjtGetValue() { return value; } + + public Token jjtGetFirstToken() { return firstToken; } + public void jjtSetFirstToken(Token token) { this.firstToken = token; } + public Token jjtGetLastToken() { return lastToken; } + public void jjtSetLastToken(Token token) { this.lastToken = token; } + + /* You can override these two methods in subclasses of SimpleNode to + customize the way the node appears when the tree is dumped. If + your output uses more than one line you should override + toString(String), otherwise overriding toString() is probably all + you need to do. */ + + public String toString() { return UnitParserTreeConstants.jjtNodeName[id]; } + public String toString(String prefix) { return prefix + toString(); } + + /* Override this method if you want to customize how the node dumps + out its children. */ + + public void dump(String prefix) { + System.out.println(toString(prefix)); + if (children != null) { + for (int i = 0; i < children.length; ++i) { + SimpleNode n = (SimpleNode)children[i]; + if (n != null) { + n.dump(prefix + " "); + } + } + } + } +} + +/* JavaCC - OriginalChecksum=97c0294de1ef3976f0b09baf888d3564 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/Token.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/Token.java new file mode 100644 index 00000000..7e6124ee --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/Token.java @@ -0,0 +1,131 @@ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */ +/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package org.simantics.sysdyn.unitParser; + +/** + * Describes the input token stream. + */ + +public class Token implements java.io.Serializable { + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** The line number of the first character of this Token. */ + public int beginLine; + /** The column number of the first character of this Token. */ + public int beginColumn; + /** The line number of the last character of this Token. */ + public int endLine; + /** The column number of the last character of this Token. */ + public int endColumn; + + /** + * The string image of the token. + */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** + * An optional attribute value of the Token. + * Tokens which are not used as syntactic sugar will often contain + * meaningful values that will be used later on by the compiler or + * interpreter. This attribute value is often different from the image. + * Any subclass of Token that actually wants to return a non-null value can + * override this method as appropriate. + */ + public Object getValue() { + return null; + } + + /** + * No-argument constructor + */ + public Token() {} + + /** + * Constructs a new token for the specified Image. + */ + public Token(int kind) + { + this(kind, null); + } + + /** + * Constructs a new token for the specified Image and Kind. + */ + public Token(int kind, String image) + { + this.kind = kind; + this.image = image; + } + + /** + * Returns the image. + */ + public String toString() + { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simply add something like : + * + * case MyParserConstants.ID : return new IDToken(ofKind, image); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use sit in your lexical actions. + */ + public static Token newToken(int ofKind, String image) + { + switch(ofKind) + { + default : return new Token(ofKind, image); + } + } + + public static Token newToken(int ofKind) + { + return newToken(ofKind, null); + } + +} +/* JavaCC - OriginalChecksum=61dd11be23a2b24c2ed31564a8c7855c (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/TokenMgrError.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/TokenMgrError.java new file mode 100644 index 00000000..d9e2ec75 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/TokenMgrError.java @@ -0,0 +1,147 @@ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */ +/* JavaCCOptions: */ +package org.simantics.sysdyn.unitParser; + +/** Token Manager Error. */ +public class TokenMgrError extends Error +{ + + /** + * The version identifier for this Serializable class. + * Increment only if the serialized form of the + * class changes. + */ + private static final long serialVersionUID = 1L; + + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** + * Lexical error occurred. + */ + static final int LEXICAL_ERROR = 0; + + /** + * An attempt was made to create a second instance of a static token manager. + */ + static final int STATIC_LEXER_ERROR = 1; + + /** + * Tried to change to an invalid lexical state. + */ + static final int INVALID_LEXICAL_STATE = 2; + + /** + * Detected (and bailed out of) an infinite loop in the token manager. + */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + + /** + * Replaces unprintable characters by their escaped (or unicode escaped) + * equivalents in the given string + */ + protected static final String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + + /** + * Returns a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + * Parameters : + * EOFSeen : indicates if EOF caused the lexical error + * curLexState : lexical state in which this error occurred + * errorLine : line number when the error occurred + * errorColumn : column number when the error occurred + * errorAfter : prefix that was seen before this error occurred + * curchar : the offending character + * Note: You can customize the lexical error message by modifying this method. + */ + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { + return("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * + * "Internal Error : Please file a bug report .... " + * + * from this method for such cases in the release version of your parser. + */ + public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + /** No arg constructor. */ + public TokenMgrError() { + } + + /** Constructor with message and reason. */ + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + /** Full Constructor. */ + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); + } +} +/* JavaCC - OriginalChecksum=1a840694e4f0cebfb591db26400a3167 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingException.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingException.java new file mode 100644 index 00000000..481004c9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingException.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser; + +public class UnitCheckingException extends Exception { + public UnitCheckingException(String string) { + super(string); + } + + private static final long serialVersionUID = -5828012051088095625L; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java new file mode 100644 index 00000000..5a711256 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.nodes.UnitResult; +import org.simantics.sysdyn.utils.Function; + + +public class UnitCheckingNode extends SimpleNode { + + public UnitCheckingNode(int id) { + super(id); + } + + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException{ + UnitResult result = new UnitResult(allowEquivalents); + + if(jjtGetNumChildren() == 0){ + String node = printNode(); + result.append(node); + } else { + for(int i = 0; i < jjtGetNumChildren(); i++) { + result.appendResult(((UnitCheckingNode)jjtGetChild(i)).getUnits(units, functions, allowEquivalents)); + } + } + return result; + } + + public String printNode() { + StringBuilder sb = new StringBuilder(); + Token token = jjtGetFirstToken(); + sb.append(token.image); + + while(token != null && !token.equals(jjtGetLastToken())) { + token = token.next; + sb.append(token.image); + } + + return sb.toString(); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java new file mode 100644 index 00000000..35f22dfb --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.nodes.AddOp; +import org.simantics.sysdyn.unitParser.nodes.Arithmetic; +import org.simantics.sysdyn.unitParser.nodes.ArrayDefinition; +import org.simantics.sysdyn.unitParser.nodes.ComponentIdentity; +import org.simantics.sysdyn.unitParser.nodes.ComponentReference; +import org.simantics.sysdyn.unitParser.nodes.ComponentReferenceFull; +import org.simantics.sysdyn.unitParser.nodes.Condition; +import org.simantics.sysdyn.unitParser.nodes.Divide; +import org.simantics.sysdyn.unitParser.nodes.Expression; +import org.simantics.sysdyn.unitParser.nodes.Factor; +import org.simantics.sysdyn.unitParser.nodes.ForIndex; +import org.simantics.sysdyn.unitParser.nodes.FunctionArguments; +import org.simantics.sysdyn.unitParser.nodes.FunctionCall; +import org.simantics.sysdyn.unitParser.nodes.IfThenElse; +import org.simantics.sysdyn.unitParser.nodes.Multiplication; +import org.simantics.sysdyn.unitParser.nodes.NamedArguments; +import org.simantics.sysdyn.unitParser.nodes.ParenthesisExpression; +import org.simantics.sysdyn.unitParser.nodes.Power; +import org.simantics.sysdyn.unitParser.nodes.RelOp; +import org.simantics.sysdyn.unitParser.nodes.Relation; +import org.simantics.sysdyn.unitParser.nodes.Term; +import org.simantics.sysdyn.unitParser.nodes.Value; + +public class UnitCheckingNodeFactory { + + private static HashMap> constructors = new HashMap>(); + + static { + constructors.put("relation", Relation.class); + constructors.put("term", Term.class); + constructors.put("factor", Factor.class); + constructors.put("arithmetic_expression", Arithmetic.class); + constructors.put("ifthenelse", IfThenElse.class); + constructors.put("array_definition", ArrayDefinition.class); + + constructors.put("component_reference_full", ComponentReferenceFull.class); + constructors.put("value", Value.class); + + + constructors.put("power", Power.class); + constructors.put("divide", Divide.class); + constructors.put("multiplication", Multiplication.class); + constructors.put("add_op", AddOp.class); + constructors.put("rel_op", RelOp.class); + + + + constructors.put("component_reference", ComponentReference.class); + constructors.put("component_identity", ComponentIdentity.class); + constructors.put("condition", Condition.class); + constructors.put("for_index", ForIndex.class); + constructors.put("parenthesis_expression", ParenthesisExpression.class); + constructors.put("function_call", FunctionCall.class); + constructors.put("function_arguments", FunctionArguments.class); + constructors.put("named_arguments", NamedArguments.class); + constructors.put("expression", Expression.class); + + + } + + private static Class getConstructor(int id) { + String name = UnitParserTreeConstants.jjtNodeName[id]; + Class constructor = constructors.get(name); + if(constructor == null) + return UnitCheckingNode.class; + else + return constructor; + } + + public static Node jjtCreate(int id) { + try { + return (Node) getConstructor(id).getConstructors()[0].newInstance(id); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.java new file mode 100644 index 00000000..4e353980 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.java @@ -0,0 +1,2723 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. UnitParser.java */ +package org.simantics.sysdyn.unitParser; + +public class UnitParser/*@bgen(jjtree)*/implements UnitParserTreeConstants, UnitParserConstants {/*@bgen(jjtree)*/ + protected JJTUnitParserState jjtree = new JJTUnitParserState(); + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + final public SimpleNode expr() throws ParseException { + /*@bgen(jjtree) expr */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTEXPR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 0: + case 6: + case 12: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + simple_expression(); + break; + default: + jj_la1[0] = jj_gen; + ; + } + jj_consume_token(0); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.jjtSetLastToken(getToken(0)); + {if (true) return jjtn000;} + break; + case 31: + ifthenelse(); + jj_consume_token(0); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.jjtSetLastToken(getToken(0)); + {if (true) return jjtn000;} + break; + default: + jj_la1[1] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + throw new Error("Missing return statement in function"); + } + + final public void expression() throws ParseException { + /*@bgen(jjtree) expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + simple_expression(); + break; + case 31: + ifthenelse(); + break; + default: + jj_la1[2] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void ifthenelse() throws ParseException { + /*@bgen(jjtree) ifthenelse */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTIFTHENELSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + jj_consume_token(31); + condition(); + jj_consume_token(28); + expression(); + label_1: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 20: + ; + break; + default: + jj_la1[3] = jj_gen; + break label_1; + } + jj_consume_token(20); + condition(); + jj_consume_token(28); + expression(); + } + jj_consume_token(15); + expression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void condition() throws ParseException { + /*@bgen(jjtree) condition */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTCONDITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + expression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void simple_expression() throws ParseException { + /*@bgen(jjtree) simple_expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTSIMPLE_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + logical_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 67: + jj_consume_token(67); + logical_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 67: + jj_consume_token(67); + logical_expression(); + break; + default: + jj_la1[4] = jj_gen; + ; + } + break; + default: + jj_la1[5] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void logical_expression() throws ParseException { + /*@bgen(jjtree) logical_expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTLOGICAL_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + logical_term(); + label_2: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 22: + ; + break; + default: + jj_la1[6] = jj_gen; + break label_2; + } + jj_consume_token(22); + logical_term(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void logical_term() throws ParseException { + /*@bgen(jjtree) logical_term */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTLOGICAL_TERM); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + logical_factor(); + label_3: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 9: + ; + break; + default: + jj_la1[7] = jj_gen; + break label_3; + } + jj_consume_token(9); + logical_factor(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void logical_factor() throws ParseException { + /*@bgen(jjtree) logical_factor */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTLOGICAL_FACTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 12: + jj_consume_token(12); + break; + default: + jj_la1[8] = jj_gen; + ; + } + relation(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void relation() throws ParseException { + /*@bgen(jjtree) relation */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTRELATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + arithmetic_expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + rel_op(); + arithmetic_expression(); + break; + default: + jj_la1[9] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void rel_op() throws ParseException { + /*@bgen(jjtree) rel_op */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTREL_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 70: + jj_consume_token(70); + break; + case 71: + jj_consume_token(71); + break; + case 72: + jj_consume_token(72); + break; + case 73: + jj_consume_token(73); + break; + case 74: + jj_consume_token(74); + break; + case 75: + jj_consume_token(75); + break; + default: + jj_la1[10] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void arithmetic_expression() throws ParseException { + /*@bgen(jjtree) arithmetic_expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTARITHMETIC_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 76: + case 77: + case 78: + case 79: + add_op(); + break; + default: + jj_la1[11] = jj_gen; + ; + } + term(); + label_4: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 76: + case 77: + case 78: + case 79: + ; + break; + default: + jj_la1[12] = jj_gen; + break label_4; + } + add_op(); + term(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void add_op() throws ParseException { + /*@bgen(jjtree) add_op */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTADD_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 76: + jj_consume_token(76); + break; + case 77: + jj_consume_token(77); + break; + case 78: + jj_consume_token(78); + break; + case 79: + jj_consume_token(79); + break; + default: + jj_la1[13] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void term() throws ParseException { + /*@bgen(jjtree) term */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTTERM); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + if (jj_2_1(2147483647)) { + factor(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 33: + case 35: + case 60: + case 62: + case 64: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + primary(); + break; + default: + jj_la1[14] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + label_5: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 80: + case 81: + case 82: + case 83: + ; + break; + default: + jj_la1[15] = jj_gen; + break label_5; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 80: + case 82: + multiplication(); + break; + case 81: + case 83: + divide(); + break; + default: + jj_la1[16] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + if (jj_2_2(2147483647)) { + factor(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 33: + case 35: + case 60: + case 62: + case 64: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + primary(); + break; + default: + jj_la1[17] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void factor() throws ParseException { + /*@bgen(jjtree) factor */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFACTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + primary(); + power(); + primary(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void power() throws ParseException { + /*@bgen(jjtree) power */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPOWER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 84: + jj_consume_token(84); + break; + case 85: + jj_consume_token(85); + break; + default: + jj_la1[18] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void multiplication() throws ParseException { + /*@bgen(jjtree) multiplication */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTMULTIPLICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 80: + jj_consume_token(80); + break; + case 82: + jj_consume_token(82); + break; + default: + jj_la1[19] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void divide() throws ParseException { + /*@bgen(jjtree) divide */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTDIVIDE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 81: + jj_consume_token(81); + break; + case 83: + jj_consume_token(83); + break; + default: + jj_la1[20] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void primary() throws ParseException { + /*@bgen(jjtree) primary */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPRIMARY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 33: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + value(); + break; + default: + jj_la1[22] = jj_gen; + if (jj_2_3(2147483647)) { + function_call(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + component_reference_full(); + break; + case 60: + parenthesis_expression(); + break; + case 64: + jj_consume_token(64); + expression_list(); + label_6: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 68: + ; + break; + default: + jj_la1[21] = jj_gen; + break label_6; + } + jj_consume_token(68); + expression_list(); + } + jj_consume_token(65); + break; + case 62: + array_definition(); + break; + case 35: + jj_consume_token(35); + break; + default: + jj_la1[23] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void component_reference_full() throws ParseException { + /*@bgen(jjtree) component_reference_full */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTCOMPONENT_REFERENCE_FULL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + component_reference(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void array_definition() throws ParseException { + /*@bgen(jjtree) array_definition */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTARRAY_DEFINITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + jj_consume_token(62); + function_arguments(); + jj_consume_token(63); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void function_call() throws ParseException { + /*@bgen(jjtree) function_call */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFUNCTION_CALL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + name(); + function_call_args(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void parenthesis_expression() throws ParseException { + /*@bgen(jjtree) parenthesis_expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPARENTHESIS_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + parenthesis_open(); + expression(); + parenthesis_close(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void value() throws ParseException { + /*@bgen(jjtree) value */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTVALUE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case UNSIGNED_NUMBER: + jj_consume_token(UNSIGNED_NUMBER); + break; + case UNSIGNED_INTEGER: + jj_consume_token(UNSIGNED_INTEGER); + break; + case STRING: + jj_consume_token(STRING); + break; + case 6: + jj_consume_token(6); + break; + case 33: + jj_consume_token(33); + break; + default: + jj_la1[24] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void parenthesis_open() throws ParseException { + /*@bgen(jjtree) parenthesis_open */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPARENTHESIS_OPEN); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + jj_consume_token(60); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void parenthesis_close() throws ParseException { + /*@bgen(jjtree) parenthesis_close */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPARENTHESIS_CLOSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + jj_consume_token(61); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void name() throws ParseException { + /*@bgen(jjtree) name */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTNAME); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + jj_consume_token(IDENT); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + jj_consume_token(66); + name(); + break; + default: + jj_la1[25] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void component_reference() throws ParseException { + /*@bgen(jjtree) component_reference */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTCOMPONENT_REFERENCE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + component_identity(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 64: + array_subscripts(); + break; + default: + jj_la1[26] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 66: + jj_consume_token(66); + component_reference(); + break; + default: + jj_la1[27] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void component_identity() throws ParseException { + /*@bgen(jjtree) component_identity */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTCOMPONENT_IDENTITY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + jj_consume_token(IDENT); + label_7: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + ; + break; + default: + jj_la1[28] = jj_gen; + break label_7; + } + jj_consume_token(IDENT); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void function_call_args() throws ParseException { + /*@bgen(jjtree) function_call_args */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFUNCTION_CALL_ARGS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + parenthesis_open(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + function_arguments(); + break; + default: + jj_la1[29] = jj_gen; + ; + } + parenthesis_close(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void function_arguments() throws ParseException { + /*@bgen(jjtree) function_arguments */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFUNCTION_ARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + if (jj_2_4(2)) { + named_arguments(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 21: + case 69: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + function_arguments(); + break; + case 21: + jj_consume_token(21); + for_indices(); + break; + default: + jj_la1[30] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[31] = jj_gen; + ; + } + break; + default: + jj_la1[32] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void for_indices() throws ParseException { + /*@bgen(jjtree) for_indices */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFOR_INDICES); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + for_index(); + label_8: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + ; + break; + default: + jj_la1[33] = jj_gen; + break label_8; + } + jj_consume_token(69); + for_index(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void for_index() throws ParseException { + /*@bgen(jjtree) for_index */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFOR_INDEX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + jj_consume_token(IDENT); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 41: + jj_consume_token(41); + expression(); + break; + default: + jj_la1[34] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void named_arguments() throws ParseException { + /*@bgen(jjtree) named_arguments */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTNAMED_ARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + named_argument(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + jj_consume_token(69); + named_arguments(); + break; + default: + jj_la1[35] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void named_argument() throws ParseException { + /*@bgen(jjtree) named_argument */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTNAMED_ARGUMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + jj_consume_token(IDENT); + jj_consume_token(86); + expression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void output_expression_list() throws ParseException { + /*@bgen(jjtree) output_expression_list */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTOUTPUT_EXPRESSION_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[36] = jj_gen; + ; + } + label_9: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + ; + break; + default: + jj_la1[37] = jj_gen; + break label_9; + } + jj_consume_token(69); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 6: + case 12: + case 31: + case 33: + case 35: + case 60: + case 62: + case 64: + case 76: + case 77: + case 78: + case 79: + case IDENT: + case STRING: + case UNSIGNED_INTEGER: + case UNSIGNED_NUMBER: + expression(); + break; + default: + jj_la1[38] = jj_gen; + ; + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void expression_list() throws ParseException { + /*@bgen(jjtree) expression_list */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTEXPRESSION_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + expression(); + label_10: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + ; + break; + default: + jj_la1[39] = jj_gen; + break label_10; + } + jj_consume_token(69); + expression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void array_subscripts() throws ParseException { + /*@bgen(jjtree) array_subscripts */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTARRAY_SUBSCRIPTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + jj_consume_token(64); + subscript(); + label_11: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 69: + ; + break; + default: + jj_la1[40] = jj_gen; + break label_11; + } + jj_consume_token(69); + subscript(); + } + jj_consume_token(65); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void subscript() throws ParseException { + /*@bgen(jjtree) subscript */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTSUBSCRIPT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 67: + jj_consume_token(67); + break; + default: + jj_la1[42] = jj_gen; + if (jj_2_5(2147483647)) { + function_call(); + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDENT: + case UNSIGNED_INTEGER: + rangeIndex(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 67: + jj_consume_token(67); + rangeIndex(); + break; + default: + jj_la1[41] = jj_gen; + ; + } + break; + default: + jj_la1[43] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + {if (true) throw (RuntimeException)jjte000;} + } + if (jjte000 instanceof ParseException) { + {if (true) throw (ParseException)jjte000;} + } + {if (true) throw (Error)jjte000;} + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + final public void rangeIndex() throws ParseException { + /*@bgen(jjtree) rangeIndex */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTRANGEINDEX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); + try { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case UNSIGNED_INTEGER: + jj_consume_token(UNSIGNED_INTEGER); + break; + case IDENT: + jj_consume_token(IDENT); + break; + default: + jj_la1[44] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } + } + + private boolean jj_2_1(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_1(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(0, xla); } + } + + private boolean jj_2_2(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_2(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(1, xla); } + } + + private boolean jj_2_3(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_3(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(2, xla); } + } + + private boolean jj_2_4(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_4(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(3, xla); } + } + + private boolean jj_2_5(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_5(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(4, xla); } + } + + private boolean jj_3R_80() { + if (jj_3R_12()) return true; + return false; + } + + private boolean jj_3R_31() { + if (jj_scan_token(62)) return true; + if (jj_3R_37()) return true; + if (jj_scan_token(63)) return true; + return false; + } + + private boolean jj_3R_27() { + if (jj_3R_33()) return true; + return false; + } + + private boolean jj_3_3() { + if (jj_3R_14()) return true; + if (jj_3R_15()) return true; + return false; + } + + private boolean jj_3R_22() { + if (jj_3R_31()) return true; + return false; + } + + private boolean jj_3R_21() { + if (jj_scan_token(64)) return true; + if (jj_3R_29()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_30()) { jj_scanpos = xsp; break; } + } + if (jj_scan_token(65)) return true; + return false; + } + + private boolean jj_3R_20() { + if (jj_3R_28()) return true; + return false; + } + + private boolean jj_3R_19() { + if (jj_3R_27()) return true; + return false; + } + + private boolean jj_3R_18() { + if (jj_3R_26()) return true; + return false; + } + + private boolean jj_3R_12() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_17()) { + jj_scanpos = xsp; + if (jj_3R_18()) { + jj_scanpos = xsp; + if (jj_3R_19()) { + jj_scanpos = xsp; + if (jj_3R_20()) { + jj_scanpos = xsp; + if (jj_3R_21()) { + jj_scanpos = xsp; + if (jj_3R_22()) { + jj_scanpos = xsp; + if (jj_scan_token(35)) return true; + } + } + } + } + } + } + return false; + } + + private boolean jj_3R_17() { + if (jj_3R_25()) return true; + return false; + } + + private boolean jj_3R_88() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(81)) { + jj_scanpos = xsp; + if (jj_scan_token(83)) return true; + } + return false; + } + + private boolean jj_3R_87() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(80)) { + jj_scanpos = xsp; + if (jj_scan_token(82)) return true; + } + return false; + } + + private boolean jj_3R_13() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(84)) { + jj_scanpos = xsp; + if (jj_scan_token(85)) return true; + } + return false; + } + + private boolean jj_3R_62() { + if (jj_scan_token(67)) return true; + if (jj_3R_51()) return true; + return false; + } + + private boolean jj_3_1() { + if (jj_3R_12()) return true; + if (jj_3R_13()) return true; + return false; + } + + private boolean jj_3R_73() { + if (jj_3R_77()) return true; + if (jj_3R_72()) return true; + return false; + } + + private boolean jj_3R_76() { + if (jj_3R_78()) return true; + if (jj_3R_75()) return true; + return false; + } + + private boolean jj_3R_82() { + if (jj_3R_12()) return true; + if (jj_3R_13()) return true; + if (jj_3R_12()) return true; + return false; + } + + private boolean jj_3R_79() { + if (jj_3R_82()) return true; + return false; + } + + private boolean jj_3R_75() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_79()) { + jj_scanpos = xsp; + if (jj_3R_80()) return true; + } + while (true) { + xsp = jj_scanpos; + if (jj_3R_81()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_78() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(76)) { + jj_scanpos = xsp; + if (jj_scan_token(77)) { + jj_scanpos = xsp; + if (jj_scan_token(78)) { + jj_scanpos = xsp; + if (jj_scan_token(79)) return true; + } + } + } + return false; + } + + private boolean jj_3R_67() { + if (jj_scan_token(9)) return true; + if (jj_3R_66()) return true; + return false; + } + + private boolean jj_3R_74() { + if (jj_3R_78()) return true; + return false; + } + + private boolean jj_3R_72() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_74()) jj_scanpos = xsp; + if (jj_3R_75()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_76()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_77() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(70)) { + jj_scanpos = xsp; + if (jj_scan_token(71)) { + jj_scanpos = xsp; + if (jj_scan_token(72)) { + jj_scanpos = xsp; + if (jj_scan_token(73)) { + jj_scanpos = xsp; + if (jj_scan_token(74)) { + jj_scanpos = xsp; + if (jj_scan_token(75)) return true; + } + } + } + } + } + return false; + } + + private boolean jj_3R_52() { + if (jj_scan_token(67)) return true; + if (jj_3R_51()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_62()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_61() { + if (jj_scan_token(22)) return true; + if (jj_3R_60()) return true; + return false; + } + + private boolean jj_3R_54() { + if (jj_scan_token(20)) return true; + if (jj_3R_53()) return true; + if (jj_scan_token(28)) return true; + if (jj_3R_34()) return true; + return false; + } + + private boolean jj_3R_70() { + if (jj_3R_72()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_73()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_66() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(12)) jj_scanpos = xsp; + if (jj_3R_70()) return true; + return false; + } + + private boolean jj_3R_65() { + if (jj_scan_token(67)) return true; + if (jj_3R_64()) return true; + return false; + } + + private boolean jj_3_5() { + if (jj_3R_14()) return true; + if (jj_3R_15()) return true; + return false; + } + + private boolean jj_3R_60() { + if (jj_3R_66()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_67()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_50() { + if (jj_scan_token(69)) return true; + if (jj_3R_49()) return true; + return false; + } + + private boolean jj_3R_51() { + if (jj_3R_60()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_61()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_64() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(90)) { + jj_scanpos = xsp; + if (jj_scan_token(88)) return true; + } + return false; + } + + private boolean jj_3R_46() { + if (jj_3R_51()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_52()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_58() { + if (jj_3R_26()) return true; + return false; + } + + private boolean jj_3R_59() { + if (jj_3R_64()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_65()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_36() { + if (jj_scan_token(69)) return true; + if (jj_3R_34()) return true; + return false; + } + + private boolean jj_3R_49() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(67)) { + jj_scanpos = xsp; + if (jj_3R_58()) { + jj_scanpos = xsp; + if (jj_3R_59()) return true; + } + } + return false; + } + + private boolean jj_3R_57() { + if (jj_scan_token(21)) return true; + if (jj_3R_63()) return true; + return false; + } + + private boolean jj_3R_45() { + if (jj_scan_token(64)) return true; + if (jj_3R_49()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_50()) { jj_scanpos = xsp; break; } + } + if (jj_scan_token(65)) return true; + return false; + } + + private boolean jj_3R_55() { + if (jj_scan_token(69)) return true; + if (jj_3R_16()) return true; + return false; + } + + private boolean jj_3R_53() { + if (jj_3R_34()) return true; + return false; + } + + private boolean jj_3R_43() { + if (jj_3R_47()) return true; + return false; + } + + private boolean jj_3R_34() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_42()) { + jj_scanpos = xsp; + if (jj_3R_43()) return true; + } + return false; + } + + private boolean jj_3R_42() { + if (jj_3R_46()) return true; + return false; + } + + private boolean jj_3R_47() { + if (jj_scan_token(31)) return true; + if (jj_3R_53()) return true; + if (jj_scan_token(28)) return true; + if (jj_3R_34()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_54()) { jj_scanpos = xsp; break; } + } + if (jj_scan_token(15)) return true; + if (jj_3R_34()) return true; + return false; + } + + private boolean jj_3R_29() { + if (jj_3R_34()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_36()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_41() { + if (jj_scan_token(66)) return true; + if (jj_3R_33()) return true; + return false; + } + + private boolean jj_3R_24() { + if (jj_scan_token(IDENT)) return true; + if (jj_scan_token(86)) return true; + if (jj_3R_34()) return true; + return false; + } + + private boolean jj_3R_71() { + if (jj_scan_token(41)) return true; + if (jj_3R_34()) return true; + return false; + } + + private boolean jj_3R_86() { + if (jj_3R_12()) return true; + return false; + } + + private boolean jj_3R_69() { + if (jj_scan_token(69)) return true; + if (jj_3R_68()) return true; + return false; + } + + private boolean jj_3R_16() { + if (jj_3R_24()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_55()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_48() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_56()) { + jj_scanpos = xsp; + if (jj_3R_57()) return true; + } + return false; + } + + private boolean jj_3R_56() { + if (jj_scan_token(69)) return true; + if (jj_3R_37()) return true; + return false; + } + + private boolean jj_3R_38() { + if (jj_3R_37()) return true; + return false; + } + + private boolean jj_3R_68() { + if (jj_scan_token(IDENT)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_71()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_63() { + if (jj_3R_68()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_69()) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_40() { + if (jj_3R_45()) return true; + return false; + } + + private boolean jj_3R_44() { + if (jj_3R_34()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_48()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3_4() { + if (jj_3R_16()) return true; + return false; + } + + private boolean jj_3R_37() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_4()) { + jj_scanpos = xsp; + if (jj_3R_44()) return true; + } + return false; + } + + private boolean jj_3R_32() { + if (jj_3R_15()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_38()) jj_scanpos = xsp; + if (jj_3R_35()) return true; + return false; + } + + private boolean jj_3_2() { + if (jj_3R_12()) return true; + if (jj_3R_13()) return true; + return false; + } + + private boolean jj_3R_23() { + if (jj_scan_token(66)) return true; + if (jj_3R_14()) return true; + return false; + } + + private boolean jj_3R_85() { + if (jj_3R_82()) return true; + return false; + } + + private boolean jj_3R_39() { + if (jj_scan_token(IDENT)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_scan_token(88)) { jj_scanpos = xsp; break; } + } + return false; + } + + private boolean jj_3R_33() { + if (jj_3R_39()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_40()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_41()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_14() { + if (jj_scan_token(IDENT)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_23()) jj_scanpos = xsp; + return false; + } + + private boolean jj_3R_84() { + if (jj_3R_88()) return true; + return false; + } + + private boolean jj_3R_35() { + if (jj_scan_token(61)) return true; + return false; + } + + private boolean jj_3R_15() { + if (jj_scan_token(60)) return true; + return false; + } + + private boolean jj_3R_25() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(91)) { + jj_scanpos = xsp; + if (jj_scan_token(90)) { + jj_scanpos = xsp; + if (jj_scan_token(89)) { + jj_scanpos = xsp; + if (jj_scan_token(6)) { + jj_scanpos = xsp; + if (jj_scan_token(33)) return true; + } + } + } + } + return false; + } + + private boolean jj_3R_83() { + if (jj_3R_87()) return true; + return false; + } + + private boolean jj_3R_81() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_83()) { + jj_scanpos = xsp; + if (jj_3R_84()) return true; + } + xsp = jj_scanpos; + if (jj_3R_85()) { + jj_scanpos = xsp; + if (jj_3R_86()) return true; + } + return false; + } + + private boolean jj_3R_30() { + if (jj_scan_token(68)) return true; + if (jj_3R_29()) return true; + return false; + } + + private boolean jj_3R_28() { + if (jj_3R_15()) return true; + if (jj_3R_34()) return true; + if (jj_3R_35()) return true; + return false; + } + + private boolean jj_3R_26() { + if (jj_3R_14()) return true; + if (jj_3R_32()) return true; + return false; + } + + /** Generated Token Manager. */ + public UnitParserTokenManager token_source; + SimpleCharStream jj_input_stream; + /** Current token. */ + public Token token; + /** Next token. */ + public Token jj_nt; + private int jj_ntk; + private Token jj_scanpos, jj_lastpos; + private int jj_la; + private int jj_gen; + final private int[] jj_la1 = new int[45]; + static private int[] jj_la1_0; + static private int[] jj_la1_1; + static private int[] jj_la1_2; + static { + jj_la1_init_0(); + jj_la1_init_1(); + jj_la1_init_2(); + } + private static void jj_la1_init_0() { + jj_la1_0 = new int[] {0x1040,0x80001041,0x80001040,0x100000,0x0,0x0,0x400000,0x200,0x1000,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x40,0x0,0x40,0x0,0x0,0x0,0x0,0x80001040,0x200000,0x200000,0x80001040,0x0,0x0,0x0,0x80001040,0x0,0x80001040,0x0,0x0,0x0,0x0,0x0,0x0,}; + } + private static void jj_la1_init_1() { + jj_la1_1 = new int[] {0x5000000a,0x5000000a,0x5000000a,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5000000a,0x0,0x0,0x5000000a,0x0,0x0,0x0,0x0,0x2,0x50000008,0x2,0x0,0x0,0x0,0x0,0x5000000a,0x0,0x0,0x5000000a,0x0,0x200,0x0,0x5000000a,0x0,0x5000000a,0x0,0x0,0x0,0x0,0x0,0x0,}; + } + private static void jj_la1_init_2() { + jj_la1_2 = new int[] {0xf00f001,0xf00f001,0xf00f001,0x0,0x8,0x8,0x0,0x0,0x0,0xfc0,0xfc0,0xf000,0xf000,0xf000,0xf000001,0xf0000,0xf0000,0xf000001,0x300000,0x50000,0xa0000,0x10,0xe000000,0x1000001,0xe000000,0x4,0x1,0x4,0x1000000,0xf00f001,0x20,0x20,0xf00f001,0x20,0x0,0x20,0xf00f001,0x20,0xf00f001,0x20,0x20,0x8,0x8,0x5000000,0x5000000,}; + } + final private JJCalls[] jj_2_rtns = new JJCalls[5]; + private boolean jj_rescan = false; + private int jj_gc = 0; + + /** Constructor with InputStream. */ + public UnitParser(java.io.InputStream stream) { + this(stream, null); + } + /** Constructor with InputStream and supplied encoding */ + public UnitParser(java.io.InputStream stream, String encoding) { + try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source = new UnitParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 45; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream, String encoding) { + try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + jj_gen = 0; + for (int i = 0; i < 45; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor. */ + public UnitParser(java.io.Reader stream) { + jj_input_stream = new SimpleCharStream(stream, 1, 1); + token_source = new UnitParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 45; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + jj_gen = 0; + for (int i = 0; i < 45; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor with generated Token Manager. */ + public UnitParser(UnitParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 45; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(UnitParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + jj_gen = 0; + for (int i = 0; i < 45; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + jj_gen++; + if (++jj_gc > 100) { + jj_gc = 0; + for (int i = 0; i < jj_2_rtns.length; i++) { + JJCalls c = jj_2_rtns[i]; + while (c != null) { + if (c.gen < jj_gen) c.first = null; + c = c.next; + } + } + } + return token; + } + token = oldToken; + jj_kind = kind; + throw generateParseException(); + } + + static private final class LookaheadSuccess extends java.lang.Error { } + final private LookaheadSuccess jj_ls = new LookaheadSuccess(); + private boolean jj_scan_token(int kind) { + if (jj_scanpos == jj_lastpos) { + jj_la--; + if (jj_scanpos.next == null) { + jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); + } else { + jj_lastpos = jj_scanpos = jj_scanpos.next; + } + } else { + jj_scanpos = jj_scanpos.next; + } + if (jj_rescan) { + int i = 0; Token tok = token; + while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; } + if (tok != null) jj_add_error_token(kind, i); + } + if (jj_scanpos.kind != kind) return true; + if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls; + return false; + } + + +/** Get the next Token. */ + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; + } + +/** Get the specific Token. */ + final public Token getToken(int index) { + Token t = token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + private int jj_ntk() { + if ((jj_nt=token.next) == null) + return (jj_ntk = (token.next=token_source.getNextToken()).kind); + else + return (jj_ntk = jj_nt.kind); + } + + private java.util.List jj_expentries = new java.util.ArrayList(); + private int[] jj_expentry; + private int jj_kind = -1; + private int[] jj_lasttokens = new int[100]; + private int jj_endpos; + + private void jj_add_error_token(int kind, int pos) { + if (pos >= 100) return; + if (pos == jj_endpos + 1) { + jj_lasttokens[jj_endpos++] = kind; + } else if (jj_endpos != 0) { + jj_expentry = new int[jj_endpos]; + for (int i = 0; i < jj_endpos; i++) { + jj_expentry[i] = jj_lasttokens[i]; + } + jj_entries_loop: for (java.util.Iterator it = jj_expentries.iterator(); it.hasNext();) { + int[] oldentry = (int[])(it.next()); + if (oldentry.length == jj_expentry.length) { + for (int i = 0; i < jj_expentry.length; i++) { + if (oldentry[i] != jj_expentry[i]) { + continue jj_entries_loop; + } + } + jj_expentries.add(jj_expentry); + break jj_entries_loop; + } + } + if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind; + } + } + + /** Generate ParseException. */ + public ParseException generateParseException() { + jj_expentries.clear(); + boolean[] la1tokens = new boolean[92]; + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int i = 0; i < 45; i++) { + if (jj_la1[i] == jj_gen) { + for (int j = 0; j < 32; j++) { + if ((jj_la1_0[i] & (1< jj_gen) { + jj_la = p.arg; jj_lastpos = jj_scanpos = p.first; + switch (i) { + case 0: jj_3_1(); break; + case 1: jj_3_2(); break; + case 2: jj_3_3(); break; + case 3: jj_3_4(); break; + case 4: jj_3_5(); break; + } + } + p = p.next; + } while (p != null); + } catch(LookaheadSuccess ls) { } + } + jj_rescan = false; + } + + private void jj_save(int index, int xla) { + JJCalls p = jj_2_rtns[index]; + while (p.gen > jj_gen) { + if (p.next == null) { p = p.next = new JJCalls(); break; } + p = p.next; + } + p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla; + } + + static final class JJCalls { + int gen; + Token first; + int arg; + JJCalls next; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jj b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jj new file mode 100644 index 00000000..7261f8cf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jj @@ -0,0 +1,1250 @@ +/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. UnitParser.jj */ +/*@egen*/options { + JDK_VERSION = "1.6"; + STATIC = false; + + + +} + +PARSER_BEGIN(UnitParser) +package org.simantics.sysdyn.unitParser; + +public class UnitParser/*@bgen(jjtree)*/implements UnitParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/ + protected JJTUnitParserState jjtree = new JJTUnitParserState(); + +/*@egen*/ + + + +} +PARSER_END(UnitParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ +"algorithm" | "discrete" | "false" | "model" | "redeclare" +| "and" | "each" | "final" | "not" | "replaceable" +| "annotation" | "else" | "flow" | "operator" | "return" +|"assert" | "elseif" | "for" | "or" | "stream" +| "block" | "elsewhen" | "function" | "outer" | "then" +| "break" | "encapsulated" | "if" | "output" | "true" +| "class" | "end" | "import" | "package" | "type" +| "connect" | "enumeration" | "in" | "parameter" | "when" +| "connector" | "equation" | /*"initial" |*/ "partial" | "while" +| "constant" | "expandable" | "inner" | "protected" | "within" +| "constrainedby" | "extends" | "input" | "public" +| /*"der" |*/ "external" | "loop" | "record" +| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | "," +| "<" | "<=" | ">" | ">=" | "==" | "<>" +| "+" | "-" | ".+" | ".-" +| "*" | "/" | ".*" | "./" +| "^" | ".^" +| "=" | ":=" +| +| + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +| +| "." ()? (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +} + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + +SimpleNode expr() : {/*@bgen(jjtree) expr */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTEXPR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) expr */ + try { +/*@egen*/ + (simple_expression())? /*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.jjtSetLastToken(getToken(0)); + } +/*@egen*/ + { + return jjtn000; + } + | + ifthenelse() /*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtn000.jjtSetLastToken(getToken(0)); + } +/*@egen*/ + { + return jjtn000; + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void expression() : {/*@bgen(jjtree) expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) expression */ + try { +/*@egen*/ + simple_expression() + | ifthenelse()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void ifthenelse() : {/*@bgen(jjtree) ifthenelse */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTIFTHENELSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ } {/*@bgen(jjtree) ifthenelse */ + try { +/*@egen*/ + "if" condition() "then" expression() ( "elseif" condition() "then" expression() )* "else" expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void condition() : {/*@bgen(jjtree) condition */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTCONDITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) condition */ + try { +/*@egen*/ + expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void simple_expression() : {/*@bgen(jjtree) simple_expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTSIMPLE_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) simple_expression */ + try { +/*@egen*/ + logical_expression() ( ":" logical_expression() ( ":" logical_expression() )? )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void logical_expression() : {/*@bgen(jjtree) logical_expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTLOGICAL_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) logical_expression */ + try { +/*@egen*/ + logical_term() ( "or" logical_term() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void logical_term() : {/*@bgen(jjtree) logical_term */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTLOGICAL_TERM); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) logical_term */ + try { +/*@egen*/ + logical_factor() ( "and" logical_factor() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void logical_factor() : {/*@bgen(jjtree) logical_factor */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTLOGICAL_FACTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) logical_factor */ + try { +/*@egen*/ + ( "not" )? relation()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void relation() : {/*@bgen(jjtree) relation */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTRELATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) relation */ + try { +/*@egen*/ + arithmetic_expression() ( rel_op() arithmetic_expression() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void rel_op() : {/*@bgen(jjtree) rel_op */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTREL_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) rel_op */ + try { +/*@egen*/ + "<" | "<=" | ">" | ">=" | "==" | "<>"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void arithmetic_expression() : {/*@bgen(jjtree) arithmetic_expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTARITHMETIC_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) arithmetic_expression */ + try { +/*@egen*/ + (add_op())? term() (add_op() term())*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void add_op() : {/*@bgen(jjtree) add_op */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTADD_OP); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) add_op */ + try { +/*@egen*/ + "+" | "-" | ".+" | ".-"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void term() : {/*@bgen(jjtree) term */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTTERM); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) term */ + try { +/*@egen*/ + ( LOOKAHEAD(primary() power()) factor() | primary() ) ( (multiplication() | divide()) ( LOOKAHEAD(primary() power()) factor() | primary()) )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void factor() : {/*@bgen(jjtree) factor */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFACTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) factor */ + try { +/*@egen*/ + primary() power() primary()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void power() : {/*@bgen(jjtree) power */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPOWER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) power */ + try { +/*@egen*/ + "^" | ".^"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} +void multiplication() : {/*@bgen(jjtree) multiplication */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTMULTIPLICATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) multiplication */ + try { +/*@egen*/ + "*" | ".*"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void divide() : {/*@bgen(jjtree) divide */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTDIVIDE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) divide */ + try { +/*@egen*/ + "/" | "./"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void primary() : {/*@bgen(jjtree) primary */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPRIMARY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) primary */ + try { +/*@egen*/ + value() + | LOOKAHEAD( name() parenthesis_open() ) function_call() + | component_reference_full() + /*| "(" output_expression_list() ")"*/ // Not needed, replaced with following: + | parenthesis_expression() + | "[" expression_list() ( ";" expression_list() )* "]" + | array_definition() + | "end"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void component_reference_full() : {/*@bgen(jjtree) component_reference_full */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTCOMPONENT_REFERENCE_FULL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) component_reference_full */ + try { +/*@egen*/ + component_reference()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void array_definition() : {/*@bgen(jjtree) array_definition */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTARRAY_DEFINITION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) array_definition */ + try { +/*@egen*/ + "{" function_arguments() "}"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void function_call() : {/*@bgen(jjtree) function_call */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFUNCTION_CALL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) function_call */ + try { +/*@egen*/ + name() function_call_args()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void parenthesis_expression() : {/*@bgen(jjtree) parenthesis_expression */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPARENTHESIS_EXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ } {/*@bgen(jjtree) parenthesis_expression */ + try { +/*@egen*/ parenthesis_open() expression() parenthesis_close()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void value() : {/*@bgen(jjtree) value */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTVALUE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ } {/*@bgen(jjtree) value */ + try { +/*@egen*/ + + | + | + | "false" + | "true"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void parenthesis_open() : {/*@bgen(jjtree) parenthesis_open */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPARENTHESIS_OPEN); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) parenthesis_open */ + try { +/*@egen*/ + "("/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void parenthesis_close() : {/*@bgen(jjtree) parenthesis_close */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTPARENTHESIS_CLOSE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) parenthesis_close */ + try { +/*@egen*/ + ")"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void name() : {/*@bgen(jjtree) name */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTNAME); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) name */ + try { +/*@egen*/ + ( "." name() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void component_reference() : {/*@bgen(jjtree) component_reference */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTCOMPONENT_REFERENCE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) component_reference */ + try { +/*@egen*/ + //IDENT [ array_subscripts ] [ "." component_reference ] + component_identity() ( array_subscripts() )? ( "." component_reference() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void component_identity() : {/*@bgen(jjtree) component_identity */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTCOMPONENT_IDENTITY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) component_identity */ + try { +/*@egen*/ ()*/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void function_call_args() : {/*@bgen(jjtree) function_call_args */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFUNCTION_CALL_ARGS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) function_call_args */ + try { +/*@egen*/ + parenthesis_open() ( function_arguments() )? parenthesis_close()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void function_arguments() : {/*@bgen(jjtree) function_arguments */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFUNCTION_ARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) function_arguments */ + try { +/*@egen*/ + //expression [ "," function_arguments | for for_indices ] + //| named_arguments + LOOKAHEAD(2) named_arguments() + | expression() ( "," function_arguments() | "for" for_indices() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ + +} + +void for_indices() : {/*@bgen(jjtree) for_indices */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFOR_INDICES); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) for_indices */ + try { +/*@egen*/ + //for_index {"," for_index} + for_index() ("," for_index())*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void for_index() : {/*@bgen(jjtree) for_index */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTFOR_INDEX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) for_index */ + try { +/*@egen*/ + //IDENT [ in expression ] + ( "in" expression() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void named_arguments() : {/*@bgen(jjtree) named_arguments */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTNAMED_ARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) named_arguments */ + try { +/*@egen*/ + named_argument() ( "," named_arguments() )?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void named_argument() : {/*@bgen(jjtree) named_argument */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTNAMED_ARGUMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) named_argument */ + try { +/*@egen*/ + "=" expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void output_expression_list() : {/*@bgen(jjtree) output_expression_list */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTOUTPUT_EXPRESSION_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) output_expression_list */ + try { +/*@egen*/ + ( expression() )? ( "," ( expression() )? )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + + +void expression_list() : {/*@bgen(jjtree) expression_list */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTEXPRESSION_LIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) expression_list */ + try { +/*@egen*/ + expression() ( "," expression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void array_subscripts() : {/*@bgen(jjtree) array_subscripts */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTARRAY_SUBSCRIPTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) array_subscripts */ + try { +/*@egen*/ + "[" subscript() ( "," subscript() )* "]"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void subscript() : {/*@bgen(jjtree) subscript */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTSUBSCRIPT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) subscript */ + try { +/*@egen*/ ":" + | LOOKAHEAD( name() parenthesis_open() ) function_call() + | rangeIndex() ( ":" rangeIndex())?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + +void rangeIndex() : {/*@bgen(jjtree) rangeIndex */ + UnitCheckingNode jjtn000 = (UnitCheckingNode)UnitCheckingNodeFactory.jjtCreate(JJTRANGEINDEX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtn000.jjtSetFirstToken(getToken(1)); +/*@egen*/ +} {/*@bgen(jjtree) rangeIndex */ + try { +/*@egen*/ + | /*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtn000.jjtSetLastToken(getToken(0)); + } + } +/*@egen*/ +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jjt b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jjt new file mode 100644 index 00000000..81d5fcb8 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jjt @@ -0,0 +1,282 @@ +options { + JDK_VERSION = "1.6"; + STATIC = false; + TRACK_TOKENS=true; + NODE_CLASS="UnitCheckingNode"; + NODE_FACTORY="UnitCheckingNodeFactory"; +} + +PARSER_BEGIN(UnitParser) +package org.simantics.sysdyn.unitParser; + +public class UnitParser { + + + +} +PARSER_END(UnitParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ +"algorithm" | "discrete" | "false" | "model" | "redeclare" +| "and" | "each" | "final" | "not" | "replaceable" +| "annotation" | "else" | "flow" | "operator" | "return" +|"assert" | "elseif" | "for" | "or" | "stream" +| "block" | "elsewhen" | "function" | "outer" | "then" +| "break" | "encapsulated" | "if" | "output" | "true" +| "class" | "end" | "import" | "package" | "type" +| "connect" | "enumeration" | "in" | "parameter" | "when" +| "connector" | "equation" | /*"initial" |*/ "partial" | "while" +| "constant" | "expandable" | "inner" | "protected" | "within" +| "constrainedby" | "extends" | "input" | "public" +| /*"der" |*/ "external" | "loop" | "record" +| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | "," +| "<" | "<=" | ">" | ">=" | "==" | "<>" +| "+" | "-" | ".+" | ".-" +| "*" | "/" | ".*" | "./" +| "^" | ".^" +| "=" | ":=" +| +| + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +| +| "." ()? (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +} + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + +SimpleNode expr() : { +} { + (simple_expression())? + { + return jjtThis; + } + | + ifthenelse() + { + return jjtThis; + } +} + +void expression() : { +} { + simple_expression() + | ifthenelse() +} + +void ifthenelse() : { } { + "if" condition() "then" expression() ( "elseif" condition() "then" expression() )* "else" expression() +} + +void condition() : { +} { + expression() +} + +void simple_expression() : { +} { + logical_expression() ( ":" logical_expression() ( ":" logical_expression() )? )? +} + +void logical_expression() : { +} { + logical_term() ( "or" logical_term() )* +} + +void logical_term() : { +} { + logical_factor() ( "and" logical_factor() )* +} + +void logical_factor() : { +} { + ( "not" )? relation() +} + +void relation() : { +} { + arithmetic_expression() ( rel_op() arithmetic_expression() )? +} + +void rel_op() : { +} { + "<" | "<=" | ">" | ">=" | "==" | "<>" +} + +void arithmetic_expression() : { +} { + (add_op())? term() (add_op() term())* +} + +void add_op() : { +} { + "+" | "-" | ".+" | ".-" +} + +void term() : { +} { + ( LOOKAHEAD(primary() power()) factor() | primary() ) ( (multiplication() | divide()) ( LOOKAHEAD(primary() power()) factor() | primary()) )* +} + +void factor() : { +} { + primary() power() primary() +} + +void power() : { +} { + "^" | ".^" +} +void multiplication() : { +} { + "*" | ".*" +} + +void divide() : { +} { + "/" | "./" +} + +void primary() : { +} { + value() + | LOOKAHEAD( name() parenthesis_open() ) function_call() + | component_reference_full() + /*| "(" output_expression_list() ")"*/ // Not needed, replaced with following: + | parenthesis_expression() + | "[" expression_list() ( ";" expression_list() )* "]" + | array_definition() + | "end" +} + +void component_reference_full() : { +} { + component_reference() +} + +void array_definition() : { +} { + "{" function_arguments() "}" +} + +void function_call() : { +} { + name() function_call_args() +} + +void parenthesis_expression() : { } { parenthesis_open() expression() parenthesis_close() +} + +void value() : { } { + + | + | + | "false" + | "true" +} + +void parenthesis_open() : { +} { + "(" +} + +void parenthesis_close() : { +} { + ")" +} + +void name() : { +} { + ( "." name() )? +} + +void component_reference() : { +} { + //IDENT [ array_subscripts ] [ "." component_reference ] + component_identity() ( array_subscripts() )? ( "." component_reference() )? +} + +void component_identity() : { +} { ()* +} + +void function_call_args() : { +} { + parenthesis_open() ( function_arguments() )? parenthesis_close() +} + +void function_arguments() : { +} { + //expression [ "," function_arguments | for for_indices ] + //| named_arguments + LOOKAHEAD(2) named_arguments() + | expression() ( "," function_arguments() | "for" for_indices() )? + +} + +void for_indices() : { +} { + //for_index {"," for_index} + for_index() ("," for_index())* +} + +void for_index() : { +} { + //IDENT [ in expression ] + ( "in" expression() )? +} + +void named_arguments() : { +} { + named_argument() ( "," named_arguments() )? +} + +void named_argument() : { +} { + "=" expression() +} + +void output_expression_list() : { +} { + ( expression() )? ( "," ( expression() )? )* +} + + +void expression_list() : { +} { + expression() ( "," expression() )* +} + +void array_subscripts() : { +} { + "[" subscript() ( "," subscript() )* "]" +} + +void subscript() : { +} { ":" + | LOOKAHEAD( name() parenthesis_open() ) function_call() + | rangeIndex() ( ":" rangeIndex())? +} + +void rangeIndex() : { +} { + | +} + diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParserConstants.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParserConstants.java new file mode 100644 index 00000000..1cef5de9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParserConstants.java @@ -0,0 +1,127 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. UnitParserConstants.java */ +package org.simantics.sysdyn.unitParser; + + +/** + * Token literal values and constants. + * Generated by org.javacc.parser.OtherFilesGen#start() + */ +public interface UnitParserConstants { + + /** End of File. */ + int EOF = 0; + /** RegularExpression Id. */ + int WHITESPACE = 1; + /** RegularExpression Id. */ + int COMMENT1 = 2; + /** RegularExpression Id. */ + int COMMENT2 = 3; + /** RegularExpression Id. */ + int IDENT = 88; + /** RegularExpression Id. */ + int STRING = 89; + /** RegularExpression Id. */ + int UNSIGNED_INTEGER = 90; + /** RegularExpression Id. */ + int UNSIGNED_NUMBER = 91; + + /** Lexical state. */ + int DEFAULT = 0; + + /** Literal token values. */ + String[] tokenImage = { + "", + "", + "", + "", + "\"algorithm\"", + "\"discrete\"", + "\"false\"", + "\"model\"", + "\"redeclare\"", + "\"and\"", + "\"each\"", + "\"final\"", + "\"not\"", + "\"replaceable\"", + "\"annotation\"", + "\"else\"", + "\"flow\"", + "\"operator\"", + "\"return\"", + "\"assert\"", + "\"elseif\"", + "\"for\"", + "\"or\"", + "\"stream\"", + "\"block\"", + "\"elsewhen\"", + "\"function\"", + "\"outer\"", + "\"then\"", + "\"break\"", + "\"encapsulated\"", + "\"if\"", + "\"output\"", + "\"true\"", + "\"class\"", + "\"end\"", + "\"import\"", + "\"package\"", + "\"type\"", + "\"connect\"", + "\"enumeration\"", + "\"in\"", + "\"parameter\"", + "\"when\"", + "\"connector\"", + "\"equation\"", + "\"partial\"", + "\"while\"", + "\"constant\"", + "\"expandable\"", + "\"inner\"", + "\"protected\"", + "\"within\"", + "\"constrainedby\"", + "\"extends\"", + "\"input\"", + "\"public\"", + "\"external\"", + "\"loop\"", + "\"record\"", + "\"(\"", + "\")\"", + "\"{\"", + "\"}\"", + "\"[\"", + "\"]\"", + "\".\"", + "\":\"", + "\";\"", + "\",\"", + "\"<\"", + "\"<=\"", + "\">\"", + "\">=\"", + "\"==\"", + "\"<>\"", + "\"+\"", + "\"-\"", + "\".+\"", + "\".-\"", + "\"*\"", + "\"/\"", + "\".*\"", + "\"./\"", + "\"^\"", + "\".^\"", + "\"=\"", + "\":=\"", + "", + "", + "", + "", + }; + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParserTokenManager.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParserTokenManager.java new file mode 100644 index 00000000..17e5dd5c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParserTokenManager.java @@ -0,0 +1,1395 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. UnitParserTokenManager.java */ +package org.simantics.sysdyn.unitParser; + +/** Token Manager. */ +public class UnitParserTokenManager implements UnitParserConstants +{ + + /** Debug output. */ + public java.io.PrintStream debugStream = System.out; + /** Set debug output. */ + public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } +private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1) +{ + switch (pos) + { + case 0: + if ((active0 & 0xffffffffffffff0L) != 0L) + { + jjmatchedKind = 88; + return 2; + } + if ((active1 & 0x20000L) != 0L) + return 13; + if ((active1 & 0x2cc004L) != 0L) + return 9; + return -1; + case 1: + if ((active0 & 0x84020080400000L) != 0L) + return 2; + if ((active0 & 0xf7bfdff7fbffff0L) != 0L) + { + if (jjmatchedPos != 1) + { + jjmatchedKind = 88; + jjmatchedPos = 1; + } + return 2; + } + return -1; + case 2: + if ((active0 & 0x800201200L) != 0L) + return 2; + if ((active0 & 0xffffdf77f9fedf0L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 2; + return 2; + } + return -1; + case 3: + if ((active0 & 0x400084212118400L) != 0L) + return 2; + if ((active0 & 0xbfff5b56d8e69f0L) != 0L) + { + if (jjmatchedPos != 3) + { + jjmatchedKind = 88; + jjmatchedPos = 3; + } + return 2; + } + return -1; + case 4: + if ((active0 & 0x848004290008c0L) != 0L) + return 2; + if ((active0 & 0xb7b75b1469e6130L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 4; + return 2; + } + return -1; + case 5: + if ((active0 & 0x9100011009c0000L) != 0L) + return 2; + if ((active0 & 0x26b75a046026130L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 5; + return 2; + } + return -1; + case 6: + if ((active0 & 0x4050a000000000L) != 0L) + return 2; + if ((active0 & 0x22b250046026130L) != 0L) + { + if (jjmatchedPos != 6) + { + jjmatchedKind = 88; + jjmatchedPos = 6; + } + return 2; + } + return -1; + case 7: + if ((active0 & 0x201200006020020L) != 0L) + return 2; + if ((active0 & 0x2a150040006110L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 7; + return 2; + } + return -1; + case 8: + if ((active0 & 0x22010040006000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 8; + return 2; + } + if ((active0 & 0x8140000000110L) != 0L) + return 2; + return -1; + case 9: + if ((active0 & 0x2000000004000L) != 0L) + return 2; + if ((active0 & 0x20010040002000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 9; + return 2; + } + return -1; + case 10: + if ((active0 & 0x10000002000L) != 0L) + return 2; + if ((active0 & 0x20000040000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 10; + return 2; + } + return -1; + case 11: + if ((active0 & 0x40000000L) != 0L) + return 2; + if ((active0 & 0x20000000000000L) != 0L) + { + jjmatchedKind = 88; + jjmatchedPos = 11; + return 2; + } + return -1; + default : + return -1; + } +} +private final int jjStartNfa_0(int pos, long active0, long active1) +{ + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1); +} +private int jjStopAtPos(int pos, int kind) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} +private int jjMoveStringLiteralDfa0_0() +{ + switch(curChar) + { + case 40: + return jjStopAtPos(0, 60); + case 41: + return jjStopAtPos(0, 61); + case 42: + return jjStopAtPos(0, 80); + case 43: + return jjStopAtPos(0, 76); + case 44: + return jjStopAtPos(0, 69); + case 45: + return jjStopAtPos(0, 77); + case 46: + jjmatchedKind = 66; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2cc000L); + case 47: + return jjStartNfaWithStates_0(0, 81, 13); + case 58: + jjmatchedKind = 67; + return jjMoveStringLiteralDfa1_0(0x0L, 0x800000L); + case 59: + return jjStopAtPos(0, 68); + case 60: + jjmatchedKind = 70; + return jjMoveStringLiteralDfa1_0(0x0L, 0x880L); + case 61: + jjmatchedKind = 86; + return jjMoveStringLiteralDfa1_0(0x0L, 0x400L); + case 62: + jjmatchedKind = 72; + return jjMoveStringLiteralDfa1_0(0x0L, 0x200L); + case 91: + return jjStopAtPos(0, 64); + case 93: + return jjStopAtPos(0, 65); + case 94: + return jjStopAtPos(0, 84); + case 97: + return jjMoveStringLiteralDfa1_0(0x84210L, 0x0L); + case 98: + return jjMoveStringLiteralDfa1_0(0x21000000L, 0x0L); + case 99: + return jjMoveStringLiteralDfa1_0(0x21108400000000L, 0x0L); + case 100: + return jjMoveStringLiteralDfa1_0(0x20L, 0x0L); + case 101: + return jjMoveStringLiteralDfa1_0(0x242210842108400L, 0x0L); + case 102: + return jjMoveStringLiteralDfa1_0(0x4210840L, 0x0L); + case 105: + return jjMoveStringLiteralDfa1_0(0x84021080000000L, 0x0L); + case 108: + return jjMoveStringLiteralDfa1_0(0x400000000000000L, 0x0L); + case 109: + return jjMoveStringLiteralDfa1_0(0x80L, 0x0L); + case 110: + return jjMoveStringLiteralDfa1_0(0x1000L, 0x0L); + case 111: + return jjMoveStringLiteralDfa1_0(0x108420000L, 0x0L); + case 112: + return jjMoveStringLiteralDfa1_0(0x108442000000000L, 0x0L); + case 114: + return jjMoveStringLiteralDfa1_0(0x800000000042100L, 0x0L); + case 115: + return jjMoveStringLiteralDfa1_0(0x800000L, 0x0L); + case 116: + return jjMoveStringLiteralDfa1_0(0x4210000000L, 0x0L); + case 119: + return jjMoveStringLiteralDfa1_0(0x10880000000000L, 0x0L); + case 123: + return jjStopAtPos(0, 62); + case 125: + return jjStopAtPos(0, 63); + default : + return jjMoveNfa_0(0, 0); + } +} +private int jjMoveStringLiteralDfa1_0(long active0, long active1) +{ + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(0, active0, active1); + return 1; + } + switch(curChar) + { + case 42: + if ((active1 & 0x40000L) != 0L) + return jjStopAtPos(1, 82); + break; + case 43: + if ((active1 & 0x4000L) != 0L) + return jjStopAtPos(1, 78); + break; + case 45: + if ((active1 & 0x8000L) != 0L) + return jjStopAtPos(1, 79); + break; + case 47: + if ((active1 & 0x80000L) != 0L) + return jjStopAtPos(1, 83); + break; + case 61: + if ((active1 & 0x80L) != 0L) + return jjStopAtPos(1, 71); + else if ((active1 & 0x200L) != 0L) + return jjStopAtPos(1, 73); + else if ((active1 & 0x400L) != 0L) + return jjStopAtPos(1, 74); + else if ((active1 & 0x800000L) != 0L) + return jjStopAtPos(1, 87); + break; + case 62: + if ((active1 & 0x800L) != 0L) + return jjStopAtPos(1, 75); + break; + case 94: + if ((active1 & 0x200000L) != 0L) + return jjStopAtPos(1, 85); + break; + case 97: + return jjMoveStringLiteralDfa2_0(active0, 0x442000000440L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa2_0(active0, 0x800000000042100L, active1, 0L); + case 102: + if ((active0 & 0x80000000L) != 0L) + return jjStartNfaWithStates_0(1, 31, 2); + break; + case 104: + return jjMoveStringLiteralDfa2_0(active0, 0x880010000000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa2_0(active0, 0x10000000000820L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa2_0(active0, 0x403118010L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa2_0(active0, 0x1000000000L, active1, 0L); + case 110: + if ((active0 & 0x20000000000L) != 0L) + { + jjmatchedKind = 41; + jjmatchedPos = 1; + } + return jjMoveStringLiteralDfa2_0(active0, 0x84010840004200L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa2_0(active0, 0x421108000201080L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa2_0(active0, 0x20000L, active1, 0L); + case 113: + return jjMoveStringLiteralDfa2_0(active0, 0x200000000000L, active1, 0L); + case 114: + if ((active0 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(1, 22, 2); + return jjMoveStringLiteralDfa2_0(active0, 0x8000220000000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa2_0(active0, 0x80000L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa2_0(active0, 0x800000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa2_0(active0, 0x10000010c000000L, active1, 0L); + case 120: + return jjMoveStringLiteralDfa2_0(active0, 0x242000000000000L, active1, 0L); + case 121: + return jjMoveStringLiteralDfa2_0(active0, 0x4000000000L, active1, 0L); + default : + break; + } + return jjStartNfa_0(0, active0, active1); +} +private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1) +{ + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(0, old0, old1); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(1, active0, 0L); + return 2; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa3_0(active0, 0x400000000L); + case 98: + return jjMoveStringLiteralDfa3_0(active0, 0x100000000000000L); + case 99: + return jjMoveStringLiteralDfa3_0(active0, 0x800002040000400L); + case 100: + if ((active0 & 0x200L) != 0L) + return jjStartNfaWithStates_0(2, 9, 2); + else if ((active0 & 0x800000000L) != 0L) + return jjStartNfaWithStates_0(2, 35, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x180L); + case 101: + return jjMoveStringLiteralDfa3_0(active0, 0x80030020000L); + case 103: + return jjMoveStringLiteralDfa3_0(active0, 0x10L); + case 105: + return jjMoveStringLiteralDfa3_0(active0, 0x800000000000L); + case 108: + return jjMoveStringLiteralDfa3_0(active0, 0x40L); + case 110: + return jjMoveStringLiteralDfa3_0(active0, 0x25108004004800L); + case 111: + return jjMoveStringLiteralDfa3_0(active0, 0x408000001010000L); + case 112: + return jjMoveStringLiteralDfa3_0(active0, 0x82005000002000L); + case 114: + if ((active0 & 0x200000L) != 0L) + return jjStartNfaWithStates_0(2, 21, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x440000800000L); + case 115: + return jjMoveStringLiteralDfa3_0(active0, 0x2188020L); + case 116: + if ((active0 & 0x1000L) != 0L) + return jjStartNfaWithStates_0(2, 12, 2); + return jjMoveStringLiteralDfa3_0(active0, 0x250000108040000L); + case 117: + return jjMoveStringLiteralDfa3_0(active0, 0x210200000000L); + default : + break; + } + return jjStartNfa_0(1, active0, 0L); +} +private int jjMoveStringLiteralDfa3_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(1, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(2, active0, 0L); + return 3; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa4_0(active0, 0x2240060000800L); + case 99: + return jjMoveStringLiteralDfa4_0(active0, 0x5000020L); + case 101: + if ((active0 & 0x8000L) != 0L) + { + jjmatchedKind = 15; + jjmatchedPos = 3; + } + else if ((active0 & 0x200000000L) != 0L) + return jjStartNfaWithStates_0(3, 33, 2); + else if ((active0 & 0x4000000000L) != 0L) + return jjStartNfaWithStates_0(3, 38, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x24400000a980180L); + case 104: + if ((active0 & 0x400L) != 0L) + return jjStartNfaWithStates_0(3, 10, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x10000000000000L); + case 107: + return jjMoveStringLiteralDfa4_0(active0, 0x2000000000L); + case 108: + return jjMoveStringLiteralDfa4_0(active0, 0x100800000002000L); + case 109: + return jjMoveStringLiteralDfa4_0(active0, 0x10000000000L); + case 110: + if ((active0 & 0x10000000L) != 0L) + return jjStartNfaWithStates_0(3, 28, 2); + else if ((active0 & 0x80000000000L) != 0L) + return jjStartNfaWithStates_0(3, 43, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x108000000000L); + case 111: + return jjMoveStringLiteralDfa4_0(active0, 0x800001000004010L); + case 112: + if ((active0 & 0x400000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 58, 2); + return jjMoveStringLiteralDfa4_0(active0, 0x100000000L); + case 114: + return jjMoveStringLiteralDfa4_0(active0, 0x20000L); + case 115: + return jjMoveStringLiteralDfa4_0(active0, 0x21000400000040L); + case 116: + return jjMoveStringLiteralDfa4_0(active0, 0x8400000000000L); + case 117: + return jjMoveStringLiteralDfa4_0(active0, 0x80000000040000L); + case 119: + if ((active0 & 0x10000L) != 0L) + return jjStartNfaWithStates_0(3, 16, 2); + break; + default : + break; + } + return jjStartNfa_0(2, active0, 0L); +} +private int jjMoveStringLiteralDfa4_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(2, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(3, active0, 0L); + return 4; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa5_0(active0, 0x2000822000L); + case 99: + return jjMoveStringLiteralDfa5_0(active0, 0x100L); + case 101: + if ((active0 & 0x40L) != 0L) + return jjStartNfaWithStates_0(4, 6, 2); + else if ((active0 & 0x800000000000L) != 0L) + return jjStartNfaWithStates_0(4, 47, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x8118000000000L); + case 105: + return jjMoveStringLiteralDfa5_0(active0, 0x110400000100000L); + case 107: + if ((active0 & 0x1000000L) != 0L) + return jjStartNfaWithStates_0(4, 24, 2); + else if ((active0 & 0x20000000L) != 0L) + return jjStartNfaWithStates_0(4, 29, 2); + break; + case 108: + if ((active0 & 0x80L) != 0L) + return jjStartNfaWithStates_0(4, 7, 2); + else if ((active0 & 0x800L) != 0L) + return jjStartNfaWithStates_0(4, 11, 2); + break; + case 109: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L); + case 110: + return jjMoveStringLiteralDfa5_0(active0, 0x42000000000000L); + case 112: + return jjMoveStringLiteralDfa5_0(active0, 0x40000000L); + case 114: + if ((active0 & 0x8000000L) != 0L) + return jjStartNfaWithStates_0(4, 27, 2); + else if ((active0 & 0x4000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 50, 2); + return jjMoveStringLiteralDfa5_0(active0, 0xa000010000c0030L); + case 115: + if ((active0 & 0x400000000L) != 0L) + return jjStartNfaWithStates_0(4, 34, 2); + break; + case 116: + if ((active0 & 0x80000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 55, 2); + return jjMoveStringLiteralDfa5_0(active0, 0x21200004004000L); + case 117: + return jjMoveStringLiteralDfa5_0(active0, 0x100000000L); + case 119: + return jjMoveStringLiteralDfa5_0(active0, 0x2000000L); + default : + break; + } + return jjStartNfa_0(3, active0, 0L); +} +private int jjMoveStringLiteralDfa5_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(3, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(4, active0, 0L); + return 5; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa6_0(active0, 0x1400000004000L); + case 99: + if ((active0 & 0x100000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 56, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x8108000002000L); + case 100: + if ((active0 & 0x800000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 59, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x42000000000000L); + case 101: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000020L); + case 102: + if ((active0 & 0x100000L) != 0L) + return jjStartNfaWithStates_0(5, 20, 2); + break; + case 103: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000000L); + case 104: + return jjMoveStringLiteralDfa6_0(active0, 0x2000000L); + case 105: + return jjMoveStringLiteralDfa6_0(active0, 0x200004000010L); + case 108: + return jjMoveStringLiteralDfa6_0(active0, 0x100L); + case 109: + if ((active0 & 0x800000L) != 0L) + return jjStartNfaWithStates_0(5, 23, 2); + break; + case 110: + if ((active0 & 0x40000L) != 0L) + return jjStartNfaWithStates_0(5, 18, 2); + else if ((active0 & 0x10000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 52, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x200000000000000L); + case 114: + return jjMoveStringLiteralDfa6_0(active0, 0x20010000000000L); + case 115: + return jjMoveStringLiteralDfa6_0(active0, 0x40000000L); + case 116: + if ((active0 & 0x80000L) != 0L) + return jjStartNfaWithStates_0(5, 19, 2); + else if ((active0 & 0x100000000L) != 0L) + return jjStartNfaWithStates_0(5, 32, 2); + else if ((active0 & 0x1000000000L) != 0L) + return jjStartNfaWithStates_0(5, 36, 2); + return jjMoveStringLiteralDfa6_0(active0, 0x20000L); + default : + break; + } + return jjStartNfa_0(4, active0, 0L); +} +private int jjMoveStringLiteralDfa6_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(4, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(5, active0, 0L); + return 6; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa7_0(active0, 0x222010000000100L); + case 101: + if ((active0 & 0x2000000000L) != 0L) + return jjStartNfaWithStates_0(6, 37, 2); + return jjMoveStringLiteralDfa7_0(active0, 0x2002000L); + case 108: + if ((active0 & 0x400000000000L) != 0L) + return jjStartNfaWithStates_0(6, 46, 2); + break; + case 110: + return jjMoveStringLiteralDfa7_0(active0, 0x1000000000000L); + case 111: + return jjMoveStringLiteralDfa7_0(active0, 0x200004020000L); + case 115: + if ((active0 & 0x40000000000000L) != 0L) + return jjStartNfaWithStates_0(6, 54, 2); + break; + case 116: + if ((active0 & 0x8000000000L) != 0L) + { + jjmatchedKind = 39; + jjmatchedPos = 6; + } + return jjMoveStringLiteralDfa7_0(active0, 0x8140000004030L); + case 117: + return jjMoveStringLiteralDfa7_0(active0, 0x40000000L); + default : + break; + } + return jjStartNfa_0(5, active0, 0L); +} +private int jjMoveStringLiteralDfa7_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(5, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(6, active0, 0L); + return 7; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa8_0(active0, 0x2000L); + case 98: + return jjMoveStringLiteralDfa8_0(active0, 0x2000000000000L); + case 101: + if ((active0 & 0x20L) != 0L) + return jjStartNfaWithStates_0(7, 5, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x8040000000000L); + case 104: + return jjMoveStringLiteralDfa8_0(active0, 0x10L); + case 105: + return jjMoveStringLiteralDfa8_0(active0, 0x20000000004000L); + case 108: + if ((active0 & 0x200000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 57, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x40000000L); + case 110: + if ((active0 & 0x2000000L) != 0L) + return jjStartNfaWithStates_0(7, 25, 2); + else if ((active0 & 0x4000000L) != 0L) + return jjStartNfaWithStates_0(7, 26, 2); + else if ((active0 & 0x200000000000L) != 0L) + return jjStartNfaWithStates_0(7, 45, 2); + break; + case 111: + return jjMoveStringLiteralDfa8_0(active0, 0x100000000000L); + case 114: + if ((active0 & 0x20000L) != 0L) + return jjStartNfaWithStates_0(7, 17, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x100L); + case 116: + if ((active0 & 0x1000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 48, 2); + return jjMoveStringLiteralDfa8_0(active0, 0x10000000000L); + default : + break; + } + return jjStartNfa_0(6, active0, 0L); +} +private int jjMoveStringLiteralDfa8_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(6, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(7, active0, 0L); + return 8; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa9_0(active0, 0x40000000L); + case 98: + return jjMoveStringLiteralDfa9_0(active0, 0x2000L); + case 100: + if ((active0 & 0x8000000000000L) != 0L) + return jjStartNfaWithStates_0(8, 51, 2); + break; + case 101: + if ((active0 & 0x100L) != 0L) + return jjStartNfaWithStates_0(8, 8, 2); + break; + case 105: + return jjMoveStringLiteralDfa9_0(active0, 0x10000000000L); + case 108: + return jjMoveStringLiteralDfa9_0(active0, 0x2000000000000L); + case 109: + if ((active0 & 0x10L) != 0L) + return jjStartNfaWithStates_0(8, 4, 2); + break; + case 110: + return jjMoveStringLiteralDfa9_0(active0, 0x20000000000000L); + case 111: + return jjMoveStringLiteralDfa9_0(active0, 0x4000L); + case 114: + if ((active0 & 0x40000000000L) != 0L) + return jjStartNfaWithStates_0(8, 42, 2); + else if ((active0 & 0x100000000000L) != 0L) + return jjStartNfaWithStates_0(8, 44, 2); + break; + default : + break; + } + return jjStartNfa_0(7, active0, 0L); +} +private int jjMoveStringLiteralDfa9_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(7, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(8, active0, 0L); + return 9; + } + switch(curChar) + { + case 101: + if ((active0 & 0x2000000000000L) != 0L) + return jjStartNfaWithStates_0(9, 49, 2); + return jjMoveStringLiteralDfa10_0(active0, 0x20000000000000L); + case 108: + return jjMoveStringLiteralDfa10_0(active0, 0x2000L); + case 110: + if ((active0 & 0x4000L) != 0L) + return jjStartNfaWithStates_0(9, 14, 2); + break; + case 111: + return jjMoveStringLiteralDfa10_0(active0, 0x10000000000L); + case 116: + return jjMoveStringLiteralDfa10_0(active0, 0x40000000L); + default : + break; + } + return jjStartNfa_0(8, active0, 0L); +} +private int jjMoveStringLiteralDfa10_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(8, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(9, active0, 0L); + return 10; + } + switch(curChar) + { + case 100: + return jjMoveStringLiteralDfa11_0(active0, 0x20000000000000L); + case 101: + if ((active0 & 0x2000L) != 0L) + return jjStartNfaWithStates_0(10, 13, 2); + return jjMoveStringLiteralDfa11_0(active0, 0x40000000L); + case 110: + if ((active0 & 0x10000000000L) != 0L) + return jjStartNfaWithStates_0(10, 40, 2); + break; + default : + break; + } + return jjStartNfa_0(9, active0, 0L); +} +private int jjMoveStringLiteralDfa11_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(9, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(10, active0, 0L); + return 11; + } + switch(curChar) + { + case 98: + return jjMoveStringLiteralDfa12_0(active0, 0x20000000000000L); + case 100: + if ((active0 & 0x40000000L) != 0L) + return jjStartNfaWithStates_0(11, 30, 2); + break; + default : + break; + } + return jjStartNfa_0(10, active0, 0L); +} +private int jjMoveStringLiteralDfa12_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(10, old0, 0L); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(11, active0, 0L); + return 12; + } + switch(curChar) + { + case 121: + if ((active0 & 0x20000000000000L) != 0L) + return jjStartNfaWithStates_0(12, 53, 2); + break; + default : + break; + } + return jjStartNfa_0(11, active0, 0L); +} +private int jjStartNfaWithStates_0(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_0(state, pos + 1); +} +static final long[] jjbitVec0 = { + 0x0L, 0x0L, 0x20000800000000L, 0x0L +}; +static final long[] jjbitVec1 = { + 0x0L, 0x0L, 0xfffffffffffe0000L, 0x3ffL +}; +static final long[] jjbitVec2 = { + 0x0L, 0x0L, 0x100000000000L, 0x0L +}; +static final long[] jjbitVec3 = { + 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +static final long[] jjbitVec5 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +private int jjMoveNfa_0(int startState, int curPos) +{ + int startsAt = 0; + jjnewStateCnt = 31; + int i = 1; + jjstateSet[0] = startState; + int kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + do + { + switch(jjstateSet[--i]) + { + case 13: + if (curChar == 47) + { + if (kind > 3) + kind = 3; + jjCheckNAdd(20); + } + else if (curChar == 42) + jjCheckNAddStates(0, 2); + break; + case 0: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 90) + kind = 90; + jjCheckNAddStates(3, 7); + } + else if ((0x100002600L & l) != 0L) + { + if (kind > 1) + kind = 1; + } + else if ((0x3000000000L & l) != 0L) + { + if (kind > 88) + kind = 88; + jjCheckNAdd(2); + } + else if (curChar == 47) + jjAddStates(8, 9); + else if (curChar == 46) + jjCheckNAdd(9); + else if (curChar == 34) + jjCheckNAddStates(10, 12); + break; + case 1: + if ((0x3000000000L & l) == 0L) + break; + if (kind > 88) + kind = 88; + jjCheckNAdd(2); + break; + case 2: + if ((0x3ff003000000000L & l) == 0L) + break; + if (kind > 88) + kind = 88; + jjCheckNAdd(2); + break; + case 3: + if (curChar == 34) + jjCheckNAddStates(10, 12); + break; + case 4: + if ((0xfffffffbfffffbffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 6: + if ((0xfffffffffffffbffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 7: + if (curChar == 34 && kind > 89) + kind = 89; + break; + case 8: + if (curChar == 46) + jjCheckNAdd(9); + break; + case 9: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAddTwoStates(9, 10); + break; + case 11: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjstateSet[jjnewStateCnt++] = 11; + break; + case 12: + if (curChar == 47) + jjAddStates(8, 9); + break; + case 14: + if ((0xfffffbffffffffffL & l) != 0L) + jjCheckNAddStates(0, 2); + break; + case 15: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 16; + break; + case 16: + if ((0xffff7fffffffffffL & l) != 0L) + jjCheckNAddStates(0, 2); + break; + case 17: + if (curChar == 47 && kind > 2) + kind = 2; + break; + case 18: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 17; + break; + case 19: + if (curChar != 47) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(20); + break; + case 20: + if ((0xfffffffffffffbffL & l) == 0L) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(20); + break; + case 21: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjCheckNAddStates(3, 7); + break; + case 22: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 90) + kind = 90; + jjCheckNAdd(22); + break; + case 23: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(23, 24); + break; + case 24: + if (curChar != 46) + break; + if (kind > 91) + kind = 91; + jjCheckNAddTwoStates(25, 26); + break; + case 25: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjCheckNAddTwoStates(25, 26); + break; + case 27: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjstateSet[jjnewStateCnt++] = 27; + break; + case 28: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(28, 29); + break; + case 30: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 91) + kind = 91; + jjstateSet[jjnewStateCnt++] = 30; + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 0: + case 2: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 88) + kind = 88; + jjCheckNAdd(2); + break; + case 4: + if ((0xffffffffefffffffL & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 5: + if (curChar == 92) + jjstateSet[jjnewStateCnt++] = 6; + break; + case 6: + jjCheckNAddStates(10, 12); + break; + case 10: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 11; + break; + case 14: + case 16: + jjCheckNAddStates(0, 2); + break; + case 20: + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 20; + break; + case 26: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 27; + break; + case 29: + if ((0x2000000020L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 30; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int hiByte = (int)(curChar >> 8); + int i1 = hiByte >> 6; + long l1 = 1L << (hiByte & 077); + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 0: + case 2: + if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) + break; + if (kind > 88) + kind = 88; + jjCheckNAdd(2); + break; + case 4: + case 6: + if (jjCanMove_1(hiByte, i1, i2, l1, l2)) + jjCheckNAddStates(10, 12); + break; + case 14: + case 16: + if (jjCanMove_2(hiByte, i1, i2, l1, l2)) + jjCheckNAddStates(0, 2); + break; + case 20: + if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) + break; + if (kind > 3) + kind = 3; + jjstateSet[jjnewStateCnt++] = 20; + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 31 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +static final int[] jjnextStates = { + 14, 15, 18, 22, 23, 24, 28, 29, 13, 19, 4, 5, 7, +}; +private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) +{ + switch(hiByte) + { + case 0: + return ((jjbitVec0[i2] & l2) != 0L); + case 3: + return ((jjbitVec1[i2] & l2) != 0L); + case 32: + return ((jjbitVec2[i2] & l2) != 0L); + default : + return false; + } +} +private static final boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2) +{ + switch(hiByte) + { + case 0: + return ((jjbitVec5[i2] & l2) != 0L); + default : + if ((jjbitVec3[i1] & l1) != 0L) + return true; + return false; + } +} +private static final boolean jjCanMove_2(int hiByte, int i1, int i2, long l1, long l2) +{ + switch(hiByte) + { + case 0: + return ((jjbitVec5[i2] & l2) != 0L); + default : + return false; + } +} + +/** Token literal values. */ +public static final String[] jjstrLiteralImages = { +"", null, null, null, "\141\154\147\157\162\151\164\150\155", +"\144\151\163\143\162\145\164\145", "\146\141\154\163\145", "\155\157\144\145\154", +"\162\145\144\145\143\154\141\162\145", "\141\156\144", "\145\141\143\150", "\146\151\156\141\154", "\156\157\164", +"\162\145\160\154\141\143\145\141\142\154\145", "\141\156\156\157\164\141\164\151\157\156", "\145\154\163\145", +"\146\154\157\167", "\157\160\145\162\141\164\157\162", "\162\145\164\165\162\156", +"\141\163\163\145\162\164", "\145\154\163\145\151\146", "\146\157\162", "\157\162", +"\163\164\162\145\141\155", "\142\154\157\143\153", "\145\154\163\145\167\150\145\156", +"\146\165\156\143\164\151\157\156", "\157\165\164\145\162", "\164\150\145\156", "\142\162\145\141\153", +"\145\156\143\141\160\163\165\154\141\164\145\144", "\151\146", "\157\165\164\160\165\164", "\164\162\165\145", +"\143\154\141\163\163", "\145\156\144", "\151\155\160\157\162\164", "\160\141\143\153\141\147\145", +"\164\171\160\145", "\143\157\156\156\145\143\164", +"\145\156\165\155\145\162\141\164\151\157\156", "\151\156", "\160\141\162\141\155\145\164\145\162", "\167\150\145\156", +"\143\157\156\156\145\143\164\157\162", "\145\161\165\141\164\151\157\156", "\160\141\162\164\151\141\154", +"\167\150\151\154\145", "\143\157\156\163\164\141\156\164", +"\145\170\160\141\156\144\141\142\154\145", "\151\156\156\145\162", "\160\162\157\164\145\143\164\145\144", +"\167\151\164\150\151\156", "\143\157\156\163\164\162\141\151\156\145\144\142\171", +"\145\170\164\145\156\144\163", "\151\156\160\165\164", "\160\165\142\154\151\143", +"\145\170\164\145\162\156\141\154", "\154\157\157\160", "\162\145\143\157\162\144", "\50", "\51", "\173", "\175", +"\133", "\135", "\56", "\72", "\73", "\54", "\74", "\74\75", "\76", "\76\75", +"\75\75", "\74\76", "\53", "\55", "\56\53", "\56\55", "\52", "\57", "\56\52", "\56\57", +"\136", "\56\136", "\75", "\72\75", null, null, null, null, }; + +/** Lexer state names. */ +public static final String[] lexStateNames = { + "DEFAULT", +}; +static final long[] jjtoToken = { + 0xfffffffffffffff1L, 0xfffffffL, +}; +static final long[] jjtoSkip = { + 0xeL, 0x0L, +}; +protected SimpleCharStream input_stream; +private final int[] jjrounds = new int[31]; +private final int[] jjstateSet = new int[62]; +private final StringBuilder jjimage = new StringBuilder(); +private StringBuilder image = jjimage; +private int jjimageLen; +private int lengthOfMatch; +protected char curChar; +/** Constructor. */ +public UnitParserTokenManager(SimpleCharStream stream){ + if (SimpleCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + input_stream = stream; +} + +/** Constructor. */ +public UnitParserTokenManager(SimpleCharStream stream, int lexState){ + this(stream); + SwitchTo(lexState); +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream) +{ + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); +} +private void ReInitRounds() +{ + int i; + jjround = 0x80000001; + for (i = 31; i-- > 0;) + jjrounds[i] = 0x80000000; +} + +/** Reinitialise parser. */ +public void ReInit(SimpleCharStream stream, int lexState) +{ + ReInit(stream); + SwitchTo(lexState); +} + +/** Switch to specified lex state. */ +public void SwitchTo(int lexState) +{ + if (lexState >= 1 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); + else + curLexState = lexState; +} + +protected Token jjFillToken() +{ + final Token t; + final String curTokenImage; + final int beginLine; + final int endLine; + final int beginColumn; + final int endColumn; + String im = jjstrLiteralImages[jjmatchedKind]; + curTokenImage = (im == null) ? input_stream.GetImage() : im; + beginLine = input_stream.getBeginLine(); + beginColumn = input_stream.getBeginColumn(); + endLine = input_stream.getEndLine(); + endColumn = input_stream.getEndColumn(); + t = Token.newToken(jjmatchedKind, curTokenImage); + + t.beginLine = beginLine; + t.endLine = endLine; + t.beginColumn = beginColumn; + t.endColumn = endColumn; + + return t; +} + +int curLexState = 0; +int defaultLexState = 0; +int jjnewStateCnt; +int jjround; +int jjmatchedPos; +int jjmatchedKind; + +/** Get the next Token. */ +public Token getNextToken() +{ + Token matchedToken; + int curPos = 0; + + EOFLoop : + for (;;) + { + try + { + curChar = input_stream.BeginToken(); + } + catch(java.io.IOException e) + { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + } + image = jjimage; + image.setLength(0); + jjimageLen = 0; + + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + if (jjmatchedKind != 0x7fffffff) + { + if (jjmatchedPos + 1 < curPos) + input_stream.backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) + { + matchedToken = jjFillToken(); + TokenLexicalActions(matchedToken); + return matchedToken; + } + else + { + continue EOFLoop; + } + } + int error_line = input_stream.getEndLine(); + int error_column = input_stream.getEndColumn(); + String error_after = null; + boolean EOFSeen = false; + try { input_stream.readChar(); input_stream.backup(1); } + catch (java.io.IOException e1) { + EOFSeen = true; + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + if (curChar == '\n' || curChar == '\r') { + error_line++; + error_column = 0; + } + else + error_column++; + } + if (!EOFSeen) { + input_stream.backup(1); + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + } + throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); + } +} + +void TokenLexicalActions(Token matchedToken) +{ + switch(jjmatchedKind) + { + case 89 : + image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); + matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); + break; + default : + break; + } +} +private void jjCheckNAdd(int state) +{ + if (jjrounds[state] != jjround) + { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } +} +private void jjAddStates(int start, int end) +{ + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); +} +private void jjCheckNAddTwoStates(int state1, int state2) +{ + jjCheckNAdd(state1); + jjCheckNAdd(state2); +} + +private void jjCheckNAddStates(int start, int end) +{ + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); +} + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParserTreeConstants.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParserTreeConstants.java new file mode 100644 index 00000000..656c2382 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParserTreeConstants.java @@ -0,0 +1,89 @@ +/* Generated By:JavaCC: Do not edit this line. UnitParserTreeConstants.java Version 5.0 */ +package org.simantics.sysdyn.unitParser; + +public interface UnitParserTreeConstants +{ + public int JJTEXPR = 0; + public int JJTEXPRESSION = 1; + public int JJTIFTHENELSE = 2; + public int JJTCONDITION = 3; + public int JJTSIMPLE_EXPRESSION = 4; + public int JJTLOGICAL_EXPRESSION = 5; + public int JJTLOGICAL_TERM = 6; + public int JJTLOGICAL_FACTOR = 7; + public int JJTRELATION = 8; + public int JJTREL_OP = 9; + public int JJTARITHMETIC_EXPRESSION = 10; + public int JJTADD_OP = 11; + public int JJTTERM = 12; + public int JJTFACTOR = 13; + public int JJTPOWER = 14; + public int JJTMULTIPLICATION = 15; + public int JJTDIVIDE = 16; + public int JJTPRIMARY = 17; + public int JJTCOMPONENT_REFERENCE_FULL = 18; + public int JJTARRAY_DEFINITION = 19; + public int JJTFUNCTION_CALL = 20; + public int JJTPARENTHESIS_EXPRESSION = 21; + public int JJTVALUE = 22; + public int JJTPARENTHESIS_OPEN = 23; + public int JJTPARENTHESIS_CLOSE = 24; + public int JJTNAME = 25; + public int JJTCOMPONENT_REFERENCE = 26; + public int JJTCOMPONENT_IDENTITY = 27; + public int JJTFUNCTION_CALL_ARGS = 28; + public int JJTFUNCTION_ARGUMENTS = 29; + public int JJTFOR_INDICES = 30; + public int JJTFOR_INDEX = 31; + public int JJTNAMED_ARGUMENTS = 32; + public int JJTNAMED_ARGUMENT = 33; + public int JJTOUTPUT_EXPRESSION_LIST = 34; + public int JJTEXPRESSION_LIST = 35; + public int JJTARRAY_SUBSCRIPTS = 36; + public int JJTSUBSCRIPT = 37; + public int JJTRANGEINDEX = 38; + + + public String[] jjtNodeName = { + "expr", + "expression", + "ifthenelse", + "condition", + "simple_expression", + "logical_expression", + "logical_term", + "logical_factor", + "relation", + "rel_op", + "arithmetic_expression", + "add_op", + "term", + "factor", + "power", + "multiplication", + "divide", + "primary", + "component_reference_full", + "array_definition", + "function_call", + "parenthesis_expression", + "value", + "parenthesis_open", + "parenthesis_close", + "name", + "component_reference", + "component_identity", + "function_call_args", + "function_arguments", + "for_indices", + "for_index", + "named_arguments", + "named_argument", + "output_expression_list", + "expression_list", + "array_subscripts", + "subscript", + "rangeIndex", + }; +} +/* JavaCC - OriginalChecksum=55cc0533e9e24a32b3fbe9bcd56ca148 (do not edit this line) */ diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java new file mode 100644 index 00000000..6aafee9c --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class AddOp extends UnitCheckingNode { + + public AddOp(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); + result.setUnitType(UnitType.OPERATOR); + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java new file mode 100644 index 00000000..44bb2e21 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class Arithmetic extends UnitCheckingNode { + + public Arithmetic(int id) { + super(id); + } + + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = new UnitResult(allowEquivalents); + + UnitCheckingNode base = null; + UnitCheckingNode operator = null; + UnitCheckingNode candidateNode = null; + + for(int i = 0; i < jjtGetNumChildren(); i++) { + candidateNode = ((UnitCheckingNode)jjtGetChild(i)); + UnitResult candidateUnits = candidateNode.getUnits(units, functions, allowEquivalents); + if(candidateUnits.getUnitType() == UnitType.OPERATOR) { + continue; + } else if(base == null || result.getUnitType() == UnitType.SCALAR || result.getUnitType() == UnitType.ANY) { + base = ((UnitCheckingNode)jjtGetChild(i)); + result.appendResult(base.getUnits(units, functions, allowEquivalents)); + continue; + } else if(candidateUnits.getUnitType() == UnitType.SCALAR) { + continue; + } else { + operator = ((UnitCheckingNode)jjtGetChild(i-1)); + if(!result.equals(candidateUnits)) { + throw new UnitCheckingException("Not equals exception: " + + base.printNode() + " [" + result.getCleanFullUnit() + "] " + operator.printNode() + " " + + candidateNode.printNode() + " [" + candidateUnits.getCleanFullUnit() + "]" + ); + } + } + } +// System.out.println("Arithmetic: " + printNode() + " [" + result.getFullUnit() + " : " + result.getUnitType() + "]"); + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ArrayDefinition.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ArrayDefinition.java new file mode 100644 index 00000000..9754bd3e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ArrayDefinition.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ArrayDefinition extends UnitCheckingNode { + + public ArrayDefinition(int id) { + super(id); + } + + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = new UnitResult(allowEquivalents); + result.setUnitType(UnitType.SCALAR); + + UnitCheckingNode base = null; + + if(jjtGetNumChildren() > 0 && jjtGetChild(0) instanceof FunctionArguments) { + FunctionArguments functionArguments = (FunctionArguments) jjtGetChild(0); + + for(UnitCheckingNode candidateNode : gatherExpressions(functionArguments, new ArrayList())) { + UnitResult candidateUnits = candidateNode.getUnits(units, functions, allowEquivalents); + if(candidateUnits.getUnitType() == UnitType.SCALAR) { + continue; + } else if(base == null) { + base = candidateNode; + UnitType oldUnitType = result.getUnitType(); + result.appendResult(base.getUnits(units, functions, allowEquivalents)); + + /* + * Make sure unit type persist + * {Var1, Var2, 1} would result in UnitType.SCALAR even though it should be UnitType.NORMAL + * because the last element has UnitType.SCALAR + */ + UnitType newUnitType = result.getUnitType(); + if(newUnitType == UnitType.SCALAR || newUnitType == UnitType.ANY || newUnitType == UnitType.DMNL) + result.setUnitType(oldUnitType); + continue; + } else { + if(!result.equals(candidateUnits)) { + throw new UnitCheckingException("Array elements do not have same units: " + + base.printNode() + " [" + result.getCleanFullUnit() + "] =/= " + + candidateNode.printNode() + " [" + candidateUnits.getCleanFullUnit() + "]" + ); + } + } + } + } + + return result; + } + + /** + * Gather all expressions of array definitions. + * + * void function_arguments() : { + * } { + * LOOKAHEAD(2) named_argument() ( "," function_arguments() )? + * | expression() ( "," function_arguments() | "for" for_indices() )? + * + * } + * @param functionArguments + * @param expressions + * @return + */ + private ArrayList gatherExpressions(UnitCheckingNode functionArguments, ArrayList expressions) { + if(functionArguments.jjtGetNumChildren() > 0) { + if(functionArguments.jjtGetChild(0) instanceof Expression) { + expressions.add(((UnitCheckingNode)functionArguments.jjtGetChild(0))); + } + } + + if(functionArguments.jjtGetNumChildren() > 1) { + gatherExpressions((UnitCheckingNode)functionArguments.jjtGetChild(1), expressions); + } + + return expressions; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentIdentity.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentIdentity.java new file mode 100644 index 00000000..8d90375e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentIdentity.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import org.simantics.sysdyn.unitParser.Token; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class ComponentIdentity extends UnitCheckingNode { + + public ComponentIdentity(int id) { + super(id); + } + + @Override + public String printNode() { + StringBuilder sb = new StringBuilder(); + Token token = jjtGetFirstToken(); + sb.append(token.image); + + while(token != null && !token.equals(jjtGetLastToken())) { + sb.append(" "); + token = token.next; + sb.append(token.image); + } + return sb.toString(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReference.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReference.java new file mode 100644 index 00000000..b9541bbd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReference.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class ComponentReference extends UnitCheckingNode { + + public ComponentReference(int id) { + super(id); + } + + @Override + public String printNode() { + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < jjtGetNumChildren(); i++) { + UnitCheckingNode node = (UnitCheckingNode) jjtGetChild(i); + if(node instanceof ComponentIdentity || node instanceof ComponentReference) { + if(sb.length() > 0) + sb.append("."); + sb.append(node.printNode()); + } + } + return sb.toString(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java new file mode 100644 index 00000000..fa8e959b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.ParseException; +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.UnitParser; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ComponentReferenceFull extends UnitCheckingNode { + + public ComponentReferenceFull(int id) { + super(id); + } + + protected UnitResult parseUnits(String units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + StringReader sr = new StringReader(units); + UnitParser parser = new UnitParser(sr); + try { + UnitCheckingNode node = (UnitCheckingNode) parser.expr(); + return node.getUnits(null, functions, allowEquivalents); + } catch (UnitCheckingException e) { + e.printStackTrace(); + } catch (ParseException e) { + throw new UnitCheckingException("Cannot validate units: Syntax error in expression."); + } + return null; + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + String node = printNode(); + + if("dmnl".equals(node)) { + UnitResult result = new UnitResult(allowEquivalents); + result.setUnitType(UnitType.DMNL); + return result; + } + + if(units != null) { + if(!units.containsKey(node) || units.get(node) == null) + throw new UnitCheckingException("No units defined for " + node); + else { + return parseUnits(units.get(node), functions, allowEquivalents); + } + } else { + UnitResult result = new UnitResult(allowEquivalents); + result.addDivident(node); + result.append(node); + return result; + } + } + + @Override + public String printNode() { + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < jjtGetNumChildren(); i++) { + UnitCheckingNode node = (UnitCheckingNode) jjtGetChild(i); + sb.append(node.printNode()); + } + return sb.toString(); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Condition.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Condition.java new file mode 100644 index 00000000..c382cda3 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Condition.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class Condition extends UnitCheckingNode { + + public Condition(int id) { + super(id); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java new file mode 100644 index 00000000..c2061059 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class Divide extends UnitCheckingNode { + + public Divide(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); + result.setUnitType(UnitType.OPERATOR); + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Expression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Expression.java new file mode 100644 index 00000000..eb3ec7f7 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Expression.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class Expression extends UnitCheckingNode { + + public Expression(int id) { + super(id); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java new file mode 100644 index 00000000..fc92f871 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Factor.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.Token; +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Tuomas Miettinen + * @author Teemu Lempinen + * + */ +public class Factor extends UnitCheckingNode { + + public Factor(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = new UnitResult(allowEquivalents); + + UnitCheckingNode current = null; + UnitCheckingNode operator = null; + UnitCheckingNode base = null; + + for(int i = 0; i < jjtGetNumChildren(); i++) { + current = ((UnitCheckingNode)jjtGetChild(i)); + UnitResult currentUnits = current.getUnits(units, functions, allowEquivalents); + + if(currentUnits.getUnitType() == UnitType.ANY) { + result = new UnitResult(allowEquivalents); + result.setUnitType(UnitType.ANY); + return result; + } else if(currentUnits.getUnitType() == UnitType.OPERATOR) { + continue; + } else if(base == null) { + base = current; + continue; + } else { + operator = ((UnitCheckingNode)jjtGetChild(i-1)); + + if(operator instanceof Power) { + UnitType unitType = currentUnits.getUnitType(); + if(unitType == UnitType.SCALAR) { + int exponent; + UnitResult baseUnits = base.getUnits(units, functions, allowEquivalents); + try { + exponent = Integer.valueOf(currentUnits.getFullUnit()); + } catch (NumberFormatException e) { + exponent = 1; /* It's a bit of a corner case if someone want's to use + an arithmetic expression other than a constant in the exponent. */ + } + + if (exponent < 0) { + for (int j = 0; j > exponent; --j) { + // Negative exponent turns the base number around. + result.addAllDividers(baseUnits.getDividents()); + result.addAllDividents(baseUnits.getDividers()); + result.append(operator.printNode()); + result.append(baseUnits.getFullUnit()); + } + result.setUnitType(baseUnits.getUnitType()); + } else if (exponent > 0) { + result.appendResult(baseUnits); + for (int j = 1; j < exponent; ++j) { + result.addAllDividents(baseUnits.getDividents()); + result.addAllDividers(baseUnits.getDividers()); + result.append(operator.printNode()); + result.append(baseUnits.getFullUnit()); + } + result.setUnitType(baseUnits.getUnitType()); + } // 0 is a corner case + } + } + } + } +// System.out.println("Term: " + printNode() + " [" + result.getFullUnit() + " : " + result.getUnitType() + "]"); + return result; + } + + @Override + public String printNode() { + StringBuilder sb = new StringBuilder(); + Token token = jjtGetFirstToken(); + sb.append(token.image); + + Token prevToken = null; + while(token != null && !token.equals(jjtGetLastToken())) { + prevToken = token; + token = token.next; + if(!token.image.equals("[") + && !token.image.equals("]") + && !prevToken.image.equals("[") + && !prevToken.image.equals("]") + && !token.image.equals(".") + && !prevToken.image.equals(".")) + sb.append(" "); + sb.append(token.image); + } + return sb.toString(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java new file mode 100644 index 00000000..40889a10 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class ForIndex extends UnitCheckingNode { + + public ForIndex(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + return new UnitResult(allowEquivalents); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionArguments.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionArguments.java new file mode 100644 index 00000000..3921d3cf --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionArguments.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class FunctionArguments extends UnitCheckingNode { + + public FunctionArguments(int id) { + super(id); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java new file mode 100644 index 00000000..0832b0df --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/FunctionCall.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; +import org.simantics.sysdyn.utils.Function.Input; +import org.simantics.sysdyn.utils.Function.Output; +import org.simantics.utils.datastructures.Pair; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class FunctionCall extends UnitCheckingNode { + + public FunctionCall(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitCheckingNode functionLabelNode = ((UnitCheckingNode)jjtGetChild(0)); + String functionLabel = functionLabelNode.printNode(); + + UnitCheckingNode functionArgumentsWithParenthesisNode = ((UnitCheckingNode)jjtGetChild(1)); + UnitCheckingNode functionArgumentsNode = ((UnitCheckingNode)functionArgumentsWithParenthesisNode.jjtGetChild(1)); + + UnitCheckingException u = null; + + for (Function f : functions) { + if (f.getName().equals(functionLabel)) { + // Get the expected inputs + ArrayList inputs = f.getInputList(); + // Get arguments from parser. + ArrayList> argumentUnits = getArgumentsOf(functionArgumentsNode, units, functions, allowEquivalents); + // Get correspondent actual units for unit templates in inputs. + HashMap correspondences = getReplacementUnitCorrespondences(inputs, argumentUnits); + + try { + // If the function input parameter units are OK, set the output unit accordingly. + if (f.areArgumentUnitsValid(argumentUnits, correspondences, functions, allowEquivalents, units)) { + Output o = f.getOutputList().get(0); // Support only single return value functions. + return o.getUnitResult(units, f, functions, allowEquivalents, correspondences); + } + + // Create the exception when we first time arrive here, since the functions + // are sorted so that scalar functions are before vector ones and there are + // a few duplicates, so this way the exception message is more likely useful. + if (u == null) + u = getException(functionLabelNode, inputs, argumentUnits); + // There may be similarly named functions, so if one doesn't succeed, go through the rest of the list anyway. + } catch (UnitCheckingException e) { + u = e; // Override the general exception with a more specific one. + } + } + } + + if (u == null) { + UnitResult result = new UnitResult(allowEquivalents); + result.setUnitType(UnitType.ANY); // The function was not found. + return result; + } + + throw u; + } + + private static HashMap getReplacementUnitCorrespondences( + ArrayList inputs, ArrayList> argumentUnits) { + // TODO: General case. Currently each 'p, 'q etc. must exist as an atomic unit. + HashMap correspondences = new HashMap(); + for (int i = 0; i < argumentUnits.size(); ++i) { + if (argumentUnits.get(i).second != null) { // named arguments + for (Input input : inputs) { + if (input.name.equals(argumentUnits.get(i).second)) { + addPossibleCorrespondence(correspondences, input, argumentUnits.get(i).first); + } + } + } else if (inputs.size() > i) { + addPossibleCorrespondence(correspondences, inputs.get(i), argumentUnits.get(i).first); + } + } + // If there is no mapping between the actual and defined inputs (e.g. 'p refers to both m and s), + // then return the latest correspondence. The users of this functions currently assume such behavior. + return correspondences; + } + + private static void addPossibleCorrespondence(HashMap correspondences, + Input input, UnitResult argumentUnit) { + if (correspondences.containsKey(input.unit) + && argumentUnit.getUnitType() == UnitType.SCALAR) { + // Don't overwrite if the correspondence already exists and the new argument is scalar. + return; + } + if (input.unit.matches("'[a-zA-Z]")) { + String fullUnit = argumentUnit.getCleanFullUnit(); + if ("".equals(fullUnit)) + fullUnit = "1"; + correspondences.put(input.unit, fullUnit); + } + } + + /** + * Get the exception (text) shown to user. + * @param functionLabelNode + * @param inputs + * @param argumentUnits + * @return + */ + private static UnitCheckingException getException(UnitCheckingNode functionLabelNode, + ArrayList inputs, + ArrayList> argumentUnits) { + String exception = new String("Function arguments do not have correct units. Expected " + functionLabelNode.printNode() + "("); + + for (int i = 0; i < inputs.size(); ++i) { + Input input = inputs.get(i); + if (i == 0) + exception += " "; + exception += "[" + input.unit + "]"; + if (input.variableLength) { + exception += "... "; + } + + if (i != inputs.size() - 1) + exception += ", "; + } + exception += " ), got " + functionLabelNode.printNode() + "("; + for (int i = 0; i < argumentUnits.size(); ++i) { + UnitResult argumentUnit = argumentUnits.get(i).first; + if (i == 0) + exception += " "; + exception += "[" + argumentUnit.getCleanFullUnit() + "]"; + + if (i != argumentUnits.size() - 1) + exception += ", "; + + } + exception += " )."; + + return new UnitCheckingException(exception); + } + + private static ArrayList> getArgumentsOf( + UnitCheckingNode functionArgumentsNode, + HashMap units, + ArrayList functions, + boolean allowEquivalents) throws UnitCheckingException { + // Arguments are defined recursively in OpenModelica + ArrayList> argumentUnits = new ArrayList>(); + if (functionArgumentsNode instanceof FunctionArguments) { + UnitCheckingNode firstArg = ((UnitCheckingNode) functionArgumentsNode.jjtGetChild(0)); + if (firstArg instanceof NamedArguments) { + // Found all position arguments, continue with named arguments + argumentUnits.addAll(getNamedArgumentsOf(firstArg, units, functions, allowEquivalents)); + } else { + argumentUnits.add(new Pair(firstArg.getUnits(units, functions, allowEquivalents), null)); + if (functionArgumentsNode.jjtGetNumChildren() > 1) { + // Continue to the next argument (within the following function_arguments) + UnitCheckingNode next = ((UnitCheckingNode) functionArgumentsNode.jjtGetChild(1)); + argumentUnits.addAll(getArgumentsOf(next, units, functions, allowEquivalents)); + } + } + } + return argumentUnits; + } + + private static ArrayList> getNamedArgumentsOf( + UnitCheckingNode namedArgumentsNode, + HashMap units, + ArrayList functions, + boolean allowEquivalents) throws UnitCheckingException { + // Named arguments are defined recursively in OpenModelica + ArrayList> argumentUnits = new ArrayList>(); + if (namedArgumentsNode instanceof NamedArguments) { + UnitCheckingNode firstArg = ((UnitCheckingNode) namedArgumentsNode.jjtGetChild(0)); + String argumentName = firstArg.jjtGetFirstToken().image; + argumentUnits.add(new Pair(firstArg.getUnits(units, functions, allowEquivalents), argumentName)); + if (namedArgumentsNode.jjtGetNumChildren() > 1) { + // Continue to the next argument (within the following function_arguments) + UnitCheckingNode next = ((UnitCheckingNode) namedArgumentsNode.jjtGetChild(1)); + argumentUnits.addAll(getNamedArgumentsOf(next, units, functions, allowEquivalents)); + } + } + return argumentUnits; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java new file mode 100644 index 00000000..05c36d9b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class IfThenElse extends UnitCheckingNode { + + public IfThenElse(int id) { + super(id); + } + + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult base = null; + UnitCheckingNode baseNode = null; + UnitCheckingNode candidateNode = null; + + for(int i = 0; i < jjtGetNumChildren(); i++) { + candidateNode = ((UnitCheckingNode)jjtGetChild(i)); + UnitResult candidateUnits = candidateNode.getUnits(units, functions, allowEquivalents); + + if(!(candidateNode instanceof Condition)) { + + if(base == null) { + base = candidateUnits; + baseNode = candidateNode; + } else { + if(!base.equals(candidateUnits)) { + base.equals(candidateUnits); + throw new UnitCheckingException("Conditional results do not have same units: " + + printNode() + " -> " + + baseNode.printNode() + " [" + base.getFullUnit() + "] <-> " + + candidateNode.printNode() + " [" + candidateUnits.getFullUnit() + "]" + ); + } + } + } + + + } + + return base; + } + + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java new file mode 100644 index 00000000..57f28f79 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class Multiplication extends UnitCheckingNode { + + public Multiplication(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); + result.setUnitType(UnitType.OPERATOR); + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/NamedArguments.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/NamedArguments.java new file mode 100644 index 00000000..7afcf98e --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/NamedArguments.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Tuomas Miettinen + * + */ +public class NamedArguments extends UnitCheckingNode { + + public NamedArguments(int id) { + super(id); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ParenthesisExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ParenthesisExpression.java new file mode 100644 index 00000000..93d28726 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ParenthesisExpression.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Tuomas Miettinen + * + */ +public class ParenthesisExpression extends UnitCheckingNode { + + public ParenthesisExpression(int id) { + super(id); + } + + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException{ + UnitResult result = new UnitResult(allowEquivalents); + // Get the Expression between the parenthesis. + result.appendResult(((UnitCheckingNode)jjtGetChild(1)).getUnits(units, functions, allowEquivalents)); + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java new file mode 100644 index 00000000..8d90de3a --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Power.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Tuomas Miettinen + * + */ +public class Power extends UnitCheckingNode { + + public Power(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); + result.setUnitType(UnitType.OPERATOR); + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java new file mode 100644 index 00000000..56b4138f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class RelOp extends UnitCheckingNode { + + public RelOp(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); + result.setUnitType(UnitType.OPERATOR); + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java new file mode 100644 index 00000000..5831092b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class Relation extends UnitCheckingNode { + + public Relation(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = new UnitResult(allowEquivalents); + + UnitCheckingNode base = null; + UnitCheckingNode operator = null; + UnitCheckingNode candidateNode = null; + + base = ((UnitCheckingNode)jjtGetChild(0)); + if(!(base instanceof Arithmetic) && jjtGetNumChildren() > 1) + base = ((UnitCheckingNode)jjtGetChild(1)); + + if(base instanceof Arithmetic) { + result.appendResult(base.getUnits(units, functions, allowEquivalents)); + + for(int i = 2; i < jjtGetNumChildren(); i = i + 2) { + candidateNode = ((UnitCheckingNode)jjtGetChild(i)); + + if(!(candidateNode instanceof Value)) { + operator = ((UnitCheckingNode)jjtGetChild(i-1)); + UnitResult candidateUnits = candidateNode.getUnits(units, functions, allowEquivalents); + if(!result.equals(candidateUnits)) { + result.equals(candidateUnits); + throw new UnitCheckingException("Not equals exception: " + + base.printNode() + " [" + result.getFullUnit() + "] " + operator.printNode() + " " + + candidateNode.printNode() + " [" + candidateUnits.getFullUnit() + "]" + ); + } + } + + } + } + + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java new file mode 100644 index 00000000..baa4a1ce --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.Token; +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class Term extends UnitCheckingNode { + + public Term(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = new UnitResult(allowEquivalents); + + UnitCheckingNode current = null; + UnitCheckingNode operator = null; + UnitCheckingNode base = null; + + for(int i = 0; i < jjtGetNumChildren(); i++) { + current = ((UnitCheckingNode)jjtGetChild(i)); + UnitResult currentUnits = current.getUnits(units, functions, allowEquivalents); + + if(currentUnits.getUnitType() == UnitType.ANY) { + result = new UnitResult(allowEquivalents); + result.setUnitType(UnitType.ANY); + return result; + } else if(currentUnits.getUnitType() == UnitType.OPERATOR) { + continue; + } else if(base == null) { + base = current; + result.appendResult(currentUnits); + continue; + } else { + operator = ((UnitCheckingNode)jjtGetChild(i-1)); + + if(operator instanceof Multiplication) { + UnitType unitType = currentUnits.getUnitType(); + if(unitType != UnitType.SCALAR && unitType != UnitType.DMNL) { + result.append(operator.printNode()); + result.appendResult(currentUnits); + } + } else if(operator instanceof Divide) { + result.append(operator.printNode()); + result.addAllDividents(currentUnits.getDividers()); + result.addAllDividers(currentUnits.getDividents()); + UnitType unitType = currentUnits.getUnitType(); + if(unitType == UnitType.SCALAR || unitType == UnitType.DMNL) { + result.append("1"); + } else { + result.append(currentUnits.getFullUnit()); + result.setUnitType(unitType); + } + } + } + } +// System.out.println("Term: " + printNode() + " [" + result.getFullUnit() + " : " + result.getUnitType() + "]"); + return result; + } + + @Override + public String printNode() { + StringBuilder sb = new StringBuilder(); + Token token = jjtGetFirstToken(); + sb.append(token.image); + + Token prevToken = null; + while(token != null && !token.equals(jjtGetLastToken())) { + prevToken = token; + token = token.next; + if(!token.image.equals("[") + && !token.image.equals("]") + && !prevToken.image.equals("[") + && !prevToken.image.equals("]") + && !token.image.equals(".") + && !prevToken.image.equals(".")) + sb.append(" "); + sb.append(token.image); + } + return sb.toString(); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/UnitResult.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/UnitResult.java new file mode 100644 index 00000000..c5920af5 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/UnitResult.java @@ -0,0 +1,289 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + ********************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; + +/** + * Result of getUnits() request for Unit Parser nodes. + * + * Result is built of dividers and dividents. ( divident / divider ) + * + * UnitType may provide information for handling this unit result + * + * fullUnit is the print of this unit in the order it is created. + * + * getCleanFullUnit reduces all unnecessary units and provides the most + * clean representation of the unit. ( e.g. m * s / m -> s ) + * + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class UnitResult { + + public enum UnitType {NORMAL, ANY, DMNL, OPERATOR, SCALAR}; + + private ArrayList dividers = new ArrayList(); + private ArrayList dividents = new ArrayList(); + private StringBuilder fullUnit = new StringBuilder(); + private UnitType unitType; + + // Equivalent forms of units: + private final Equivalent[] EQUIVALENTS = { + new Equivalent("$","$s","dollar","dollars","usd"), + new Equivalent("\u20ac","\u20acs","eur","euro","euros","e","ecu"), + new Equivalent("£","£s","pound","pounds","gbp"), + new Equivalent("unit","units"), + new Equivalent("person","people","persons"), + new Equivalent("second","seconds","sec","s"), + new Equivalent("minute","minutes","min"), + new Equivalent("hour","hours","h","hr"), + new Equivalent("day","days","d"), + new Equivalent("month","months","mon","mth","mo","mos"), + new Equivalent("year","years","a","y","yr") + }; + private boolean allowEquivalents; + + private class Equivalent { + public ArrayList forms; + + Equivalent(String ... forms) { + this.forms = new ArrayList(); + for (String f : forms) + this.forms.add(f); + } + + public boolean contains(String form) { + for (String f : forms) + if (f.equalsIgnoreCase(form)) + return true; + return false; + } + + public String getDefault() { + if (forms.size() > 0) + return forms.get(0); + else return null; + } + } + + public UnitResult(boolean allowEquivalents) { + this.allowEquivalents = allowEquivalents; + setUnitType(UnitType.NORMAL); + } + + public void appendResult(UnitResult result) { + addAllDividents(result.getDividents()); + addAllDividers(result.getDividers()); + append(result.getFullUnit()); + setUnitType(result.getUnitType()); + } + + public void addDivider(String divider) { + this.dividers.add(divider); + Collections.sort(this.dividers); + } + + public void addAllDividers(ArrayList dividers) { + this.dividers.addAll(dividers); + Collections.sort(this.dividers); + } + + public void addDivident(String divident) { + this.dividents.add(divident); + Collections.sort(this.dividents); + } + + public void addAllDividents(ArrayList dividents) { + this.dividents.addAll(dividents); + Collections.sort(this.dividents); + } + + public void append(String text) { + this.fullUnit.append(text); + } + + public ArrayList getDividers() { + return this.dividers; + } + + public ArrayList getDividents() { + return this.dividents; + } + + public String getFullUnit() { + return fullUnit.toString(); + } + + + /** + * Get clean representation of this unit. All redundant + * units are cleanend out and the unit is represented + * with max one '/' character. + * @return + */ + public String getCleanFullUnit() { + if(dividers.size() == 0 && dividents.size() == 0) + return ""; + + if(dividers.size() > 0 && dividents.size() == 0) + dividents.add("1"); + + ArrayList copyDividers1 = new ArrayList(dividers); + ArrayList copyDividents1 = new ArrayList(dividents); + reduceUnitLists(dividents, copyDividents1, copyDividers1, allowEquivalents); + + StringBuilder sb = new StringBuilder(); + Iterator iterator = copyDividents1.iterator(); + while(iterator.hasNext()) { + String s = iterator.next(); + sb.append(s); + if(iterator.hasNext()) + sb.append("*"); + } + + if(copyDividers1.size() > 0) { + sb.append("/"); + if(copyDividers1.size() > 1) + sb.append("("); + + iterator = copyDividers1.iterator(); + while(iterator.hasNext()) { + String s = iterator.next(); + sb.append(s); + if(iterator.hasNext()) + sb.append("*"); + } + + if(copyDividers1.size() > 1) + sb.append(")"); + } + + return sb.toString(); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof UnitResult)) + return false; + + UnitResult other = (UnitResult)obj; + + if(getUnitType() == UnitType.ANY || other.getUnitType() == UnitType.ANY) + return true; + + if(getUnitType() != other.getUnitType()) + return true; + + ArrayList copyDividers1 = new ArrayList(dividers); + ArrayList copyDividents1 = new ArrayList(dividents); + reduceUnitLists(dividents, copyDividents1, copyDividers1, allowEquivalents); + + ArrayList copyDividers2 = new ArrayList(other.dividers); + ArrayList copyDividents2 = new ArrayList(other.dividents); + reduceUnitLists(other.dividents, copyDividents2, copyDividers2, allowEquivalents); + + if(copyDividents1.size() != copyDividents2.size()) + return false; + if(copyDividers1.size() != copyDividers2.size()) + return false; + + if (allowEquivalents) { + // Replace and sort all once again. + for(int i = 0; i < copyDividents1.size(); i++) { + copyDividents1.set(i, getDefaultForm(copyDividents1.get(i))); + copyDividents2.set(i, getDefaultForm(copyDividents2.get(i))); + Collections.sort(copyDividents1); + Collections.sort(copyDividents2); + } + for(int i = 0; i < copyDividers1.size(); i++) { + copyDividers1.set(i, getDefaultForm(copyDividers1.get(i))); + copyDividers2.set(i, getDefaultForm(copyDividers2.get(i))); + Collections.sort(copyDividers1); + Collections.sort(copyDividers2); + } + } + + for(int i = 0; i < copyDividents1.size(); i++) { + String a = copyDividents1.get(i); + String b = copyDividents2.get(i); + if(!a.equals(b)) { + return false; + } + } + for(int i = 0; i < copyDividers1.size(); i++) { + String a = copyDividers1.get(i); + String b = copyDividers2.get(i); + if(!a.equals(b)) { + return false; + } + } + + return true; + } + + /** + * Get the default form of a unit (e.g. dollars -> $). + * @param unit + * @return default form of unit + */ + private String getDefaultForm(String unit) { + for (Equivalent e : EQUIVALENTS) + if (e.contains(unit)) + return e.getDefault(); + return unit; + } + + public void reduceUnitLists( + ArrayList originalDividents, + ArrayList copyDividents, + ArrayList copyDividers, + boolean allowEquivalents) { + if (allowEquivalents) { + // Replace equivalents + for(int i = 0; i < originalDividents.size(); i++) { + copyDividents.set(i, getDefaultForm(copyDividents.get(i))); + } + for(int i = 0; i < copyDividers.size(); i++) { + copyDividers.set(i, getDefaultForm(copyDividers.get(i))); + } + } + + for(String s : originalDividents) { + String equiv = allowEquivalents ? getDefaultForm(s) : s; + if(copyDividers.contains(equiv)) { + copyDividers.remove(equiv); + copyDividents.remove(equiv); + } + } + + if(copyDividents.isEmpty()) + copyDividents.add("1"); + } + + public UnitType getUnitType() { + return unitType; + } + + public void setUnitType(UnitType unitType) { + this.unitType = unitType; + } + + @Override + public String toString() { + return getCleanFullUnit(); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java new file mode 100644 index 00000000..e0edb445 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + * VTT Technical Research Centre of Finland + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.sysdyn.utils.Function; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * @author Tuomas Miettinen + * + */ +public class Value extends UnitCheckingNode { + + public Value(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units, ArrayList functions, boolean allowEquivalents) throws UnitCheckingException { + UnitResult result = super.getUnits(units, functions, allowEquivalents); + result.setUnitType(UnitType.SCALAR); + return result; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/DocumentationUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/DocumentationUtils.java new file mode 100644 index 00000000..296c0ddd --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/DocumentationUtils.java @@ -0,0 +1,495 @@ +package org.simantics.sysdyn.utils; + +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.util.Base64; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithSupertype; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.Book; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.Shadow; +import org.simantics.sysdyn.representation.Stock; +import org.simantics.sysdyn.representation.Variability; +import org.simantics.sysdyn.representation.Variable; +import org.simantics.sysdyn.utils.imports.ImportUtils; + +public class DocumentationUtils { + + public static List getModules(ReadGraph graph, org.simantics.db.layer0.variable.Variable model) throws DatabaseException { + if(model == null) + return Collections.emptyList(); + + SysdynResource SR = SysdynResource.getInstance(graph); + Resource modelResource = model.getRepresents(graph); + + ArrayList result = new ArrayList(); + + if(graph.isInstanceOf(modelResource, SR.SysdynModel)) { + result.add(modelResource); + result.addAll(graph.syncRequest(new ObjectsWithSupertype(modelResource, Layer0.getInstance(graph).ConsistsOf, SR.Module))); + } + + return result; + } + + public static List getExperimentVariables(ReadGraph graph, org.simantics.db.layer0.variable.Variable model) throws DatabaseException { + if(model == null) + return Collections.emptyList(); + + ModelingResources MR = ModelingResources.getInstance(graph); + if (model == null || !graph.isInstanceOf(model.getRepresents(graph), MR.StructuralModel)) { + return Collections.emptyList(); + } + + Layer0 L0 = Layer0.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + ArrayList result = new ArrayList(); + for (Resource config : graph.getObjects(model.getRepresents(graph), L0.ConsistsOf)) { + if (graph.isInstanceOf(config, SIMU.Experiment)) { + for (Resource run : graph.getObjects(config, L0.ConsistsOf)) { + if (graph.isInstanceOf(run, SIMU.Run)) { + if (graph.hasStatement(run, SIMU.IsActive)) { + org.simantics.db.layer0.variable.Variable runVar = Variables.getPossibleVariable(graph, run); + if(runVar != null) + result.add(runVar); + } + } + } + } + } + + return result; + } + + public static List getRoleVariables(ReadGraph graph, org.simantics.db.layer0.variable.Variable experiment) throws DatabaseException { + if(experiment == null) + return Collections.emptyList(); + + SimulationResource SIMU = SimulationResource.getInstance(graph); + + if(graph.isInstanceOf(experiment.getRepresents(graph), SIMU.Run)) + experiment = experiment.getParent(graph); + + if(!graph.isInstanceOf(experiment.getRepresents(graph), SIMU.Experiment)) + return Collections.emptyList(); + + Resource roleType = graph.getPossibleResource("http://www.semantum.fi/Simupedia-1.0/Role"); + if(roleType == null) + return Collections.emptyList(); + + ArrayList result = new ArrayList(); + for(org.simantics.db.layer0.variable.Variable part : experiment.getChildren(graph)) { + if(graph.isInstanceOf(part.getRepresents(graph), roleType)) { + result.add(part); + } + } + + return result; + } + + public static List getDocumentVariables(ReadGraph graph, org.simantics.db.layer0.variable.Variable model) throws DatabaseException { + if(model == null) + return Collections.emptyList(); + + Resource documentType = graph.getPossibleResource("http://www.simantics.org/Documentation-1.2/Document"); + if(documentType == null) + return Collections.emptyList(); + + ArrayList result = new ArrayList(); + for(org.simantics.db.layer0.variable.Variable part : model.getChildren(graph)) { + if(graph.isInstanceOf(part.getRepresents(graph), documentType)) { + result.add(part); + } + } + + return result; + } + + public static List getResultVariables(ReadGraph graph, org.simantics.db.layer0.variable.Variable model) throws DatabaseException { + if(model == null) + return Collections.emptyList(); + + org.simantics.db.layer0.variable.Variable library = model.getPossibleChild(graph, "PDFLibrary"); + if(library == null) + return Collections.emptyList(); + + + return new ArrayList(library.getChildren(graph)); + } + + public static List getIndexDocuments(ReadGraph graph, org.simantics.db.layer0.variable.Variable project) throws DatabaseException { + Resource indexRelation = graph.getPossibleResource("http://www.semantum.fi/Simupedia-1.0/indexDocument"); + + if(indexRelation == null) + return Collections.emptyList(); + + ArrayList result = new ArrayList(); + for(org.simantics.db.layer0.variable.Variable model : project.getChildren(graph)) { + Resource modelResource = model.getRepresents(graph); + if(modelResource == null) + continue; + + Resource indexDocumentResource = graph.getPossibleObject(modelResource, indexRelation); + if(indexDocumentResource != null) { + org.simantics.db.layer0.variable.Variable indexDoc = Variables.getVariable(graph, indexDocumentResource); + result.add(indexDoc); + } + } + return result; + } + + public static Resource getConfiguration(ReadGraph graph, Resource module) throws DatabaseException { + if(module == null) + return null; + + SysdynResource SR = SysdynResource.getInstance(graph); + + if(graph.isInstanceOf(module, SR.SysdynModel)) { + return graph.getSingleObject(module, SimulationResource.getInstance(graph).HasConfiguration); + } else if(graph.isInheritedFrom(module, SR.Module)) { + return graph.getSingleObject(module, StructuralResource2.getInstance(graph).IsDefinedBy); + } else { + return null; + } + } + + public static List getConfigurationVariables(ReadGraph graph, Resource configuration) throws DatabaseException { + if(configuration == null) + return Collections.emptyList(); + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, configuration); + + ArrayList elements = new ArrayList(); + + for(IElement element : sm.getConfiguration().getElements()) { + if((element instanceof Variable || element instanceof Module) && !(element instanceof Book) && !(element instanceof Shadow)) { + elements.add(element); + } + } + + Collections.sort(elements, new Comparator() { + + @Override + public int compare(IElement o1, IElement o2) { + if(!isApplied(o1) || !isApplied(o2)) + return 0; + else { + String name1 = getName(o1); + String name2 = getName(o2); + return name1.compareTo(name2); + } + } + + private boolean isApplied(IElement element) { + if((element instanceof Variable || element instanceof Module) && !(element instanceof Book)) { + return true; + } else { + return false; + } + + } + + private String getName(IElement element) { + if(element instanceof Variable) + return ((Variable)element).getName(); + else if(element instanceof Module) + return ((Module)element).getName(); + else + return ""; + } + + }); + + ArrayList result = new ArrayList(); + for(IElement e : elements) + result.add(sm.getMapping().inverseGet(e)); + + return result; + } + + public static String getName(ReadGraph graph, Resource variable) throws DatabaseException { + if(variable == null) + return null; + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + Resource configuration = graph.syncRequest(new GetConfigurationRequest(variable)); + SysdynModel sm = smm.getModel(graph,configuration); + + IElement element = sm.getElement(variable); + + if(element instanceof Variable) { + Variable v = (Variable) element; + + StringBuilder sb = new StringBuilder(); + sb.append(v.getModelicaName()); + + + if(v.getArrayIndexes() != null && v.getArrayIndexes().size() > 0) { + sb.append("["); + boolean first = true; + for(Enumeration e : v.getArrayIndexes()) { + if(!first) + sb.append(", "); + first = false; + sb.append(e.getModelicaName()); + } + + sb.append("]"); + } + + return sb.toString(); + } + + if(element instanceof Module) { + Module m = (Module) element; + return m.getName(); + } + + return ""; + } + + public static String getType(ReadGraph graph, Resource variable) throws DatabaseException { + if(variable == null) + return null; + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + Resource configuration = graph.syncRequest(new GetConfigurationRequest(variable)); + SysdynModel sm = smm.getModel(graph,configuration); + + IElement element = sm.getElement(variable); + + if(element instanceof Variable) { + String result = ((Variable)element).getType(); + if(result == null) + return ""; + else + return element.getClass().getSimpleName() + " " + result; + } + + if(element instanceof Module) { + Module m = (Module) element; + return"Module " + m.getType().getName(); + } + + return ""; + } + + public static String getUnit(ReadGraph graph, Resource variable) throws DatabaseException { + if(variable == null) + return null; + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + Resource configuration = graph.syncRequest(new GetConfigurationRequest(variable)); + SysdynModel sm = smm.getModel(graph,configuration); + + IElement element = sm.getElement(variable); + + if(element instanceof Variable) { + String result = ((Variable)element).getUnit(); + if(result == null) + return ""; + else + return result; + } + + return ""; + } + + + public static String getVariability(ReadGraph graph, Resource variable) throws DatabaseException { + if(variable == null) + return null; + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + Resource configuration = graph.syncRequest(new GetConfigurationRequest(variable)); + SysdynModel sm = smm.getModel(graph,configuration); + + IElement element = sm.getElement(variable); + + if(element instanceof Stock) + return ""; + + if(element instanceof IndependentVariable) { + Variability variability = Variability.getVariability((IndependentVariable)element); + if(variability == Variability.CONTINUOUS) + return ""; + return variability.toString().toLowerCase(); + } + if(element instanceof Variable) { + String result = ((Variable)element).getVariability(); + if(result == null) + return ""; + else { + return result; + } + } + + return ""; + } + + public static String getDescription(ReadGraph graph, Resource variable) throws DatabaseException { + if(variable == null) + return null; + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + Resource configuration = graph.syncRequest(new GetConfigurationRequest(variable)); + SysdynModel sm = smm.getModel(graph,configuration); + + IElement element = sm.getElement(variable); + + if(element instanceof Variable) { + String result = ((Variable)element).getDescription(); + if(result == null) + return ""; + else + return result; + } + + return ""; + } + + + public static String getDocumentationDefinition(ReadGraph graph, Resource variable) throws DatabaseException { + if(variable == null) + return null; + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + Resource configuration = graph.syncRequest(new GetConfigurationRequest(variable)); + SysdynModel sm = smm.getModel(graph,configuration); + + IElement element = sm.getElement(variable); + + if(element instanceof Variable) { + Variable v = (Variable) element; + String result = v.getDocumentationDefinition(graph); + if(result == null) + return ""; + else + return result; + } + + if(element instanceof Module) { + Module m = (Module) element; + return m.getDocumentationDefinition(); + // Print interface variables and parameter overrides + } + + return ""; + + } + + + public static int numberOfVariables(ReadGraph graph, Resource configuration, boolean recursive) throws DatabaseException { + return graph.syncRequest(new ModuleSummaryRequest(configuration, recursive)).getVariables(); + } + + public static int totalNumberOfVariables(ReadGraph graph, Resource configuration, boolean recursive) throws DatabaseException { + return graph.syncRequest(new ModuleSummaryRequest(configuration, recursive)).getTotalVariables(); + } + + public static int numberOfStocks(ReadGraph graph, Resource configuration, boolean recursive) throws DatabaseException { + return graph.syncRequest(new ModuleSummaryRequest(configuration, recursive)).getStocks(); + } + + public static int numberOfValves(ReadGraph graph, Resource configuration, boolean recursive) throws DatabaseException { + return graph.syncRequest(new ModuleSummaryRequest(configuration, recursive)).getValves(); + } + + public static int numberOfInputs(ReadGraph graph, Resource configuration, boolean recursive) throws DatabaseException { + return graph.syncRequest(new ModuleSummaryRequest(configuration, recursive)).getInputs(); + } + + public static int numberOfShadows(ReadGraph graph, Resource configuration, boolean recursive) throws DatabaseException { + return graph.syncRequest(new ModuleSummaryRequest(configuration, recursive)).getShadows(); + } + + public static int numberOfAuxiliaries(ReadGraph graph, Resource configuration, boolean recursive) throws DatabaseException { + return graph.syncRequest(new ModuleSummaryRequest(configuration, recursive)).getAuxiliaries(); + } + + public static int numberOfModules(ReadGraph graph, Resource configuration, boolean recursive) throws DatabaseException { + return graph.syncRequest(new ModuleSummaryRequest(configuration, recursive)).getModules(); + } + + public static int numberOfSheets(ReadGraph graph, Resource configuration, boolean recursive) throws DatabaseException { + return graph.syncRequest(new ModuleSummaryRequest(configuration, recursive)).getSheets(); + } + + public static int numberOfModuleTypes(ReadGraph graph, org.simantics.db.layer0.variable.Variable model) throws DatabaseException { + if(model == null) + return 0; + + Resource modelResource = model.getRepresents(graph); + return graph.syncRequest(new ObjectsWithSupertype( + modelResource, + Layer0.getInstance(graph).ConsistsOf, + SysdynResource.getInstance(graph).Module)) + .size(); + } + + public static String base64Encode(ReadGraph graph, org.simantics.db.layer0.variable.Variable variable, String property) throws DatabaseException { + byte[] fileBArray = variable.getPossiblePropertyValue(graph, property, Bindings.BYTE_ARRAY); + if(fileBArray != null) + return Base64.encode(fileBArray); + else + return ""; + } + + public static String formatDate(long timeMillis) { + Date date = new Date(timeMillis); + String result = DateFormat.getDateInstance().format(date); + return result; + } + + /** + * Supports importing Sysdyn models into the current project from TG files + * in SCL. + * + * @param path + */ + public static void importModel(String path) { + ImportUtils.importModelFile(path, new NullProgressMonitor()); + } + + public static boolean isParameter(ReadGraph graph, org.simantics.db.layer0.variable.Variable variable) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + Resource represents = variable.getPossibleRepresents(graph); + System.out.println(graph.getURI(represents)); + if(represents == null || !graph.isInstanceOf(represents, SR.IndependentVariable)) + return false; + + Resource expressionList = graph.getPossibleObject(represents, SR.Variable_expressionList); + + if(expressionList == null) + return false; + + List expressions = ListUtils.toList(graph, expressionList); + if(expressions == null || expressions.size() != 1) + return false; + + Resource expression = expressions.get(0); + return graph.isInstanceOf(expression, SR.ParameterExpression); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java new file mode 100644 index 00000000..bedd3247 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/Function.java @@ -0,0 +1,563 @@ +package org.simantics.sysdyn.utils; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.unitParser.ParseException; +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.UnitParser; +import org.simantics.sysdyn.unitParser.nodes.UnitResult; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.datastructures.Pair; + + +/** + * Class to store function name, type, and parameters. + * + * @author Tuomas Miettinen + * + */ +public class Function implements Comparable{ + + private final String name; + private final Type type; + private final ArrayList inputList; + private final ArrayList outputList; + private final String description; + + public static class Parameter { + public static final String ANY = "ANY"; + public static final String TIME = "TIME"; + public String name; + public String unit = ANY; + + public UnitResult getUnitResult( + HashMap units, + Function f, + ArrayList functions, + boolean allowEquivalents, + HashMap correspondences) throws UnitCheckingException { + + UnitResult result = new UnitResult(allowEquivalents); + if (Parameter.ANY.equals(this.unit)) { + result.setUnitType(UnitType.ANY); + } else if ("1".equals(this.unit)) { // TODO: see if this should be changed to something else + result.setUnitType(UnitType.SCALAR); + } else { + // Replace TIME with actual time unit. + String timeUnit = units.get("time"); + String timeReplaced = this.unit.replace(Parameter.TIME, timeUnit); + + // Replace 'p, 'q, etc. in output with units from actual inputs. + String correspondencesReplaced = replaceCorrespondences(f, timeReplaced, correspondences); + + try { + StringReader outputReader = new StringReader(correspondencesReplaced); + UnitParser outputParser = new UnitParser(outputReader); + UnitCheckingNode output; + output = (UnitCheckingNode) outputParser.expr(); + outputReader.close(); + result.appendResult(output.getUnits(null, functions, allowEquivalents)); + result.setUnitType(UnitType.NORMAL); + } catch (UnitCheckingException e) { + e.printStackTrace(); + } catch (ParseException e) { + throw new UnitCheckingException("Cannot validate units: Syntax error in expression."); + } + } + + return result; + } + + private static String replaceCorrespondences(Function f, String original, + HashMap correspondences) throws UnitCheckingException { + int index; + String ret = new String(original); + // Go through the unit as long as there are part of form 'p, 'q, etc. and replace them. + while ((index = ret.indexOf('\'')) >= 0) { + String replaced = ret.substring(index, index + 2); // The replaced units are always of length 2. + try { + ret = ret.replace(replaced, correspondences.get(replaced)); + } catch (NullPointerException npe) { + throw new UnitCheckingException("Function " + f.getName() + " output unit could not be determined. Replacement unit " + + replaced + " not found in input unit definitions."); + } + } + return ret; + } + } + + public static class Input extends Parameter { + public boolean variableLength = false; + public boolean optional = false; + public ArrayList variableLengthLabels; + } + + public static class Output extends Parameter { + } + + public enum Type { + USER_DEFINED, + SHARED, + SYSDYN, + MODELICA, + MODELICA_ARRAY, + VENSIM + } + + public Function( + String name, + ArrayList inputList, + ArrayList outputList, + Type type, + String description){ + + this.name = new String(name); + + this.type = type; + + if (inputList != null) + this.inputList = inputList; + else + this.inputList = new ArrayList(); + + if (outputList != null) + this.outputList = outputList; + else + this.outputList = new ArrayList(); + + if (description != null) + this.description = new String(description); + else + this.description = null; + } + + /** + * Convert list of Inputs to string + * @param inputList list of Inputs + * @return printable form of inputs (for function declaration) + */ + public static String inputListToString(ArrayList inputList) { + String inputStr = null; + for (Input p : inputList) { + String pName; + // Variable length parameter list + if (p.variableLength) { + pName = ""; + for (String label : p.variableLengthLabels) { + pName += label + ", "; + } + pName += "..."; + } else { + pName = p.name; + } + + if (inputStr == null) + inputStr = new String(pName); + else + inputStr += ", " + pName; + } + return inputStr; + } + + public ArrayList getInputList() { + return inputList; + } + + public ArrayList getOutputList() { + return outputList; + } + + public String getName() { + return name; + } + + public Type getType() { + return type; + } + + public String getDescription() { + return description; + } + + @Override + public int compareTo(Function f) { + // Sorting is done first in the order of Types and then alphabetically. + int typeCompare = type.compareTo(f.getType()); + return typeCompare != 0 ? typeCompare : name.compareTo(f.getName()); + } + + /** + * Get Modelica function input parameters + * @param graph + * @param sr + * @param r Resource of the Modelica function + * @return ArrayList of Inputs + * @throws DatabaseException + */ + public static ArrayList getFunctionInputs(ReadGraph graph, SysdynResource sr, Resource r) throws DatabaseException { + Resource inputs = graph.getPossibleObject(r, sr.SysdynModelicaFunction_inputs); + ArrayList inputParameters = new ArrayList(); + if (inputs != null) { + for (Resource input : ListUtils.toList(graph, inputs)) { + // Convert the Resource into Parameter; + Input inputParameter = new Input(); + inputParameter.name = NameUtils.getSafeName(graph, input); + inputParameter.optional = graph.getPossibleRelatedValue( + input, + sr.SysdynModelicaFunction_optional, + Bindings.BOOLEAN); + inputParameter.unit = graph.getPossibleRelatedValue( + input, + sr.SysdynModelicaFunction_unit, + Bindings.STRING); + if (graph.isInstanceOf(input, sr.SysdynModelicaFunction_VariableLengthInput)) { + inputParameter.variableLength = true; + Resource shownLabels = graph.getPossibleObject( + input, + sr.SysdynModelicaFunction_VariableLengthInput_shownLabels); + inputParameter.variableLengthLabels = new ArrayList(); + if (shownLabels != null) { + for (Resource label : ListUtils.toList(graph, shownLabels)) { + inputParameter.variableLengthLabels.add(NameUtils.getSafeName(graph, label)); + } + } + } + + inputParameters.add(inputParameter); + } + } + return inputParameters; + } + + /** + * Get Modelica function outputs + * @param graph + * @param sr + * @param r Resource of the Modelica function + * @return ArrayList of Outputs + * @throws DatabaseException + */ + protected static ArrayList getFunctionOutputs(ReadGraph graph, + SysdynResource sr, Resource r) throws DatabaseException { + Resource outputs = graph.getPossibleObject(r, sr.SysdynModelicaFunction_outputs); + ArrayList outputParameters = new ArrayList(1); + if (outputs != null) { + for (Resource output : ListUtils.toList(graph, outputs)) { + // Convert the Resource into Parameter; + Output outputParameter = new Output(); + outputParameter.name = NameUtils.getSafeName(graph, output); + outputParameter.unit = graph.getPossibleRelatedValue( + output, + sr.SysdynModelicaFunction_unit, + Bindings.STRING); + outputParameters.add(outputParameter); + } + } + return outputParameters; + } + + public static String getFunctionDescription(ReadGraph graph, Resource r) throws DatabaseException { + String descriptionStr = null; + Layer0 l0 = Layer0.getInstance(graph); + Resource description = graph.getPossibleObject(r, l0.HasDescription); + if (description != null) { + descriptionStr = graph.getPossibleRelatedValue(r, l0.HasDescription, Bindings.STRING); + } + + return descriptionStr; + } + + private static ArrayList getFunctionsOfType(ReadGraph graph, String functionTypeUri, Type functionType) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + Layer0 l0 = Layer0.getInstance(graph); + ArrayList functions = new ArrayList(); + + // Add functions + Resource functionLibrary = graph.getPossibleResource(functionTypeUri); + for(Resource r : graph.syncRequest(new ObjectsWithType(functionLibrary, l0.ConsistsOf, sr.SysdynModelicaFunction))) { + String name = NameUtils.getSafeName(graph, r); + ArrayList inputs = getFunctionInputs(graph, sr, r); + ArrayList outputs = getFunctionOutputs(graph, sr, r); + String description = getFunctionDescription(graph, r); + functions.add(new Function(name, inputs, outputs, functionType, description)); + } + return functions; + } + + /** + * Get all built-in Modelica functions. + * Should be used if called inside a transaction + * @return ArrayList containing all built-in functions. + */ + public static ArrayList getAllBuiltInFunctions(ReadGraph graph) throws DatabaseException { + ArrayList functions = new ArrayList(); + + // Add different types of functions. + functions.addAll(getFunctionsOfType(graph, SysdynResource.URIs.Built$in_Functions, Type.SYSDYN)); + functions.addAll(getFunctionsOfType(graph, SysdynResource.URIs.Built$in_Functions_Vensim_Functions, Type.VENSIM)); + functions.addAll(getFunctionsOfType(graph, SysdynResource.URIs.Built$in_Functions_Modelica_Functions, Type.MODELICA)); + functions.addAll(getFunctionsOfType(graph, SysdynResource.URIs.Built$in_Functions_Modelica_Array_Functions, Type.MODELICA_ARRAY)); + + return functions; + } + + /** + * Get all built-in Modelica functions. + * @return ArrayList containing all built-in functions. + */ + public static ArrayList getAllBuiltInFunctions() { + ArrayList result = null; + + //Finding functions + try { + result = SimanticsUI.getSession().syncRequest(new Read>() { + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + return getAllBuiltInFunctions(graph); + } + }); + } + catch (DatabaseException e) { + e.printStackTrace(); + } + + return result; + } + + /** + * Get all shared Modelica functions. + * @param variable of which model is in question + * @return ArrayList containing all shared functions. + */ + public static ArrayList getSharedFunctions(final Resource model) { + ArrayList functions = new ArrayList(); + if (model == null) { + return functions; + } + + try { + functions = SimanticsUI.getSession().syncRequest(new Read>() { + + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + // Full names of the collected functions + ArrayList sharedFunctions = new ArrayList(); + + Collection linkedResources = graph.getObjects(model, l0.IsLinkedTo); + for (Resource r : linkedResources) { + // Find the "Shared functions" library + if (graph.isInstanceOf(r, sr.SharedFunctionOntology)) { + // Get all function resources under the Shared Functions "folder". + Collection userFunctionResources = getFunctionsInside(graph, r); + for (Resource function : userFunctionResources) { + // Construct the Modelica name of the function + String fullName = NameUtils.getSafeName(graph, function); + Resource parent = function; // Parent is updated properly in the loop + do { + parent = graph.getPossibleObject(parent, l0.PartOf); + fullName = NameUtils.getSafeName(graph, parent) + "." + fullName; + } while (!graph.isInstanceOf(parent, l0.Ontology)); + + // Create a Function object out of the Resource + Function sharedFunction = new Function(fullName, + Function.getFunctionInputs(graph, sr, function), + Function.getFunctionOutputs(graph, sr, function), + Type.SHARED, + Function.getFunctionDescription(graph, function)); + sharedFunctions.add(sharedFunction); + } + } + } + return sharedFunctions; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return functions; + } + + /** + * Get all user defined Modelica functions. + * @param variable of which model is in question + * @return ArrayList containing all user defined functions. + */ + public static ArrayList getUserDefinedFunctions(final Resource model) { + ArrayList functions = new ArrayList(); + if (model == null) { + return functions; + } + + try { + functions = SimanticsUI.getSession().syncRequest(new Read>() { + + @Override + public ArrayList perform(ReadGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + // Full names of the collected functions + ArrayList userFunctions = new ArrayList(); + + // Get all function resources under model recursively + Collection userFunctionResources = getFunctionsInside(graph, model); + for (Resource function : userFunctionResources) { + // Construct the Modelica name of the function + String fullName = NameUtils.getSafeName(graph, function); + Resource parent = graph.getPossibleObject(function, l0.PartOf); + while (!graph.isInstanceOf(parent, sr.SysdynModel)) { + fullName = NameUtils.getSafeName(graph, parent) + "." + fullName; + parent = graph.getPossibleObject(parent, l0.PartOf); + } + + // Create a Function object out of the Resource + Function userFunction = new Function(fullName, + Function.getFunctionInputs(graph, sr, function), + Function.getFunctionOutputs(graph, sr, function), + Type.USER_DEFINED, + Function.getFunctionDescription(graph, function)); + userFunctions.add(userFunction); + } + + return userFunctions; + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return functions; + } + + /** + * Get functions inside a resource + * @param graph + * @param r Recource in which functions are sought + * @return found function Resources + * @throws DatabaseException + */ + public static Collection getFunctionsInside(ReadGraph graph, Resource r) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + ArrayList functions = new ArrayList(); + functions.addAll(graph.syncRequest(new ObjectsWithType( + r, + l0.ConsistsOf, + sr.SysdynModelicaFunction))); + Collection functionLibraries; + functionLibraries = graph.syncRequest(new ObjectsWithType( + r, + l0.ConsistsOf, + sr.SysdynModelicaFunctionLibrary)); + for (Resource library : functionLibraries) { + functions.addAll(getFunctionsInside(graph, library)); + } + return functions; + } + + /** + * Converts the description string to HTML-format + * @return HMTL-formatted description. + */ + public String getDescriptionHTML() { + if (description == null) + return null; + return description.replaceAll("<", "<").replaceAll(">", ">").replaceAll("\n", "
"); + } + + /** + * Determine if the units of the given arguments are valid + * @param argumentUnits validated arguments + * @param correspondences mapping from templates to actual arguments + * @param functions all functions available + * @param allowEquivalents true iff equivalent units are used (e.g. $ == dollar) + * @param units evm + * @return true iff argument units are valid + * @throws UnitCheckingException if + */ + public boolean areArgumentUnitsValid(ArrayList> argumentUnits, + HashMap correspondences, + ArrayList functions, + boolean allowEquivalents, + HashMap units) throws UnitCheckingException { + ArrayList inputMatches = new ArrayList(); // Table for matching inputs. + for (int i = 0; i < inputList.size(); ++i) + inputMatches.add(Boolean.FALSE); + + for (int i = 0; i < argumentUnits.size(); ++i) { // Go through all _arguments_ + if (inputList.size() == 0) + return false; // No inputs expected but got at least one + + if (argumentUnits.get(i).second != null) { // Named argument + boolean found = false; + for (int j = 0; j < inputList.size(); ++j) { + Input namedInput = inputList.get(j); + if (namedInput.name.equals(argumentUnits.get(i).second)) { + // Match input unit to argument unit + UnitResult inputUnit = namedInput.getUnitResult(units, this, functions, allowEquivalents, correspondences); + if (!inputUnit.equals(argumentUnits.get(i).first)) + return false; + inputMatches.set(j, Boolean.TRUE); + found = true; + break; + } + } + if (!found) { + throw new UnitCheckingException("Undefined input argument " + argumentUnits.get(i).second + + " used in function " + this.getName() + "."); + } + } else { // Position argument + if (i >= inputList.size()) { // Test for variable length argument + // Assume there can be only one variable length input and its in the end. + // And that there cannot be any optional arguments before. + Input input = inputList.get(inputList.size() - 1); + if (input.variableLength) { + // Match input unit to argument unit + UnitResult inputUnit = input.getUnitResult(units, this, functions, allowEquivalents, correspondences); + if (!inputUnit.equals(argumentUnits.get(i).first)) + return false; + // The corresponding _input_ has already been gone through, no need to set true. + } else { + return false; + } + } else { + // Match input unit to argument unit + UnitResult inputUnit = inputList.get(i).getUnitResult(units, this, functions, allowEquivalents, correspondences); + if (inputUnit.getUnitType() == UnitType.SCALAR + && !(argumentUnits.get(i).first.getUnitType() == UnitType.SCALAR)) + return false; // Here we don't accept a "1" replaced with a NORMAL expression, there's "ANY" for that. + if (!inputUnit.equals(argumentUnits.get(i).first)) + return false; + inputMatches.set(i, Boolean.TRUE); + } + } + } + + // See if some of the required inputs has not been defined. + for (int i = 0; i < inputList.size(); ++i) { + if (!inputMatches.get(i) && !inputList.get(i).optional) { + return false; + } + } + + return true; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/GetConfigurationRequest.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/GetConfigurationRequest.java new file mode 100644 index 00000000..4aa51554 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/GetConfigurationRequest.java @@ -0,0 +1,42 @@ +package org.simantics.sysdyn.utils; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; + +public class GetConfigurationRequest implements Read { + + private Resource resource; + + public GetConfigurationRequest(Resource resource) { + this.resource = resource; + } + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return getConfiguration(graph, resource); + } + + private Resource getConfiguration(ReadGraph graph, Resource resource) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource parent = graph.getPossibleObject(resource, L0.PartOf); + if(parent == null) + return null; + + SysdynResource SR = SysdynResource.getInstance(graph); + if(graph.isInstanceOf(parent, SR.SysdynModel)) { + parent = graph.getPossibleObject(parent, SimulationResource.getInstance(graph).HasConfiguration); + } + + if(graph.isInstanceOf(parent, SR.Configuration)) { + return parent; + } + + else + return getConfiguration(graph, parent); + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/LoopUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/LoopUtils.java new file mode 100644 index 00000000..cfb10396 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/LoopUtils.java @@ -0,0 +1,322 @@ +/******************************************************************************* + * Copyright (c) 2014 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.utils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.request.Read; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.elementaryCycles.ElementaryCyclesSearch; +import org.simantics.ui.SimanticsUI; + +/** + * Utils for loops + * @author Tuomas Miettinen + * + */ +public class LoopUtils { + + private static class ElementaryLoopItem { + public int mapping; + ArrayList dependencies; + + public ElementaryLoopItem(int mapping, ArrayList dependencies) { + this.mapping = mapping; + this.dependencies = dependencies; + } + } + + public enum LoopType { + REINFORCING, + BALANCING, + UNDEFINED + }; + + /** + * Get all the loops within the diagram where the resource belongs to. + * @param r Resource that is studied + * @return List of loops; each loop is a list of resources in the same order in which + * they appear in the loop. The first item in the list can be any of the items in the + * loop. + */ + public static List> getLoops(final Resource r) { + List> loops = Collections.emptyList(); + try { + loops = SimanticsUI.getSession().syncRequest(new Read>>() { + + @Override + public List> perform(ReadGraph graph) + throws DatabaseException { + return getLoops(graph, r); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + return loops; + } + + @SuppressWarnings({ "rawtypes", "unchecked", "unused" }) + public static List> getLoops(ReadGraph g, Resource r) throws DatabaseException, ServiceException { + // Get all loops in the diagram. + List> cycles = getAllLoopsInDiagram(g, r); + + // Collect all those loops in which the original resource exists. + List> loops = new ArrayList>(); + for (Object o : cycles) { + if (o instanceof List) { + List loop = (List)o; + if (loop.contains(r)) + loops.add(loop); + } + } + + // Debug print the result + if (false) { + System.out.println(cyclesToString(g, cycles)); + } + + return loops; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static List> getAllLoopsInDiagram(ReadGraph g, Resource r) throws DatabaseException, ServiceException { + Layer0 l0 = Layer0.getInstance(g); + SysdynResource sr = SysdynResource.getInstance(g); + Resource configuration = g.getPossibleObject(r, l0.PartOf); + if (configuration == null) + return Collections.emptyList(); + + Collection variables = g.getObjects(configuration, l0.ConsistsOf); + ArrayList shadows = new ArrayList(); + + // Leave only independent variables and shadows (and modules) + Iterator it = variables.iterator(); + while (it.hasNext()) { + Resource v = it.next(); + if (g.isInstanceOf(v, sr.IndependentVariable)) { + } else if (g.isInstanceOf(v, sr.Shadow)) { + shadows.add(v); + it.remove(); + /*} else if (|| g.isInstanceOf(v, sr.Module)) { + */ + } else { + it.remove(); + } + } + + int variableCount = variables.size(); + Resource nodes[] = new Resource[variableCount]; + + // Add independent variables to map and array + int k = 0; + HashMap elementaryLoopItems = new HashMap(); + for (Resource variable : variables) { + ArrayList dependingVariables = new ArrayList(); + // Add forward dependencies and flows from valves. + Collection dependencies = g.getObjects(variable, sr.Variable_isTailOf); + for (Resource dependency : dependencies) { + Resource head = g.getPossibleObject(dependency, sr.Variable_HasHead); + // Skip dependencies and flows to modules and clouds. + if (head == null + || g.isInstanceOf(head, sr.Module) + || g.isInstanceOf(head, sr.Cloud)) + continue; + + if ((g.isInstanceOf(dependency, sr.Flow) && g.isInstanceOf(variable, sr.Valve)) + || g.isInstanceOf(dependency, sr.Dependency)) { + // Add all dependencies + // Add (only) such flows that start from a valve. + dependingVariables.add(head); + } + } + // Add backward flows from stocks. + Collection backwardFlows = g.getObjects(variable, sr.Variable_isHeadOf); + for (Resource flow : backwardFlows) { + if (g.isInstanceOf(flow, sr.Flow)) { + Resource tail = g.getPossibleObject(flow, sr.Variable_HasTail); + if (tail != null && g.isInstanceOf(tail, sr.Stock)) { + // Add (only) such flows that start from a stock. + dependingVariables.add(tail); + } + } + } + // Put the variable in the hash map. + elementaryLoopItems.put(variable, new ElementaryLoopItem(k, dependingVariables)); + nodes[k++] = variable; + } + + // Add dependencies of shadow variables for their original variables + for (Resource shadow : shadows) { + Resource original = g.getPossibleObject(shadow, sr.Shadow_original); + ArrayList dependingVariables = new ArrayList(); + Collection dependencies = g.getObjects(shadow, sr.Variable_isTailOf); + for (Resource dependency : dependencies) { + Resource head = g.getPossibleObject(dependency, sr.Variable_HasHead); + if (!g.isInstanceOf(head, sr.Module)) { + dependingVariables.add(head); + } + } + elementaryLoopItems.get(original).dependencies.addAll(dependingVariables); + } + + // Fill the adjacent matrix + boolean adjMatrix[][] = new boolean[variableCount][variableCount]; + for (int j = 0; j < nodes.length; ++j) { + ArrayList dependingVariables = elementaryLoopItems.get(nodes[j]).dependencies; + for (Resource v : dependingVariables) { + adjMatrix[j][elementaryLoopItems.get(v).mapping] = true; + } + } + + // Get ALL nodes in the diagram. + ElementaryCyclesSearch ecs = new ElementaryCyclesSearch(adjMatrix, nodes); + List cycles = ecs.getElementaryCycles(); + + return cycles; + } + + /** + * Get the String representation of cycles. + * @param g + * @param cycles List of Resource Lists of which names are returned. + * @return the String representation of cycles + * @throws DatabaseException + */ + public static String cyclesToString(ReadGraph g, List> cycles) throws DatabaseException { + StringBuilder sb = new StringBuilder(""); + for (int i = 0; i < cycles.size(); i++) { + sb.append(cycleToString(g, cycles.get(i))); + sb.append("\n"); + } + return sb.toString(); + } + + /** + * Get the String representation of a cycle. + * @param g + * @param cycle List of Resources of which names are returned. + * @return the String representation of a cycle + * @throws DatabaseException + */ + public static String cycleToString(ReadGraph g, List cycle) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(g); + StringBuilder sb = new StringBuilder(""); + for (int j = 0; j < cycle.size(); j++) { + Resource node = (Resource) cycle.get(j); + if (j < cycle.size() - 1) { + sb.append(g.getPossibleRelatedValue(node, l0.HasName, Bindings.STRING) + " -> "); + } else { + sb.append(g.getPossibleRelatedValue(node, l0.HasName, Bindings.STRING)); + } + } + return sb.toString(); + } + + /** + * Get the type of the loop, i.e. whether the loop is reinforcing or balancing. + * The type is determined based on the dependency arrows and flows on the diagram; + * the loop is balancing if there is odd number of dependencies with negative + * polarity (Polarity = "-"). Note: + * 1) each flow of which tail is a valve is considered a dependency with positive + * (+) polarity. + * 2) each flow of which tail is a stock is considered a dependency with negative + * (-) polarity which GOES TO THE OPPOSITE DIRECTION. + * 3) the polarity of a supplementary dependency arrow overrides a flow. + * 4) the loops are defined as a list of Resources. If the set of dependencies + * between is ambiguous, the implementation may choose any possible dependency. + * 5) empty and null polarity are considered positive (+) polarities. + * @param graph + * @param resource The loop component + * @return the type of the loop. If the type cannot be determined, + * LoopType.UNDEFINED is returned + * @throws DatabaseException + */ + public static LoopType getLoopType(ReadGraph graph, Resource resource) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + ModelingResources mod = ModelingResources.getInstance(graph); + Resource loopResource = graph.getPossibleObject(resource, sr.Loop_Items); + + if (loopResource == null) + return LoopType.UNDEFINED; + + boolean oddNumberOfNegativeCausalities = false; + List loop = ListUtils.toPossibleList(graph, loopResource); + for (int i = 0; i < loop.size(); ++i) { + boolean skipBackwardFlows = false; + + // Go through forward dependencies and flows + Collection forwardDependencies = graph.getObjects(loop.get(i), sr.Variable_isTailOf); + for (Resource dependency : forwardDependencies) { + Resource dependingVariable = graph.getSingleObject(dependency, sr.Variable_HasHead); + if (dependingVariable.equals(loop.get((i + 1) % loop.size()))) { + if (graph.isInstanceOf(dependency, sr.Flow)) { + /* + * Forward flows never affect the loop type. Allow dependency arrows + * override flows; thus don't touch skipBackwardFlows and continue. + * continue also because we may have a flow from stock, which + * is the wrong dependency and we need to keep searching. + */ + continue; + } + skipBackwardFlows = true; + + Resource dependencyConnection = graph.getSingleObject(dependency, mod.ConnectionToDiagramConnection); + String polarity = (String)graph.getPossibleRelatedValue(dependencyConnection, sr.DependencyConnection_polarity, Bindings.STRING); + if ("-".equals(polarity)) { + oddNumberOfNegativeCausalities = !oddNumberOfNegativeCausalities; + } else if (polarity != null + && !"".equals(polarity) + && !"+".equals(polarity)) { + // There's something other than + in one of the dependencies + return LoopType.UNDEFINED; + } + // "+" doesn't affect loop type, consider null and "" as a "+". + break; + } + } + + if (skipBackwardFlows) + continue; + + // Backward flows from stocks. + Collection backwardFlows = graph.getObjects(loop.get(i), sr.Variable_isHeadOf); + for (Resource flow : backwardFlows) { + if (graph.isInstanceOf(flow, sr.Flow)) { + Resource dependingVariable = graph.getSingleObject(flow, sr.Variable_HasTail); + if (dependingVariable.equals(loop.get((i + 1) % loop.size()))) { + if (graph.isInstanceOf(dependingVariable, sr.Stock)) { + // Basically, we should always end up here since all other + // possibilities have already been gone through. + oddNumberOfNegativeCausalities = !oddNumberOfNegativeCausalities; + break; + } + } + } + } + } + return oddNumberOfNegativeCausalities ? LoopType.BALANCING : LoopType.REINFORCING; + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ModelUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ModelUtils.java new file mode 100644 index 00000000..2d411193 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ModelUtils.java @@ -0,0 +1,201 @@ +package org.simantics.sysdyn.utils; + +import java.util.UUID; + +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.Template; +import org.simantics.document.DocumentResource; +import org.simantics.issues.ontology.IssueResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.ModelingUtils; +import org.simantics.operation.Layer0X; +import org.simantics.project.ontology.ProjectResource; +import org.simantics.spreadsheet.resource.SpreadsheetResource; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.utils.datastructures.ArrayMap; + +public class ModelUtils { + + /** + * Returns the SysdynModel where the given variable is located + * + * @param graph ReadGraph + * @param variable Variable whose model is wanted + * @return SysdynModel where variable is located + * @throws DatabaseException + */ + public static SysdynModel getModel(ReadGraph graph, Resource variable) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + Resource configuration = graph.getPossibleObject(variable, l0.PartOf); + if(configuration == null) + return null; + SysdynModelManager sdm = SysdynModelManager.getInstance(Simantics.getSession()); + SysdynModel model = sdm.getModel(graph, configuration); + try { + model.update(graph); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + return model; + } + + public static void createModel(WriteGraph graph) { + createModelAt(graph, Simantics.getProject().get()); + } + + public static Resource createModelAt(WriteGraph g, Resource library) { + try { + Layer0 l0 = Layer0.getInstance(g); + Layer0X L0X = Layer0X.getInstance(g); + SysdynResource sr = SysdynResource.getInstance(g); + SpreadsheetResource SHEET = SpreadsheetResource.getInstance(g); + ModelingUtils mu = new ModelingUtils(g); + DocumentResource DOC = DocumentResource.getInstance(g); + + String modelName = NameUtils.findFreshName(g, "Model", library, l0.ConsistsOf, "%s%d"); + + Resource project = Simantics.getProject().get(); + Resource model = GraphUtils.create2(g, + sr.SysdynModel, + l0.PartOf, project, + l0.HasName, modelName, + l0.HasLabel, modelName, + L0X.IsActivatedBy, project + ); + + GraphUtils.create2(g, + sr.Validations_Dependencies_MissingDependencyConnectionsIssueSource, + L0X.IsActivatedBy, model, + l0.PartOf, model + ); + + GraphUtils.create2(g, + sr.Validations_Dependencies_DependencyConnectionsIssueSource, + L0X.IsActivatedBy, model, + l0.PartOf, model + ); + + GraphUtils.create2(g, + sr.Validations_Expressions_ExpressionIssueSource, + L0X.IsActivatedBy, model, + l0.PartOf, model + ); + + GraphUtils.create2(g, + sr.Validations_Enumerations_EnumerationIssueSource, + L0X.IsActivatedBy, model, + l0.PartOf, model + ); + + GraphUtils.create2(g, + sr.Validations_Units_UnitIssueSource, + L0X.IsActivatedBy, model, + l0.PartOf, model, + IssueResource.getInstance(g).IssueSource_active, false + ); + + Resource conf = GraphUtils.create2(g, + sr.Configuration, + l0.PartOf, model, + L0X.IsBaseRealizationOf, model, + l0.HasName, modelName + ); + + Resource diagram = g.newResource(); + g.adapt(sr.ConfigurationDiagramTemplate, Template.class).apply(g, + ArrayMap + .keys("", "diagram", "name") + .values(conf, diagram, "Diagrammi") + ); + + g.claim(model, mu.SIMU.HasConfiguration, conf); + + Resource book = g.newResource(); + g.claim(book, l0.InstanceOf, null, SHEET.Book); + g.addLiteral(book, l0.HasName, l0.NameOf, l0.String, "Book" + UUID.randomUUID().toString(), Bindings.STRING); + g.claim(conf, l0.ConsistsOf, l0.PartOf, book); + + SheetUtils.createSheet(g, book, "Sheet1", new String[] { }, new int[] { 50 }); + + + + ModelingResources mr = ModelingResources.getInstance(g); + // Remove default mapping and add sysdyn mapping + for(Resource trigger : g.getObjects(diagram, L0X.HasTrigger)) { + if(g.isInstanceOf(trigger, mr.DiagramToCompositeMapping)) { + g.deny(diagram, L0X.HasTrigger, trigger); + } + } + Resource mapping = g.newResource(); + g.claim(mapping, l0.InstanceOf, null, sr.DiagramToCompositeMapping); + g.claim(diagram, L0X.HasTrigger, mapping); + + Resource report = GraphUtils.create2(g, DOC.Report, DOC.HasDocumentation, "===Report==="); + + GraphUtils.create2(g, sr.BasicExperiment, + l0.HasName, "Experiment", + l0.HasLabel, "Experiment", + DOC.HasReportFactory, report, + l0.PartOf, model); + + ProjectResource PROJ = ProjectResource.getInstance(g); + for(Resource dep : g.getObjects(library, l0.IsLinkedTo)) { + if(g.isInstanceOf(dep, PROJ.NamespaceRequirement)) { + for(Resource req : g.getObjects(dep, PROJ.RequiresNamespace)) { + String uri = g.getPossibleValue(req, Bindings.STRING); + if(uri != null) { + Resource target = g.getResource(uri); + if(target != null) { + g.claim(model, l0.IsLinkedTo, null, target); + } + } + } + } + } + + createSCLMain(g, model); + + ProfileEntries.createStandardProfiles(g, model); + + return model; + + } catch (DatabaseException e ) { + Logger.defaultLogError(e); + } + + return null; + } + + public static void createSCLMain(WriteGraph graph, Resource model) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource SCLModule = GraphUtils.create2(graph, + L0.SCLModule, + L0.PartOf, model, + L0.HasName, "SCLMain" + ); + + if(graph.hasStatement(SCLModule, L0.SCLModule_definition)) + graph.deny(SCLModule, L0.SCLModule_definition); + + graph.claimLiteral(SCLModule, L0.SCLModule_definition, "include \"Simantics/DB\"\n" + + "include \"Simantics/Variables\"\n" + + "include \"Simantics/Sysdyn\"\n" + + "include \"Simupedia/Sysdyn\" as SD\n" + + "include \"http://www.simantics.org/Documentation-1.2/Components\"\n" + + "include \"http://www.simantics.org/Documentation-1.2/Properties\" as Properties\n" + + "include \"http://www.simantics.org/Documentation-1.2/Relations\" as Relations\n" + + "include \"Simupedia/simupedia\"", Bindings.STRING); + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ModuleSummary.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ModuleSummary.java new file mode 100644 index 00000000..ed0f25b0 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ModuleSummary.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.utils; + +public class ModuleSummary { + + private int variables = 0; + private int totalVariables = 0; + private int auxiliaries = 0; + private int stocks = 0; + private int valves = 0; + private int inputs = 0; + private int shadows = 0; + private int modules = 0; + private int enumerations = 0; + private int sheets = 0; + + + + public int getVariables() { + return variables; + } + public void setVariables(int variables) { + this.variables = variables; + } + public int getTotalVariables() { + return totalVariables; + } + public void setTotalVariables(int totalVariables) { + this.totalVariables = totalVariables; + } + public int getAuxiliaries() { + return auxiliaries; + } + public void setAuxiliaries(int auxiliaries) { + this.auxiliaries = auxiliaries; + } + public int getStocks() { + return stocks; + } + public void setStocks(int stocks) { + this.stocks = stocks; + } + public int getValves() { + return valves; + } + public void setValves(int valves) { + this.valves = valves; + } + public int getInputs() { + return inputs; + } + public void setInputs(int inputs) { + this.inputs = inputs; + } + public int getShadows() { + return shadows; + } + public void setShadows(int shadows) { + this.shadows = shadows; + } + public int getModules() { + return modules; + } + public void setModules(int modules) { + this.modules = modules; + } + public int getEnumerations() { + return enumerations; + } + public void setEnumerations(int enumerations) { + this.enumerations = enumerations; + } + public int getSheets() { + return sheets; + } + public void setSheets(int sheets) { + this.sheets = sheets; + } + + public void add(ModuleSummary otherSummary) { + setAuxiliaries(getAuxiliaries() + otherSummary.getAuxiliaries()); + setEnumerations(getEnumerations() + otherSummary.getEnumerations()); + setInputs(getInputs() + otherSummary.getInputs()); + setModules(getModules() + otherSummary.getModules()); + setShadows(getShadows() + otherSummary.getShadows()); + setStocks(getStocks() + otherSummary.getStocks()); + setValves(getValves() + otherSummary.getValves()); + setVariables(getVariables() + otherSummary.getVariables()); + setTotalVariables(getTotalVariables() + otherSummary.getTotalVariables()); + setSheets(getSheets() + otherSummary.getSheets()); + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ModuleSummaryRequest.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ModuleSummaryRequest.java new file mode 100644 index 00000000..1d3267d1 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ModuleSummaryRequest.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.utils; + +import java.util.HashMap; +import java.util.Map; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Read; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.Auxiliary; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.Enumeration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Input; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.Redeclaration; +import org.simantics.sysdyn.representation.Shadow; +import org.simantics.sysdyn.representation.Sheet; +import org.simantics.sysdyn.representation.Stock; +import org.simantics.sysdyn.representation.Valve; +import org.simantics.sysdyn.representation.Variable; + +public class ModuleSummaryRequest implements Read { + + private Resource module; + private boolean recursive; + + public ModuleSummaryRequest(Resource module, boolean recursive) { + this.module = module; + this.recursive = recursive; + } + + @Override + public ModuleSummary perform(ReadGraph graph) throws DatabaseException { + SysdynResource SR = SysdynResource.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + StructuralResource2 SR2 = StructuralResource2.getInstance(graph); + + ModuleSummary result = new ModuleSummary(); + + if(module == null) + return result; + + Resource configuration; + if(graph.isInstanceOf(module, SR.SysdynModel)) + configuration = graph.getPossibleObject(module, SIMU.HasConfiguration); + else if(graph.isInheritedFrom(module, SR.Module)) + configuration = graph.getPossibleObject(module, SR2.IsDefinedBy); + else + configuration = null; + + if(configuration == null) + return result; + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, configuration); + sm.update(graph); + + result.add(collectSummary(sm.getConfiguration(), recursive, new HashMap())); + + return result; + } + + private ModuleSummary collectSummary(Configuration configuration, boolean recursive, Map enumerationOverrides) { + ModuleSummary result = new ModuleSummary(); + + for(IElement e : configuration.getElements()) { + if(e instanceof Input) + result.setInputs(result.getInputs() + 1); + + if(e instanceof Auxiliary) + result.setAuxiliaries(result.getAuxiliaries() + 1); + + if(e instanceof Stock) + result.setStocks(result.getStocks() + 1); + + if(e instanceof Shadow) + result.setShadows(result.getShadows() + 1); + + if(e instanceof Valve) + result.setValves(result.getValves() + 1); + + if(e instanceof Enumeration) + result.setEnumerations(result.getEnumerations() + 1); + + if(e instanceof Sheet) + result.setSheets(result.getSheets() + 1); + + if(e instanceof Variable && !(e instanceof Sheet)) { + result.setVariables(result.getVariables() + 1); + + int n = 1; + Variable var = (Variable) e; + if(var.getArrayIndexes() != null && var.getArrayIndexes().size() > 0) { + for(Enumeration enumeration : var.getArrayIndexes()) { + if(enumerationOverrides.containsKey(enumeration.getName())) { + n = n * enumerationOverrides.get(enumeration.getName()); + } else { + n = n * enumeration.getEnumerationIndexes().size(); + } + } + } + result.setTotalVariables(result.getTotalVariables() + n); + } + + if(e instanceof Module) { + result.setModules(result.getModules() + 1); + + if(recursive) { + Module m = (Module) e; + HashMap redeclarations = new HashMap(); + for(Redeclaration redeclaration : m.getRedeclarations()) { + int n; + if(enumerationOverrides.containsKey(redeclaration.getReplacingEnumeration())) { + n = enumerationOverrides.get(redeclaration.getReplacingEnumeration()); + } else { + n = redeclaration.getReplacingEnumeration().getEnumerationIndexes().size(); + } + redeclarations.put(redeclaration.getReplacedEnumeration().getName(), n); + } + result.add(collectSummary(m.getType().getConfiguration(), recursive, redeclarations)); + } + } + } + + + return result; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ProfileEntries.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ProfileEntries.java new file mode 100644 index 00000000..f53920c9 --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/ProfileEntries.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.utils; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.diagram.profile.Profiles; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; + +public class ProfileEntries { + + + public static void createStandardProfiles(WriteGraph graph, final Resource model) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + DiagramResource DIA = DiagramResource.getInstance(graph); + + Resource simulationPlaybackProfile = createProfile(graph, "Simulation Playback", sr.SimulationPlaybackProfile ,sr.Profiles_SimulationPlaybackColours); + + Resource defaultProfile = createProfile(graph, "Default", sr.DefaultProfile, sr.Profiles_IssueWarnings, sr.Profiles_ShadowVisualizations); + + //graph.claim(model, DIA.HasProfile, defaultProfile); + graph.claim(model, L0.ConsistsOf, simulationPlaybackProfile); + graph.claim(model, L0.ConsistsOf, defaultProfile); + + // FIXME: add virtual graph write back once this is fixed: https://www.simulationsite.net/redmine/issues/3296 +// graph.sync(new WriteRequest(graph.getService(VirtualGraphSupport.class).getWorkspacePersistent("profiles")) { +// @Override +// public void perform(WriteGraph graph) throws DatabaseException { +// DiagramResource DIA = DiagramResource.getInstance(graph); + graph.claim(model, DIA.HasActiveProfile, defaultProfile); +// } +// }); + + } + + public static Resource createProfile(WriteGraph graph, String name, Resource type, Resource... entries) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + + Resource profile = Profiles.createProfile(graph, name, + entries); + + graph.deny(profile, L0.InstanceOf); + graph.claim(profile, L0.InstanceOf, null, type); + return profile; + } + +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/SheetUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/SheetUtils.java new file mode 100644 index 00000000..9bda6cab --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/SheetUtils.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.utils; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.layer0.Layer0; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.spreadsheet.SheetVariables; +import org.simantics.spreadsheet.resource.SpreadsheetResource; + +public class SheetUtils { + + public static Resource createSheet(WriteGraph graph, Resource book, String name, String[] colNames, int[] colWidths) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + SpreadsheetResource sr = SpreadsheetResource.getInstance(graph); + + Resource result = graph.newResource(); + graph.claim(result, L0.InstanceOf, null, sr.Spreadsheet); + + if(name == null) { + name = NameUtils.findFreshEscapedName(graph, "Sheet", book, L0.ConsistsOf); + } + graph.claimLiteral(result, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING); + graph.claim(book, L0.ConsistsOf, L0.PartOf, result); + + { + Resource newCell = graph.newResource(); + graph.claim(newCell, L0.InstanceOf, null, sr.Dimensions); + graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Dimensions", Bindings.STRING); + graph.addLiteral(newCell, sr.Dimensions_fitColumns, sr.Dimensions_fitColumns_Inverse, L0.Boolean, false, Bindings.BOOLEAN); + graph.addLiteral(newCell, sr.Dimensions_fitRows, sr.Dimensions_fitRows_Inverse, L0.Boolean, false, Bindings.BOOLEAN); + graph.addLiteral(newCell, sr.Dimensions_columnCount, sr.Dimensions_columnCount_Inverse, L0.Integer, 128, Bindings.INTEGER); + graph.addLiteral(newCell, sr.Dimensions_rowCount, sr.Dimensions_rowCount_Inverse, L0.Integer, 256, Bindings.INTEGER); + graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell); + } + + { + Resource newCell = graph.newResource(); + graph.claim(newCell, L0.InstanceOf, null, sr.Headers); + graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Headers", Bindings.STRING); + graph.addLiteral(newCell, sr.Headers_columnLabels, sr.Headers_columnLabels_Inverse, L0.StringArray, colNames, Bindings.STRING_ARRAY); + graph.addLiteral(newCell, sr.Headers_columnWidths, sr.Headers_columnWidths_Inverse, L0.IntegerArray, colWidths, Bindings.INT_ARRAY); + graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell); + } + +// { +// +// double[] doubles = new double[10*2]; +// for(int i=0;i<10*2;i++) doubles[i] = i; +// +// Resource newCell = graph.newResource(); +// graph.claim(newCell, L0.InstanceOf, null, sr.DoubleArrayCell); +// graph.addLiteral(newCell, sr.DoubleArrayCell_HasWidth, sr.DoubleArrayCell_HasWidth_Inverse, L0.Integer, 10, Bindings.INTEGER); +// graph.addLiteral(newCell, sr.HasLocation, sr.HasLocation_Inverse, L0.String, "B2", Bindings.STRING); +// graph.addLiteral(newCell, sr.DoubleArrayCell_HasDoubleArray, sr.DoubleArrayCell_HasDoubleArray_Inverse, L0.DoubleArray, doubles, Bindings.DOUBLE_ARRAY); +// graph.claim(result, L0.HasChildVariables, L0.HasChildVariables_Inverse, newCell); +// +// } + + return result; + + } + + public static String getStringRepresentation(ReadGraph graph, Resource model, String sheetName, String range) throws DatabaseException { + Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration); + Layer0 L0 = Layer0.getInstance(graph); + SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph); + Variable sheetVariable = null; + for(Resource book : graph.syncRequest(new ObjectsWithType(configuration, L0.ConsistsOf, SHEET.Book))) { + for(Resource sheet : graph.syncRequest(new ObjectsWithType(book, L0.ConsistsOf, SHEET.Spreadsheet))) { + if(sheetName.equals(NameUtils.getSafeName(graph, sheet))) { + sheetVariable = Variables.getVariable(graph, sheet); + } + } + } + + if(sheetVariable == null) + return null; + + Variable rangeVariable = sheetVariable.getChild(graph, range); + + + String[][] rangeCells = rangeVariable.getPropertyValue(graph, SheetVariables.RANGE_CELL_NAMES); + if(rangeCells == null || rangeCells[0].length <= 1) + return null; + else { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + for(int i = 0; i < rangeCells.length; i++) { + sb.append("{"); + for(int j = 0; j < rangeCells[i].length; j++) { + String valueCell = rangeCells[i][j]; + Variable cell = sheetVariable.getChild(graph, valueCell); + Variant valueVariant = cell.getPropertyValue(graph, SheetVariables.CONTENT, Bindings.VARIANT); + Object valueObject = valueVariant.getValue(); + sb.append(valueObject.toString()); + if(j < rangeCells[i].length - 1) + sb.append(", "); + } + sb.append("}"); + if(i < rangeCells.length - 1) + sb.append(", "); + } + sb.append("}"); + + return sb.toString(); + } + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/ImportUtils.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/ImportUtils.java new file mode 100644 index 00000000..75a83b4b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/ImportUtils.java @@ -0,0 +1,616 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - Bug #4192 + *******************************************************************************/ +package org.simantics.sysdyn.utils.imports; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.simantics.Simantics; +import org.simantics.databoard.container.DataContainers; +import org.simantics.databoard.container.DataFormatException; +import org.simantics.databoard.container.FormatHandler; +import org.simantics.db.Issue; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.request.WriteResultRequest; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor; +import org.simantics.db.layer0.migration.MigrationState; +import org.simantics.db.layer0.migration.MigrationStateKeys; +import org.simantics.db.layer0.migration.MigrationUtils; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.db.request.Read; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.issues.common.AllBatchIssueSources; +import org.simantics.issues.common.BatchIssueSource; +import org.simantics.issues.ontology.IssueResource; +import org.simantics.layer0.Layer0; +import org.simantics.layer0.utils.direct.GraphUtils; +import org.simantics.modeling.utils.BatchValidations; +import org.simantics.operation.Layer0X; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.sysdyn.Activator; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.utils.ModelUtils; + +/** + * Utilities for importing tg files: Models, Modules and Function libraries + * @author Teemu Lempinen + * + */ +public class ImportUtils { + + /** + * Null-checked begin task for monitor + * @param monitor + * @param taskName + * @param totalWork + */ + private static void beginTask(IProgressMonitor monitor, String taskName, int totalWork) { + if(monitor != null) + monitor.beginTask(taskName, totalWork); + } + + /** + * Null-checked sub task for monitor + * @param monitor + * @param taskName + */ + private static void subTask(IProgressMonitor monitor, String taskName) { + if(monitor != null) + monitor.subTask(taskName); + } + + /** + * Null-checked worked command for monitor + * @param monitor + * @param work + */ + private static void worked(IProgressMonitor monitor, int work) { + if(monitor != null) + monitor.worked(work); + } + + + /** + * Read a file from hard drive using handlers + * @param path + * @param handlers + * @return IStatus if import failed, otherwise the result is determined by handlers + */ + public static Object readFile(String path, HashMap> handlers) { + Object result = null; + try { + File file = new File(path); + if(!file.isFile()) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import failed: File " + path + " not found", null); + } else { + result = DataContainers.readFile(file, handlers); + } + } catch(DataFormatException e) { + e.printStackTrace(); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import failed", e); + } catch(IOException e) { + e.printStackTrace(); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import failed", e); + } catch(Exception e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import failed", e); + } + return result; + } + + + + /* ********************************* */ + /* ******* IMPORT MODEL ********* */ + /* ********************************* */ + public static IStatus importModelFile(String path, final IProgressMonitor monitor) { + return importModelFile(path, monitor, null); + } + public static IStatus importModelFile(String path, final IProgressMonitor monitor, Function1 callback) { + final Resource project = Simantics.getProject().get(); + if(project == null) return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import model: project not found", null); + + beginTask(monitor, "Import model", 10); + + MigrationState state = MigrationUtils.newState(); + state.setProperty(MigrationStateKeys.BASE_URI, SysdynResource.URIs.Migration); + state.setProperty(MigrationStateKeys.UPDATE_DEPENDENCIES, Boolean.FALSE); + + Resource result = null; + try { + result = MigrationUtils.importMigrated(monitor, Simantics.getSession(), new File(path), state, new DefaultPasteImportAdvisor(project), project); + } catch (Exception e1) { + e1.printStackTrace(); + } + + if(result == null || !(result instanceof Resource)) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import model failed: File could not be read.", null); + } else { + try { + final Resource ModelRoot = result; + IStatus status = Simantics.getSession().syncRequest(new WriteResultRequest() { + + @Override + public IStatus perform(WriteGraph graph) throws DatabaseException { + if(!graph.isInstanceOf(ModelRoot, SysdynResource.getInstance(graph).SysdynModel)) { + // Imported model was not a SysdynModel, display error message. + Resource instanceOf = graph.getPossibleObject(ModelRoot, Layer0.getInstance(graph).InstanceOf); + String type = "..."; + if(instanceOf != null) + type = NameUtils.getSafeName(graph, instanceOf); + else { + Resource inheritedFrom = graph.getPossibleObject(ModelRoot, Layer0.getInstance(graph).Inherits); + if(inheritedFrom != null) + type = NameUtils.getSafeName(graph, inheritedFrom); + } + final String ft = type; + graph.deny(ModelRoot, Layer0.getInstance(graph).PartOf); + + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "The imported file is not of type: System Dynamics Model (" + ft +")", null); + } else { + subTask(monitor, "Add required dependencies"); + addDependencies(graph, ModelRoot); + worked(monitor, 1); + subTask(monitor, "Remove unnecessary issue sources"); + removeIssueSourcesFromModules(graph, ModelRoot); + worked(monitor, 1); + subTask(monitor, "Add enumeration issue source"); + addEnumerationIssueSource(graph, ModelRoot); + worked(monitor, 1); + subTask(monitor, "Add unit issue source"); + addUnitIssueSource(graph, ModelRoot); + worked(monitor, 1); + subTask(monitor, "Add shadow profile"); + addShadowProfile(graph, ModelRoot); + worked(monitor, 1); + subTask(monitor, "Add SCL Main"); + addSCLMain(graph, ModelRoot); + worked(monitor, 1); + subTask(monitor, "Activate model"); + activateModel(graph, ModelRoot); + worked(monitor, 1); + } + return null; + + } + + + }); + + if(status != null) + return status; + + subTask(monitor, "Validate model"); + Collection confs = Simantics.getSession().syncRequest(new Read>() { + + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + return findAllConfigurations(graph, ModelRoot); + } + + }); + + + // Batch validate all issue sources after import + try { + for(Resource conf : confs) { + /* + * This section is copied from BatchValidations.runAll. runAll did + * not find module types to validate. + */ +// BatchValidations.runAll(null, mod); + + final Session session = Simantics.getSession(); + final Collection validations = session.sync( new AllBatchIssueSources(ModelRoot) ); + SubMonitor progress = null; + if(monitor != null) + progress = SubMonitor.convert(monitor, "Validate Model", 100); + Collection contexts = Collections.singletonList(conf); + for(BatchIssueSource bis : validations) { + Map> is = BatchValidations.validate(monitor != null ? progress.newChild(90, SubMonitor.SUPPRESS_NONE) : null, bis, contexts); + BatchValidations.store(monitor != null ? progress.newChild(10, SubMonitor.SUPPRESS_NONE) : null, bis.getResource(), is); + } + } + } catch(Throwable t) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Batch validate failed: Model could not be imported.", t); + } + + worked(monitor, 1); + + if(callback != null) { + WriteRequest userRequest = callback.apply(result); + if(userRequest != null) + Simantics.sync(userRequest); + } + + } catch (DatabaseException e) { + e.printStackTrace(); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import model failed: Model could not be imported.", e); + } + + return Status.OK_STATUS; + } + } + + protected static void addSCLMain(WriteGraph graph, Resource modelRoot) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + + Collection SCLModules = graph.syncRequest(new ObjectsWithType(modelRoot, L0.ConsistsOf, L0.SCLModule)); + + boolean hasIt = false; + + for(Resource r : SCLModules) { + if("SCLMain".equals(NameUtils.getSafeName(graph, r))) { + hasIt = true; + break; + } + } + + if(!hasIt) { + ModelUtils.createSCLMain(graph, modelRoot); + } + + } + + private static void removeIssueSourcesFromModules(WriteGraph graph, Resource modelRoot) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + IssueResource ISSUE = IssueResource.getInstance(graph); + + for(Resource m : findAllModelsAndModules(graph, modelRoot)) { + if(m.equals(modelRoot)) + continue; + + // Module may contain issue sources due to legacy reasons. Remove these. + for(Resource issueSource : graph.syncRequest(new ObjectsWithType(m, L0.ConsistsOf, ISSUE.IssueSource))) { + // Issues are created to virtual graphs, so they should not need to be removed. Just in case they are created, remove them first + for(Resource issue : graph.getObjects(issueSource, ISSUE.IssueSource_Manages)) { + RemoverUtil.remove(graph, issue); + } + + // finally remove the issue source + RemoverUtil.remove(graph, issueSource); + } + } + + } + + private static void activateModel(WriteGraph graph, Resource modelRoot) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + if(!graph.hasStatement(modelRoot, L0X.IsActivatedBy)) { + Resource project = graph.getPossibleObject(modelRoot, L0.PartOf); + if(project != null) { + graph.claim(modelRoot, L0X.IsActivatedBy, project); + } + } + } + + private static void addDependencies(WriteGraph graph, Resource modelRoot) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + + ArrayList links = new ArrayList(); + for(Resource link : graph.getObjects(modelRoot, L0.IsLinkedTo)) + links.add(graph.getURI(link)); + + if(!links.contains("http://www.semantum.fi/Simupedia-1.0")) { + Resource simupedia = graph.getPossibleResource("http://www.semantum.fi/Simupedia-1.0"); + if(simupedia != null) + graph.claim(modelRoot, L0.IsLinkedTo, simupedia); + } + + if(!links.contains("http://www.simantics.org/SelectionView-1.2")) { + Resource selectionView = graph.getPossibleResource("http://www.simantics.org/SelectionView-1.2"); + if(selectionView != null) + graph.claim(modelRoot, L0.IsLinkedTo, selectionView); + } + + if(!links.contains("http://www.semantum.fi/SimupediaWorkbench-1.0")) { + Resource simupediaWb = graph.getPossibleResource("http://www.semantum.fi/SimupediaWorkbench-1.0"); + if(simupediaWb != null) + graph.claim(modelRoot, L0.IsLinkedTo, simupediaWb); + } + + if(!links.contains("http://www.simantics.org/Documentation-1.2")) { + Resource documentation = graph.getPossibleResource("http://www.simantics.org/Documentation-1.2"); + if(documentation != null) + graph.claim(modelRoot, L0.IsLinkedTo, documentation); + } + } + + private static void addEnumerationIssueSource(WriteGraph graph, Resource modelRoot) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Collection enumerationIssueSources = graph.syncRequest(new ObjectsWithType(modelRoot, L0.ConsistsOf, sr.Validations_Enumerations_EnumerationIssueSource)); + if(enumerationIssueSources.isEmpty()) { + GraphUtils.create2(graph, + sr.Validations_Enumerations_EnumerationIssueSource, + L0X.IsActivatedBy, modelRoot, + L0.PartOf, modelRoot + ); + } + } + + + private static void addUnitIssueSource(WriteGraph graph, Resource modelRoot) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Collection unitIssueSources = graph.syncRequest(new ObjectsWithType(modelRoot, L0.ConsistsOf, sr.Validations_Units_UnitIssueSource)); + if(unitIssueSources.isEmpty()) { + GraphUtils.create2(graph, + sr.Validations_Units_UnitIssueSource, + L0X.IsActivatedBy, modelRoot, + L0.PartOf, modelRoot, + IssueResource.getInstance(graph).IssueSource_active, false + ); + } + } + + private static void addShadowProfile(WriteGraph graph, Resource modelRoot) throws DatabaseException { + DiagramResource DIA = DiagramResource.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + Resource defaultProfile = graph.syncRequest(new PossibleObjectWithType(modelRoot, Layer0.getInstance(graph).ConsistsOf, SR.DefaultProfile)); + if(defaultProfile != null) { + Resource entryList = graph.getPossibleObject(defaultProfile, DIA.HasEntries); + if(entryList != null) { + List entries = ListUtils.toList(graph, entryList); + if(entries != null && !entries.contains(SR.Profiles_ShadowVisualizations)) { + ListUtils.insertBack(graph, entryList, Collections.singletonList(SR.Profiles_ShadowVisualizations)); + } + } + + } + } + + private static Collection findAllConfigurations(ReadGraph graph, Resource modelRoot) throws DatabaseException { + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 SR2 = StructuralResource2.getInstance(graph); + Collection modulesAndModels = findAllModelsAndModules(graph, modelRoot); + Collection configurations = new ArrayList(); + + for(Resource r : modulesAndModels) { + if(graph.isInheritedFrom(r, sr.Module)) { + configurations.add(graph.getPossibleObject(r, SR2.IsDefinedBy)); + } else if(graph.isInstanceOf(r, sr.SysdynModel)) { + configurations.add(graph.getPossibleObject(modelRoot, SimulationResource.getInstance(graph).HasConfiguration)); + } + } + + return configurations; + } + + private static Collection findAllModelsAndModules(ReadGraph graph, Resource modelRoot) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Collection modelsAndModules = new ArrayList(); + modelsAndModules.add(modelRoot); + + for(Resource r : graph.getObjects(modelRoot, L0.ConsistsOf)) { + if(graph.isInheritedFrom(r, sr.Module)) { + modelsAndModules.add(r); + } + } + + return modelsAndModules; + } + + /* ********************************* */ + /* ******* IMPORT MODULE ********* */ + /* ********************************* */ + public static IStatus importModuleFile(final Resource model, String path, final IProgressMonitor monitor) { + beginTask(monitor, "Import Module", 3); + + MigrationState state = MigrationUtils.newState(); + state.setProperty(MigrationStateKeys.BASE_URI, SysdynResource.URIs.Migration); + state.setProperty(MigrationStateKeys.UPDATE_DEPENDENCIES, Boolean.FALSE); + + Resource result = null; + try { + result = MigrationUtils.importMigrated(monitor, Simantics.getSession(), new File(path), state, new DefaultPasteImportAdvisor(model), model); + } catch (Exception e1) { + e1.printStackTrace(); + } + + + if(result == null) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import module failed: Module could not be imported.", null); + } else { + final Resource ModuleRoot = result; + // Check that the imported file actually was a module. Display error message otherwise. + try { + subTask(monitor, "Validate model"); + IStatus status = Simantics.getSession().syncRequest(new WriteResultRequest() { + + @Override + public IStatus perform(WriteGraph graph) throws DatabaseException { + if(!graph.isInheritedFrom(ModuleRoot, SysdynResource.getInstance(graph).Module)) { + Resource instanceOf = graph.getPossibleObject(ModuleRoot, Layer0.getInstance(graph).InstanceOf); + String type = "..."; + if(instanceOf != null) + type = NameUtils.getSafeName(graph, instanceOf); + else { + Resource inheritedFrom = graph.getPossibleObject(ModuleRoot, Layer0.getInstance(graph).Inherits); + if(inheritedFrom != null) + type = NameUtils.getSafeName(graph, inheritedFrom); + } + final String ft = type; + graph.deny(ModuleRoot, Layer0.getInstance(graph).PartOf); + + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "The imported file is not of type: System Dynamics Module (" + ft +")", null); + } + return null; + } + }); + + if(status != null) + return status; + worked(monitor, 1); + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } + + return Status.OK_STATUS; + } + + + + /* ********************************* */ + /* *** IMPORT FUNCTION LIBRARY *** */ + /* ********************************* */ + + public static IStatus importFunctionLibrary(final Resource functionLibrary, final String path, final IProgressMonitor monitor) { + beginTask(monitor, "Import Module", 3); + + // Ensure that shared functions ontology exists + ensureSharedOntologies(); + + MigrationState state = MigrationUtils.newState(); + state.setProperty(MigrationStateKeys.BASE_URI, SysdynResource.URIs.Migration); + state.setProperty(MigrationStateKeys.UPDATE_DEPENDENCIES, Boolean.FALSE); + + Resource result = null; + try { + result = MigrationUtils.importMigrated(monitor, Simantics.getSession(), new File(path), state, new DefaultPasteImportAdvisor(functionLibrary), functionLibrary); + } catch (Exception e1) { + e1.printStackTrace(); + } + + if(result == null) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import Function library failed: Function library not be imported.", null); + } else { + final Resource FunctionLibraryRoot = (Resource) result; + // Link the imported library to the selected resource (functionLibrary) + try { + subTask(monitor, "Validate model"); + IStatus status = Simantics.getSession().syncRequest(new WriteResultRequest() { + + /** + * Link the imported library to the selected resource (functionLibrary) + * The imported library can be either SysdynModelicaFunctionLibrary or SysdynFunctionOntology + */ + @Override + public IStatus perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + // Case: SharedFunctionOntology. Link to SharedOntologies + if(graph.isInstanceOf(FunctionLibraryRoot, SysdynResource.getInstance(graph).SharedFunctionOntology)) { + Resource library = graph.getResource("http://SharedOntologies"); + if(!graph.hasStatement(library, l0.ConsistsOf, FunctionLibraryRoot)) { + graph.claim(library, l0.ConsistsOf, FunctionLibraryRoot); + } + + // Link model to the shared library + SysdynResource sr = SysdynResource.getInstance(graph); + Resource model = functionLibrary; + while(!graph.isInstanceOf(model, sr.SysdynModel) && graph.isInstanceOf(model, l0.Ontology)) + model = graph.getSingleObject(model, l0.PartOf); + if(graph.isInstanceOf(model, sr.SysdynModel)) { + graph.claim(model, l0.IsLinkedTo, l0.IsLinkedTo_Inverse, FunctionLibraryRoot); + } + + // Case: not SharedFunctionOntology or SysdynModelicaFunctionLibrary. + } else if(!graph.isInstanceOf(FunctionLibraryRoot, SysdynResource.getInstance(graph).SysdynModelicaFunctionLibrary)) { + Resource instanceOf = graph.getPossibleObject(FunctionLibraryRoot,l0.InstanceOf); + String type = "..."; + if(instanceOf != null) + type = NameUtils.getSafeName(graph, instanceOf); + else { + Resource inheritedFrom = graph.getPossibleObject(FunctionLibraryRoot, l0.Inherits); + if(inheritedFrom != null) + type = NameUtils.getSafeName(graph, inheritedFrom); + } + final String ft = type; + + // Remove the functionLibrary ConsistsOf root relation + graph.deny(FunctionLibraryRoot, l0.PartOf); + + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "The imported file is not of type: Function Library (" + ft +")", null); + } + return null; + + + } + }); + + if(status != null) + return status; + worked(monitor, 1); + + } catch (DatabaseException e) { + e.printStackTrace(); + } + } + + return Status.OK_STATUS; + } + + private static void ensureSharedOntologies() { + // Make sure the "http://SharedOntologies resource exists + try { + Boolean hasSharedOntologies; + hasSharedOntologies = Simantics.getSession().syncRequest(new Read() { + + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + try { + graph.getResource("http://SharedOntologies"); + } catch (ResourceNotFoundException e) { + return false; + } + return true; + } + }); + + if(!hasSharedOntologies) { + Simantics.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + GraphUtils.create2(graph, l0.Library, + l0.HasName, "SharedOntologies", + l0.PartOf, graph.getResource("http:/")); + } + }); + + } + } catch (DatabaseException e) { + e.printStackTrace(); + } + + } +} diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/SysdynFunctionLibraryImportAdvisor.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/SysdynFunctionLibraryImportAdvisor.java new file mode 100644 index 00000000..3373d68f --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/SysdynFunctionLibraryImportAdvisor.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.utils.imports; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteOnlyGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor; +import org.simantics.graph.representation.Root; +import org.simantics.layer0.Layer0; +import org.simantics.sysdyn.SysdynResource; + +/** + * Import advisor for importing function libraries to SysDyn + * + * @author Teemu Lempinen + * + */ +public class SysdynFunctionLibraryImportAdvisor extends DefaultPasteImportAdvisor { + + public SysdynFunctionLibraryImportAdvisor(Resource library) { + super(library); + } + + @Override + public void analyzeType(ReadGraph graph, Root root) throws DatabaseException { + // Change the library to http://SharedOntologies, if the imported library is of type SharedFunctionOntology + if(root.type.equals(SysdynResource.URIs.SharedFunctionOntology)) { + try { + library = graph.getResource("http://SharedOntologies"); + } catch (ResourceNotFoundException e) { + e.printStackTrace(); + } + } + } + + @Override + public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException { + Layer0 l0 = graph.getService(Layer0.class); + this.root = graph.newResource(); + graph.claim(library, l0.ConsistsOf, l0.PartOf, this.root); + String name = root.name; + String newName = nameMappings.get(name); + graph.addLiteral(this.root, l0.HasName, l0.NameOf, l0.String, newName, Bindings.STRING); + return this.root; + + } + +} \ No newline at end of file diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/SysdynImportFormatHandler.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/SysdynImportFormatHandler.java new file mode 100644 index 00000000..260c058b --- /dev/null +++ b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/utils/imports/SysdynImportFormatHandler.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.utils.imports; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.simantics.Simantics; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.container.DataContainer; +import org.simantics.databoard.container.DataFormatException; +import org.simantics.databoard.container.FormatHandler; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor; +import org.simantics.db.layer0.migration.MigrationState; +import org.simantics.db.layer0.migration.MigrationStateKeys; +import org.simantics.db.layer0.migration.MigrationStep; +import org.simantics.db.layer0.migration.MigrationUtils; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.sysdyn.Activator; + +/** + * Handler for migrating a tg and importing it to database + * @author Teemu Lempinen + * + */ +public class SysdynImportFormatHandler implements FormatHandler { + + private final Resource parent; + private final IProgressMonitor monitor; + private final String migrationURI; + private final DefaultPasteImportAdvisor importAdvisor; + + /** + * Works 2 (2 * 1) in the monitor + * @param parent + * @param migrationURI + * @param monitor + */ + public SysdynImportFormatHandler(Resource parent, String migrationURI, IProgressMonitor monitor) { + this(parent, migrationURI, monitor, null); + } + + public SysdynImportFormatHandler(Resource parent, String migrationURI, IProgressMonitor monitor, + DefaultPasteImportAdvisor importAdvisor) { + assert(parent != null); + assert(migrationURI != null); + this.parent = parent; + this.monitor = monitor; + this.migrationURI = migrationURI; + this.importAdvisor = importAdvisor; + } + + private void subTask(String taskName) { + if(monitor != null) + monitor.subTask(taskName); + } + + private void worked(int work) { + if(monitor != null) + monitor.worked(work); + } + + @Override + public Binding getBinding() { + return TransferableGraph1.BINDING; + } + + @Override + public Object process(DataContainer container) throws DataFormatException { + DefaultPasteImportAdvisor ia = importAdvisor != null ? importAdvisor : new DefaultPasteImportAdvisor(parent); + try { + subTask("Migrate"); + Session session = Simantics.getSession(); + TransferableGraph1 tg = (TransferableGraph1)container.content.getValue(); + + MigrationStep step = MigrationUtils.getStep(session, migrationURI); + MigrationState state = MigrationUtils.newState(); + state.setProperty(MigrationStateKeys.CURRENT_TG, tg); + step.applyTo(monitor, session, state); +// tg = state.getProperty(MigrationStateKeys.CURRENT_TG); + + worked(1); + subTask("Import"); + +// DefaultPasteHandler.defaultExecute(tg, parent, ia); + MigrationUtils.importTo(monitor, session, state, parent, ia); + worked(1); + + Resource result = state.getProperty(MigrationStateKeys.CURRENT_RESOURCE); + if(result == null) + result = ia.getRoot(); + + return result; + + } catch (Exception e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import module failed", e); + } + } + +} diff --git a/dev-jkauttio/setup/sysdyn.ism b/dev-jkauttio/setup/sysdyn.ism new file mode 100644 index 00000000..03f156e3 --- /dev/null +++ b/dev-jkauttio/setup/sysdyn.ism @@ -0,0 +1,5128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + + 1252 + Installation Database + Blank Project Template + ##COMPANY_NAME## + Installer,MSI,Database + Contact: Your local administrator + + Administrator + {2AA85B8E-AD39-4CC9-8003-4EA7B9B12CF7} + + 06/21/1999 16:00 + 07/14/2000 19:50 + 200 + 0 + + InstallShield + 1 + + + + Action + Description + Template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Advertise##IDS_ACTIONTEXT_Advertising## + AllocateRegistrySpace##IDS_ACTIONTEXT_AllocatingRegistry####IDS_ACTIONTEXT_FreeSpace##AppSearch##IDS_ACTIONTEXT_SearchInstalled####IDS_ACTIONTEXT_PropertySignature##BindImage##IDS_ACTIONTEXT_BindingExes####IDS_ACTIONTEXT_File##CCPSearch##IDS_ACTIONTEXT_UnregisterModules## + CostFinalize##IDS_ACTIONTEXT_ComputingSpace3## + CostInitialize##IDS_ACTIONTEXT_ComputingSpace## + CreateFolders##IDS_ACTIONTEXT_CreatingFolders####IDS_ACTIONTEXT_Folder##CreateShortcuts##IDS_ACTIONTEXT_CreatingShortcuts####IDS_ACTIONTEXT_Shortcut##DeleteServices##IDS_ACTIONTEXT_DeletingServices####IDS_ACTIONTEXT_Service##DuplicateFiles##IDS_ACTIONTEXT_CreatingDuplicate####IDS_ACTIONTEXT_FileDirectorySize##FileCost##IDS_ACTIONTEXT_ComputingSpace2## + FindRelatedProducts##IDS_ACTIONTEXT_SearchForRelated####IDS_ACTIONTEXT_FoundApp##GenerateScript##IDS_ACTIONTEXT_GeneratingScript####IDS_ACTIONTEXT_1##ISLockPermissionsCost##IDS_ACTIONTEXT_ISLockPermissionsCost## + ISLockPermissionsInstall##IDS_ACTIONTEXT_ISLockPermissionsInstall## + InstallAdminPackage##IDS_ACTIONTEXT_CopyingNetworkFiles####IDS_ACTIONTEXT_FileDirSize##InstallFiles##IDS_ACTIONTEXT_CopyingNewFiles####IDS_ACTIONTEXT_FileDirSize2##InstallODBC##IDS_ACTIONTEXT_InstallODBC## + InstallSFPCatalogFile##IDS_ACTIONTEXT_InstallingSystemCatalog####IDS_ACTIONTEXT_FileDependencies##InstallServices##IDS_ACTIONTEXT_InstallServices####IDS_ACTIONTEXT_Service2##InstallValidate##IDS_ACTIONTEXT_Validating## + LaunchConditions##IDS_ACTIONTEXT_EvaluateLaunchConditions## + MigrateFeatureStates##IDS_ACTIONTEXT_MigratingFeatureStates####IDS_ACTIONTEXT_Application##MoveFiles##IDS_ACTIONTEXT_MovingFiles####IDS_ACTIONTEXT_FileDirSize3##PatchFiles##IDS_ACTIONTEXT_PatchingFiles####IDS_ACTIONTEXT_FileDirSize4##ProcessComponents##IDS_ACTIONTEXT_UpdateComponentRegistration## + PublishComponents##IDS_ACTIONTEXT_PublishingQualifiedComponents####IDS_ACTIONTEXT_ComponentIDQualifier##PublishFeatures##IDS_ACTIONTEXT_PublishProductFeatures####IDS_ACTIONTEXT_FeatureColon##PublishProduct##IDS_ACTIONTEXT_PublishProductInfo## + RMCCPSearch##IDS_ACTIONTEXT_SearchingQualifyingProducts## + RegisterClassInfo##IDS_ACTIONTEXT_RegisterClassServer####IDS_ACTIONTEXT_ClassId##RegisterComPlus##IDS_ACTIONTEXT_RegisteringComPlus####IDS_ACTIONTEXT_AppIdAppTypeRSN##RegisterExtensionInfo##IDS_ACTIONTEXT_RegisterExtensionServers####IDS_ACTIONTEXT_Extension2##RegisterFonts##IDS_ACTIONTEXT_RegisterFonts####IDS_ACTIONTEXT_Font##RegisterMIMEInfo##IDS_ACTIONTEXT_RegisterMimeInfo####IDS_ACTIONTEXT_ContentTypeExtension##RegisterProduct##IDS_ACTIONTEXT_RegisteringProduct####IDS_ACTIONTEXT_1b##RegisterProgIdInfo##IDS_ACTIONTEXT_RegisteringProgIdentifiers####IDS_ACTIONTEXT_ProgID2##RegisterTypeLibraries##IDS_ACTIONTEXT_RegisterTypeLibs####IDS_ACTIONTEXT_LibId##RegisterUser##IDS_ACTIONTEXT_RegUser####IDS_ACTIONTEXT_1c##RemoveDuplicateFiles##IDS_ACTIONTEXT_RemovingDuplicates####IDS_ACTIONTEXT_FileDir##RemoveEnvironmentStrings##IDS_ACTIONTEXT_UpdateEnvironmentStrings####IDS_ACTIONTEXT_NameValueAction2##RemoveExistingProducts##IDS_ACTIONTEXT_RemoveApps####IDS_ACTIONTEXT_AppCommandLine##RemoveFiles##IDS_ACTIONTEXT_RemovingFiles####IDS_ACTIONTEXT_FileDir2##RemoveFolders##IDS_ACTIONTEXT_RemovingFolders####IDS_ACTIONTEXT_Folder1##RemoveIniValues##IDS_ACTIONTEXT_RemovingIni####IDS_ACTIONTEXT_FileSectionKeyValue##RemoveODBC##IDS_ACTIONTEXT_RemovingODBC## + RemoveRegistryValues##IDS_ACTIONTEXT_RemovingRegistry####IDS_ACTIONTEXT_KeyName##RemoveShortcuts##IDS_ACTIONTEXT_RemovingShortcuts####IDS_ACTIONTEXT_Shortcut1##Rollback##IDS_ACTIONTEXT_RollingBack####IDS_ACTIONTEXT_1d##RollbackCleanup##IDS_ACTIONTEXT_RemovingBackup####IDS_ACTIONTEXT_File2##SelfRegModules##IDS_ACTIONTEXT_RegisteringModules####IDS_ACTIONTEXT_FileFolder##SelfUnregModules##IDS_ACTIONTEXT_UnregisterModules####IDS_ACTIONTEXT_FileFolder2##SetODBCFolders##IDS_ACTIONTEXT_InitializeODBCDirs## + StartServices##IDS_ACTIONTEXT_StartingServices####IDS_ACTIONTEXT_Service3##StopServices##IDS_ACTIONTEXT_StoppingServices####IDS_ACTIONTEXT_Service4##UnmoveFiles##IDS_ACTIONTEXT_RemovingMoved####IDS_ACTIONTEXT_FileDir3##UnpublishComponents##IDS_ACTIONTEXT_UnpublishQualified####IDS_ACTIONTEXT_ComponentIdQualifier2##UnpublishFeatures##IDS_ACTIONTEXT_UnpublishProductFeatures####IDS_ACTIONTEXT_Feature##UnpublishProduct##IDS_ACTIONTEXT_UnpublishingProductInfo## + UnregisterClassInfo##IDS_ACTIONTEXT_UnregisterClassServers####IDS_ACTIONTEXT_ClsID##UnregisterComPlus##IDS_ACTIONTEXT_UnregisteringComPlus####IDS_ACTIONTEXT_AppId##UnregisterExtensionInfo##IDS_ACTIONTEXT_UnregisterExtensionServers####IDS_ACTIONTEXT_Extension##UnregisterFonts##IDS_ACTIONTEXT_UnregisteringFonts####IDS_ACTIONTEXT_Font2##UnregisterMIMEInfo##IDS_ACTIONTEXT_UnregisteringMimeInfo####IDS_ACTIONTEXT_ContentTypeExtension2##UnregisterProgIdInfo##IDS_ACTIONTEXT_UnregisteringProgramIds####IDS_ACTIONTEXT_ProgID##UnregisterTypeLibraries##IDS_ACTIONTEXT_UnregTypeLibs####IDS_ACTIONTEXT_Libid2##WriteEnvironmentStrings##IDS_ACTIONTEXT_EnvironmentStrings####IDS_ACTIONTEXT_NameValueAction##WriteIniValues##IDS_ACTIONTEXT_WritingINI####IDS_ACTIONTEXT_FileSectionKeyValue2##WriteRegistryValues##IDS_ACTIONTEXT_WritingRegistry####IDS_ACTIONTEXT_KeyNameValue##caCreateVRoots##IDS_ACTIONTEXT_CreatingIISRoots## + caRemoveVRoots##IDS_ACTIONTEXT_RemovingIISRoots## +
+ + + Action + Condition + Sequence + ISComments + ISAttributes +
CostFinalize1000CostFinalize + CostInitialize800CostInitialize + FileCost900FileCost + InstallAdminPackage3900InstallAdminPackage + InstallFiles4000InstallFiles + InstallFinalize6600InstallFinalize + InstallInitialize1500InstallInitialize + InstallValidate1400InstallValidate + ScheduleRebootISSCHEDULEREBOOT4010ScheduleReboot +
+ + + Action + Condition + Sequence + ISComments + ISAttributes +
CostFinalize1000CostFinalize + CostInitialize800CostInitialize + ExecuteAction1300ExecuteAction + FileCost900FileCost + ISVerifyScriptingRuntimeNOT AFTERREBOOT AND NOT ISSETUPDRIVEN1ISVerifyScriptingRuntime +
+ + + Action + Condition + Sequence + ISComments + ISAttributes +
CostFinalize1000CostFinalize + CostInitialize800CostInitialize + CreateShortcuts4500CreateShortcuts + InstallFinalize6600InstallFinalize + InstallInitialize1500InstallInitialize + InstallValidate1400InstallValidate + MsiPublishAssemblies6250MsiPublishAssemblies + PublishComponents6200PublishComponents + PublishFeatures6300PublishFeatures + PublishProduct6400PublishProduct + RegisterClassInfo4600RegisterClassInfo + RegisterExtensionInfo4700RegisterExtensionInfo + RegisterMIMEInfo4900RegisterMIMEInfo + RegisterProgIdInfo4800RegisterProgIdInfo + RegisterTypeLibraries4910RegisterTypeLibraries + ScheduleRebootISSCHEDULEREBOOT6410ScheduleReboot +
+ + + Action + Condition + Sequence + ISComments + ISAttributes +
+ + + AppId + RemoteServerName + LocalService + ServiceParameters + DllSurrogate + ActivateAtStorage + RunAsInteractiveUser +
+ + + Property + Signature_ +
+ + + Billboard_ + BBControl + Type + X + Y + Width + Height + Attributes + Text +
+ + + Billboard + Feature_ + Action + Ordering +
+ + + Name + Data + ISBuildSourcePath + + + +
ISSELFREG.DLL<ISProductFolder>\redist\language independent\i386\isregsvr.dllISSetup.dll<ISProductFolder>\redist\language independent\i386\ISSetup.dllISSetupFilesHelper<ISProductFolder>\redist\language independent\i386\SFHelper.dll
+ + + File_ + Path +
+ + + Signature_ +
+ + + Property + Value +
+ + + CLSID + Context + Component_ + ProgId_Default + Description + AppId_ + FileTypeMask + Icon_ + IconIndex + DefInprocHandler + Argument + Feature_ + Attributes +
+ + + Property + Order + Value + Text +
+ + + Signature_ + ComponentId + Type +
+ + + Component_ + ExpType +
+ + + Component + ComponentId + Directory_ + Attributes + Condition + KeyPath + ISAttributes + ISComments + ISScanAtBuildFile + ISRegFileToMergeAtBuild + ISDotNetInstallerArgsInstall + ISDotNetInstallerArgsCommit + ISDotNetInstallerArgsUninstall + ISDotNetInstallerArgsRollback + + +
SimanticsSysdyn32Files{97417204-517F-4FDB-8A72-83900DA3B204}INSTALLDIR817/LogFile=/LogFile=/LogFile=/LogFile=SimanticsSysdyn64Files{874B1E4B-DB82-4F7B-8555-6B648FDD9EFF}INSTALLDIR26417/LogFile=/LogFile=/LogFile=/LogFile=
+ + + Feature_ + Level + Condition +
+ + + Dialog_ + Control + Type + X + Y + Width + Height + Attributes + Property + Text + Control_Next + Help + ISWindowStyle + ISControlId + ISBuildSourcePath + Binary_ +
+ + + Dialog_ + Control_ + Action + Condition +
+ + + Dialog_ + Control_ + Event + Argument + Condition + Ordering + + + + +
CancelSetupYesDoActionISSetupFilesCleanup1200SetupCompleteErrorFinishDoActionISSetupFilesCleanup1200SetupCompleteSuccessOKDoActionISSetupFilesCleanup1200SetupInterruptedFinishDoActionISSetupFilesCleanup1200
+ + + Directory_ + Component_ +
+ + + Action + Type + Source + Target + ExtendedType + ISComments + + +
ISPreventDowngrade19[IS_PREVENT_DOWNGRADE_EXIT]Exits install when a newer version of this product is foundISSelfRegisterCosting1ISSELFREG.DLLISSelfRegisterCosting + ISSelfRegisterFiles3073ISSELFREG.DLLISSelfRegisterFiles + ISSelfRegisterFinalize1ISSELFREG.DLLISSelfRegisterFinalize + ISSetupFilesCleanup257ISSetupFilesHelperSFCleanupEx + ISSetupFilesExtract257ISSetupFilesHelperSFStartupEx + ISUnSelfRegisterFiles3073ISSELFREG.DLLISUnSelfRegisterFiles + ISVerifyScriptingRuntime19[STANDARD_USE_SETUPEXE]Required for installations using InstallScript.SetARPINSTALLLOCATION51ARPINSTALLLOCATION[INSTALLDIR] + SetAllUsersProfileNT51ALLUSERSPROFILE[%SystemRoot]\Profiles\All Users + setAllUsersProfile2K51ALLUSERSPROFILE[%ALLUSERSPROFILE] + setUserProfileNT51USERPROFILE[%USERPROFILE] +
+ + + Dialog + HCentering + VCentering + Width + Height + Attributes + Title + Control_First + Control_Default + Control_Cancel + ISComments + TextStyle_ + ISWindowStyle + ISResourceId +
+ + + Directory + Directory_Parent + DefaultDir + ISDescription + ISAttributes + ISFolderName +
ALLUSERSPROFILETARGETDIR.:ALLUSE~1|All Users0 + AdminToolsFolderTARGETDIR.:Admint~1|AdminTools0 + AppDataFolderTARGETDIR.:APPLIC~1|Application Data0 + CommonAppDataFolderTARGETDIR.:Common~1|CommonAppData0 + CommonFiles64FolderTARGETDIR.:Common640 + CommonFilesFolderTARGETDIR.:Common0 + DesktopFolderTARGETDIR.:Desktop3 + FavoritesFolderTARGETDIR.:FAVORI~1|Favorites0 + FontsFolderTARGETDIR.:Fonts0 + GlobalAssemblyCacheTARGETDIR.:Global~1|GlobalAssemblyCache0 + INSTALLDIRMY_PRODUCT_NAME.0 + LocalAppDataFolderTARGETDIR.:LocalA~1|LocalAppData0 + MY_PRODUCT_NAMEPrimaryVolumePathSIMANT~1|Simantics0 + MyPicturesFolderTARGETDIR.:MyPict~1|MyPictures0 + PersonalFolderTARGETDIR.:Personal0 + PrimaryVolumePathTARGETDIR.:Primar~1|PrimaryVolumePath0 + ProgramFiles64FolderTARGETDIR.:Prog64~1|Program Files 640 + ProgramFilesFolderTARGETDIR.:PROGRA~1|program files0 + ProgramMenuFolderTARGETDIR.:Programs3 + SIMANTICSPrimaryVolumePathSIMANT~1|Simantics0 + SendToFolderTARGETDIR.:SendTo3 + StartMenuFolderTARGETDIR.:STARTM~1|Start Menu3 + StartupFolderTARGETDIR.:StartUp3 + System16FolderTARGETDIR.:System0 + System64FolderTARGETDIR.:System640 + SystemFolderTARGETDIR.:System320 + TARGETDIRSourceDir0 + TempFolderTARGETDIR.:Temp0 + TemplateFolderTARGETDIR.:ShellNew0 + USERPROFILETARGETDIR.:USERPR~1|UserProfile0 + WindowsFolderTARGETDIR.:Windows0 + WindowsVolumeTARGETDIR.:WinRoot0 +
+ + + Signature_ + Parent + Path + Depth +
+ + + FileKey + Component_ + File_ + DestName + DestFolder +
+ + + Environment + Name + Value + Component_ +
+ + + Error + Message + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0##IDS_ERROR_0##1##IDS_ERROR_1##10##IDS_ERROR_8##11##IDS_ERROR_9##1101##IDS_ERROR_22##12##IDS_ERROR_10##13##IDS_ERROR_11##1301##IDS_ERROR_23##1302##IDS_ERROR_24##1303##IDS_ERROR_25##1304##IDS_ERROR_26##1305##IDS_ERROR_27##1306##IDS_ERROR_28##1307##IDS_ERROR_29##1308##IDS_ERROR_30##1309##IDS_ERROR_31##1310##IDS_ERROR_32##1311##IDS_ERROR_33##1312##IDS_ERROR_34##1313##IDS_ERROR_35##1314##IDS_ERROR_36##1315##IDS_ERROR_37##1316##IDS_ERROR_38##1317##IDS_ERROR_39##1318##IDS_ERROR_40##1319##IDS_ERROR_41##1320##IDS_ERROR_42##1321##IDS_ERROR_43##1322##IDS_ERROR_44##1323##IDS_ERROR_45##1324##IDS_ERROR_46##1325##IDS_ERROR_47##1326##IDS_ERROR_48##1327##IDS_ERROR_49##1328##IDS_ERROR_122##1329##IDS_ERROR_1329##1330##IDS_ERROR_1330##1331##IDS_ERROR_1331##1332##IDS_ERROR_1332##1333##IDS_ERROR_1333##1334##IDS_ERROR_1334##1335##IDS_ERROR_1335##1336##IDS_ERROR_1336##14##IDS_ERROR_12##1401##IDS_ERROR_50##1402##IDS_ERROR_51##1403##IDS_ERROR_52##1404##IDS_ERROR_53##1405##IDS_ERROR_54##1406##IDS_ERROR_55##1407##IDS_ERROR_56##1408##IDS_ERROR_57##1409##IDS_ERROR_58##1410##IDS_ERROR_59##15##IDS_ERROR_13##1500##IDS_ERROR_60##1501##IDS_ERROR_61##1502##IDS_ERROR_62##1503##IDS_ERROR_63##16##IDS_ERROR_14##1601##IDS_ERROR_64##1602##IDS_ERROR_65##1603##IDS_ERROR_66##1604##IDS_ERROR_67##1605##IDS_ERROR_68##1606##IDS_ERROR_69##1607 + 1608##IDS_ERROR_71##1609##IDS_ERROR_1609##1651##IDS_ERROR_1651##17##IDS_ERROR_15##1701##IDS_ERROR_72##1702##IDS_ERROR_73##1703##IDS_ERROR_74##1704##IDS_ERROR_75##1705##IDS_ERROR_76##1706##IDS_ERROR_77##1707##IDS_ERROR_78##1708##IDS_ERROR_79##1709##IDS_ERROR_80##1710##IDS_ERROR_81##1711##IDS_ERROR_82##1712##IDS_ERROR_83##1713##IDS_ERROR_123##1714##IDS_ERROR_124##1715##IDS_ERROR_1715##1716##IDS_ERROR_1716##1717##IDS_ERROR_1717##1718##IDS_ERROR_1718##1719##IDS_ERROR_1719##1720##IDS_ERROR_1720##1721##IDS_ERROR_1721##1722##IDS_ERROR_1722##1723##IDS_ERROR_1723##1724##IDS_ERROR_1724##1725##IDS_ERROR_1725##1726##IDS_ERROR_1726##1727##IDS_ERROR_1727##1728##IDS_ERROR_1728##1729##IDS_ERROR_1729##1730##IDS_ERROR_1730##1731##IDS_ERROR_1731##1732##IDS_ERROR_1732##18##IDS_ERROR_16##1801##IDS_ERROR_84##1802##IDS_ERROR_85##1803##IDS_ERROR_86##1804##IDS_ERROR_87##1805##IDS_ERROR_88##1806##IDS_ERROR_89##1807##IDS_ERROR_90##19##IDS_ERROR_17##1901##IDS_ERROR_91##1902##IDS_ERROR_92##1903##IDS_ERROR_93##1904##IDS_ERROR_94##1905##IDS_ERROR_95##1906##IDS_ERROR_96##1907##IDS_ERROR_97##1908##IDS_ERROR_98##1909##IDS_ERROR_99##1910##IDS_ERROR_100##1911##IDS_ERROR_101##1912##IDS_ERROR_102##1913##IDS_ERROR_103##1914##IDS_ERROR_104##1915##IDS_ERROR_105##1916##IDS_ERROR_106##1917##IDS_ERROR_107##1918##IDS_ERROR_108##1919##IDS_ERROR_109##1920##IDS_ERROR_110##1921##IDS_ERROR_111##1922##IDS_ERROR_112##1923##IDS_ERROR_113##1924##IDS_ERROR_114##1925##IDS_ERROR_115##1926##IDS_ERROR_116##1927##IDS_ERROR_117##1928##IDS_ERROR_118##1929##IDS_ERROR_119##1930##IDS_ERROR_125##1931##IDS_ERROR_126##1932##IDS_ERROR_127##1933##IDS_ERROR_128##1934##IDS_ERROR_129##1935##IDS_ERROR_1935##1936##IDS_ERROR_1936##1937##IDS_ERROR_1937##1938##IDS_ERROR_1938##2##IDS_ERROR_2##20##IDS_ERROR_18##21##IDS_ERROR_19##2101##IDS_ERROR_2101##2102##IDS_ERROR_2102##2103##IDS_ERROR_2103##2104##IDS_ERROR_2104##2105##IDS_ERROR_2105##2106##IDS_ERROR_2106##2107##IDS_ERROR_2107##2108##IDS_ERROR_2108##2109##IDS_ERROR_2109##2110##IDS_ERROR_2110##2111##IDS_ERROR_2111##2112##IDS_ERROR_2112##2113##IDS_ERROR_2113##22##IDS_ERROR_120##2200##IDS_ERROR_2200##2201##IDS_ERROR_2201##2202##IDS_ERROR_2202##2203##IDS_ERROR_2203##2204##IDS_ERROR_2204##2205##IDS_ERROR_2205##2206##IDS_ERROR_2206##2207##IDS_ERROR_2207##2208##IDS_ERROR_2208##2209##IDS_ERROR_2209##2210##IDS_ERROR_2210##2211##IDS_ERROR_2211##2212##IDS_ERROR_2212##2213##IDS_ERROR_2213##2214##IDS_ERROR_2214##2215##IDS_ERROR_2215##2216##IDS_ERROR_2216##2217##IDS_ERROR_2217##2218##IDS_ERROR_2218##2219##IDS_ERROR_2219##2220##IDS_ERROR_2220##2221##IDS_ERROR_2221##2222##IDS_ERROR_2222##2223##IDS_ERROR_2223##2224##IDS_ERROR_2224##2225##IDS_ERROR_2225##2226##IDS_ERROR_2226##2227##IDS_ERROR_2227##2228##IDS_ERROR_2228##2229##IDS_ERROR_2229##2230##IDS_ERROR_2230##2231##IDS_ERROR_2231##2232##IDS_ERROR_2232##2233##IDS_ERROR_2233##2234##IDS_ERROR_2234##2235##IDS_ERROR_2235##2236##IDS_ERROR_2236##2237##IDS_ERROR_2237##2238##IDS_ERROR_2238##2239##IDS_ERROR_2239##2240##IDS_ERROR_2240##2241##IDS_ERROR_2241##2242##IDS_ERROR_2242##2243##IDS_ERROR_2243##2244##IDS_ERROR_2244##2245##IDS_ERROR_2245##2246##IDS_ERROR_2246##2247##IDS_ERROR_2247##2248##IDS_ERROR_2248##2249##IDS_ERROR_2249##2250##IDS_ERROR_2250##2251##IDS_ERROR_2251##2252##IDS_ERROR_2252##2253##IDS_ERROR_2253##2254##IDS_ERROR_2254##2255##IDS_ERROR_2255##2256##IDS_ERROR_2256##2257##IDS_ERROR_2257##2258##IDS_ERROR_2258##2259##IDS_ERROR_2259##2260##IDS_ERROR_2260##2261##IDS_ERROR_2261##2262##IDS_ERROR_2262##2263##IDS_ERROR_2263##2264##IDS_ERROR_2264##2265##IDS_ERROR_2265##2266##IDS_ERROR_2266##2267##IDS_ERROR_2267##2268##IDS_ERROR_2268##2269##IDS_ERROR_2269##2270##IDS_ERROR_2270##2271##IDS_ERROR_2271##2272##IDS_ERROR_2272##2273##IDS_ERROR_2273##2274##IDS_ERROR_2274##2275##IDS_ERROR_2275##2276##IDS_ERROR_2276##2277##IDS_ERROR_2277##2278##IDS_ERROR_2278##2279##IDS_ERROR_2279##2280##IDS_ERROR_2280##2281##IDS_ERROR_2281##2282##IDS_ERROR_2282##23##IDS_ERROR_121##2302##IDS_ERROR_2302##2303##IDS_ERROR_2303##2304##IDS_ERROR_2304##2305##IDS_ERROR_2305##2306##IDS_ERROR_2306##2307##IDS_ERROR_2307##2308##IDS_ERROR_2308##2309##IDS_ERROR_2309##2310##IDS_ERROR_2310##2315##IDS_ERROR_2315##2318##IDS_ERROR_2318##2319##IDS_ERROR_2319##2320##IDS_ERROR_2320##2321##IDS_ERROR_2321##2322##IDS_ERROR_2322##2323##IDS_ERROR_2323##2324##IDS_ERROR_2324##2325##IDS_ERROR_2325##2326##IDS_ERROR_2326##2327##IDS_ERROR_2327##2328##IDS_ERROR_2328##2329##IDS_ERROR_2329##2330##IDS_ERROR_2330##2331##IDS_ERROR_2331##2332##IDS_ERROR_2332##2333##IDS_ERROR_2333##2334##IDS_ERROR_2334##2335##IDS_ERROR_2335##2336##IDS_ERROR_2336##2337##IDS_ERROR_2337##2338##IDS_ERROR_2338##2339##IDS_ERROR_2339##2340##IDS_ERROR_2340##2341##IDS_ERROR_2341##2342##IDS_ERROR_2342##2343##IDS_ERROR_2343##2344##IDS_ERROR_2344##2345##IDS_ERROR_2345##2347##IDS_ERROR_2347##2348##IDS_ERROR_2348##2349##IDS_ERROR_2349##2350##IDS_ERROR_2350##2351##IDS_ERROR_2351##2352##IDS_ERROR_2352##2353##IDS_ERROR_2353##2354##IDS_ERROR_2354##2355##IDS_ERROR_2355##2356##IDS_ERROR_2356##2357##IDS_ERROR_2357##2358##IDS_ERROR_2358##2359##IDS_ERROR_2359##2360##IDS_ERROR_2360##2361##IDS_ERROR_2361##2362##IDS_ERROR_2362##2363##IDS_ERROR_2363##2364##IDS_ERROR_2364##2365##IDS_ERROR_2365##2366##IDS_ERROR_2366##2367##IDS_ERROR_2367##2368##IDS_ERROR_2368##2370##IDS_ERROR_2370##2371##IDS_ERROR_2371##2372##IDS_ERROR_2372##2373##IDS_ERROR_2373##2374##IDS_ERROR_2374##2375##IDS_ERROR_2375##2376##IDS_ERROR_2376##2379##IDS_ERROR_2379##2380##IDS_ERROR_2380##2381##IDS_ERROR_2381##2382##IDS_ERROR_2382##2401##IDS_ERROR_2401##2402##IDS_ERROR_2402##2501##IDS_ERROR_2501##2502##IDS_ERROR_2502##2503##IDS_ERROR_2503##2601##IDS_ERROR_2601##2602##IDS_ERROR_2602##2603##IDS_ERROR_2603##2604##IDS_ERROR_2604##2605##IDS_ERROR_2605##2606##IDS_ERROR_2606##2607##IDS_ERROR_2607##2608##IDS_ERROR_2608##2609##IDS_ERROR_2609##2611##IDS_ERROR_2611##2612##IDS_ERROR_2612##2613##IDS_ERROR_2613##2614##IDS_ERROR_2614##2615##IDS_ERROR_2615##2616##IDS_ERROR_2616##2617##IDS_ERROR_2617##2618##IDS_ERROR_2618##2619##IDS_ERROR_2619##2620##IDS_ERROR_2620##2621##IDS_ERROR_2621##2701##IDS_ERROR_2701##2702##IDS_ERROR_2702##2703##IDS_ERROR_2703##2704##IDS_ERROR_2704##2705##IDS_ERROR_2705##2706##IDS_ERROR_2706##2707##IDS_ERROR_2707##2708##IDS_ERROR_2708##2709##IDS_ERROR_2709##2710##IDS_ERROR_2710##2711##IDS_ERROR_2711##2712##IDS_ERROR_2712##2713##IDS_ERROR_2713##2714##IDS_ERROR_2714##2715##IDS_ERROR_2715##2716##IDS_ERROR_2716##2717##IDS_ERROR_2717##2718##IDS_ERROR_2718##2719##IDS_ERROR_2719##2720##IDS_ERROR_2720##2721##IDS_ERROR_2721##2722##IDS_ERROR_2722##2723##IDS_ERROR_2723##2724##IDS_ERROR_2724##2725##IDS_ERROR_2725##2726##IDS_ERROR_2726##2727##IDS_ERROR_2727##2728##IDS_ERROR_2728##2729##IDS_ERROR_2729##2730##IDS_ERROR_2730##2731##IDS_ERROR_2731##2732##IDS_ERROR_2732##2733##IDS_ERROR_2733##2734##IDS_ERROR_2734##2735##IDS_ERROR_2735##2736##IDS_ERROR_2736##2737##IDS_ERROR_2737##2738##IDS_ERROR_2738##2739##IDS_ERROR_2739##2740##IDS_ERROR_2740##2741##IDS_ERROR_2741##2742##IDS_ERROR_2742##2743##IDS_ERROR_2743##2744##IDS_ERROR_2744##2745##IDS_ERROR_2745##2746##IDS_ERROR_2746##2747##IDS_ERROR_2747##2748##IDS_ERROR_2748##2749##IDS_ERROR_2749##2750##IDS_ERROR_2750##27500##IDS_ERROR_130##27501##IDS_ERROR_131##27502##IDS_ERROR_27502##27503##IDS_ERROR_27503##27504##IDS_ERROR_27504##27505##IDS_ERROR_27505##27506##IDS_ERROR_27506##27507##IDS_ERROR_27507##27508##IDS_ERROR_27508##27509##IDS_ERROR_27509##2751##IDS_ERROR_2751##27510##IDS_ERROR_27510##27511##IDS_ERROR_27511##27512##IDS_ERROR_27512##27513##IDS_ERROR_27513##27514##IDS_ERROR_27514##27515##IDS_ERROR_27515##27516##IDS_ERROR_27516##27517##IDS_ERROR_27517##27518##IDS_ERROR_27518##27519##IDS_ERROR_27519##2752##IDS_ERROR_2752##27520##IDS_ERROR_27520##27521##IDS_ERROR_27521##27522##IDS_ERROR_27522##27523##IDS_ERROR_27523##27524##IDS_ERROR_27524##27525##IDS_ERROR_27525##27526##IDS_ERROR_27526##27527##IDS_ERROR_27527##27528##IDS_ERROR_27528##27529##IDS_ERROR_27529##2753##IDS_ERROR_2753##27530##IDS_ERROR_27530##27531##IDS_ERROR_27531##27532##IDS_ERROR_27532##27533##IDS_ERROR_27533##27534##IDS_ERROR_27534##27535##IDS_ERROR_27535##27536##IDS_ERROR_27536##27537##IDS_ERROR_27537##27538##IDS_ERROR_27538##27539##IDS_ERROR_27539##2754##IDS_ERROR_2754##27540##IDS_ERROR_27540##27541##IDS_ERROR_27541##27542##IDS_ERROR_27542##27543##IDS_ERROR_27543##27544##IDS_ERROR_27544##27545##IDS_ERROR_27545##27546##IDS_ERROR_27546##27547##IDS_ERROR_27547##27548##IDS_ERROR_27548##27549##IDS_ERROR_27549##2755##IDS_ERROR_2755##27550##IDS_ERROR_27550##27551##IDS_ERROR_27551##27552##IDS_ERROR_27552##27553##IDS_ERROR_27553##27554##IDS_ERROR_27554##27555##IDS_ERROR_27555##2756##IDS_ERROR_2756##2757##IDS_ERROR_2757##2758##IDS_ERROR_2758##2759##IDS_ERROR_2759##2760##IDS_ERROR_2760##2761##IDS_ERROR_2761##2762##IDS_ERROR_2762##2763##IDS_ERROR_2763##2765##IDS_ERROR_2765##2766##IDS_ERROR_2766##2767##IDS_ERROR_2767##2768##IDS_ERROR_2768##2769##IDS_ERROR_2769##2770##IDS_ERROR_2770##2771##IDS_ERROR_2771##2772##IDS_ERROR_2772##2801##IDS_ERROR_2801##2802##IDS_ERROR_2802##2803##IDS_ERROR_2803##2804##IDS_ERROR_2804##2806##IDS_ERROR_2806##2807##IDS_ERROR_2807##2808##IDS_ERROR_2808##2809##IDS_ERROR_2809##2810##IDS_ERROR_2810##2811##IDS_ERROR_2811##2812##IDS_ERROR_2812##2813##IDS_ERROR_2813##2814##IDS_ERROR_2814##2815##IDS_ERROR_2815##2816##IDS_ERROR_2816##2817##IDS_ERROR_2817##2818##IDS_ERROR_2818##2819##IDS_ERROR_2819##2820##IDS_ERROR_2820##2821##IDS_ERROR_2821##2822##IDS_ERROR_2822##2823##IDS_ERROR_2823##2824##IDS_ERROR_2824##2825##IDS_ERROR_2825##2826##IDS_ERROR_2826##2827##IDS_ERROR_2827##2828##IDS_ERROR_2828##2829##IDS_ERROR_2829##2830##IDS_ERROR_2830##2831##IDS_ERROR_2831##2832##IDS_ERROR_2832##2833##IDS_ERROR_2833##2834##IDS_ERROR_2834##2835##IDS_ERROR_2835##2836##IDS_ERROR_2836##2837##IDS_ERROR_2837##2838##IDS_ERROR_2838##2839##IDS_ERROR_2839##2840##IDS_ERROR_2840##2841##IDS_ERROR_2841##2842##IDS_ERROR_2842##2843##IDS_ERROR_2843##2844##IDS_ERROR_2844##2845##IDS_ERROR_2845##2846##IDS_ERROR_2846##2847##IDS_ERROR_2847##2848##IDS_ERROR_2848##2849##IDS_ERROR_2849##2850##IDS_ERROR_2850##2851##IDS_ERROR_2851##2852##IDS_ERROR_2852##2853##IDS_ERROR_2853##2854##IDS_ERROR_2854##2855##IDS_ERROR_2855##2856##IDS_ERROR_2856##2857##IDS_ERROR_2857##2858##IDS_ERROR_2858##2859##IDS_ERROR_2859##2860##IDS_ERROR_2860##2861##IDS_ERROR_2861##2862##IDS_ERROR_2862##2863##IDS_ERROR_2863##2864##IDS_ERROR_2864##2865##IDS_ERROR_2865##2866##IDS_ERROR_2866##2867##IDS_ERROR_2867##2868##IDS_ERROR_2868##2869##IDS_ERROR_2869##2870##IDS_ERROR_2870##2871##IDS_ERROR_2871##2872##IDS_ERROR_2872##2873##IDS_ERROR_2873##2874##IDS_ERROR_2874##2875##IDS_ERROR_2875##2876##IDS_ERROR_2876##2877##IDS_ERROR_2877##2878##IDS_ERROR_2878##2879##IDS_ERROR_2879##2880##IDS_ERROR_2880##2881##IDS_ERROR_2881##2882##IDS_ERROR_2882##2883##IDS_ERROR_2883##2884##IDS_ERROR_2884##2885##IDS_ERROR_2885##2886##IDS_ERROR_2886##2887##IDS_ERROR_2887##2888##IDS_ERROR_2888##2889##IDS_ERROR_2889##2890##IDS_ERROR_2890##2891##IDS_ERROR_2891##2892##IDS_ERROR_2892##2893##IDS_ERROR_2893##2894##IDS_ERROR_2894##2895##IDS_ERROR_2895##2896##IDS_ERROR_2896##2897##IDS_ERROR_2897##2898##IDS_ERROR_2898##2899##IDS_ERROR_2899##2901##IDS_ERROR_2901##2902##IDS_ERROR_2902##2903##IDS_ERROR_2903##2904##IDS_ERROR_2904##2905##IDS_ERROR_2905##2906##IDS_ERROR_2906##2907##IDS_ERROR_2907##2908##IDS_ERROR_2908##2909##IDS_ERROR_2909##2910##IDS_ERROR_2910##2911##IDS_ERROR_2911##2912##IDS_ERROR_2912##2919##IDS_ERROR_2919##2920##IDS_ERROR_2920##2924##IDS_ERROR_2924##2927##IDS_ERROR_2927##2928##IDS_ERROR_2928##2929##IDS_ERROR_2929##2932##IDS_ERROR_2932##2933##IDS_ERROR_2933##2934##IDS_ERROR_2934##2935##IDS_ERROR_2935##2936##IDS_ERROR_2936##2937##IDS_ERROR_2937##2938##IDS_ERROR_2938##2939##IDS_ERROR_2939##2940##IDS_ERROR_2940##2941##IDS_ERROR_2941##2942##IDS_ERROR_2942##2943##IDS_ERROR_2943##2944##IDS_ERROR_2944##2945##IDS_ERROR_2945##3001##IDS_ERROR_3001##3002##IDS_ERROR_3002##32##IDS_ERROR_20##33##IDS_ERROR_21##4##IDS_ERROR_3##5##IDS_ERROR_4##7##IDS_ERROR_5##8##IDS_ERROR_6##9##IDS_ERROR_7##
+ + + Dialog_ + Control_ + Event + Attribute +
+ + + Extension + Component_ + ProgId_ + MIME_ + Feature_ +
+ + + Feature + Feature_Parent + Title + Description + Display + Level + Directory_ + Attributes + ISReleaseFlags + ISComments + ISFeatureCabName + ISProFeatureName +
SimanticsSysdyn32##ID_STRING7####ID_STRING8##21INSTALLDIR0x32sysdyn + SimanticsSysdyn64##ID_STRING9####ID_STRING10##41INSTALLDIR0x64sysdyn +
+ + + Feature_ + Component_ + + +
SimanticsSysdyn32SimanticsSysdyn32FilesSimanticsSysdyn64SimanticsSysdyn64Files
+ + + File + Component_ + FileName + FileSize + Version + Language + Attributes + Sequence + ISBuildSourcePath + ISAttributes + ISComponentSubFolder_ +
+ + + File_ + SFPCatalog_ +
+ + + File_ + FontTitle +
+ + + Alias + Identifier + Table +
+ + + Tag + Data + + + +
BiildCDROMEnabled + BiildInternetEnabled + BiildSingleExeEnabledYesBiildSingleMSIEnabled + PROJECT_ASSISTANT_DEFAULT_FEATUREDefaultFeaturePROJECT_ASSISTANT_FEATURESSelectable
+ + + AppKey + AppName + CompanyName + DefDir + IconPath + IconIndex + DeviceFile + DesktopTargetDir + Description + DeleteMedia + InstallNetCF + InstallSQLServer + InstallSQLClient + InstallSQLDev + PreXML + PostXML + NoUninstall + SPCFile + PVKFile + Attributes + RawDeviceFile + Component_ + InstallNetCF2 + InstallSQLServer2 + InstallSQLClient2 + InstallSQLDev2 + SPCPwd +
+ + + AppKey + DirKey + DirParent + DirValue +
+ + + AppKey + FileKey + Name + Destination + Source + Processor + Platform + CopyOption + FileOption + AdvancedOptions +
+ + + AppKey + ExtKey + FileKey + Description + Extension + IconIndex +
+ + + CEInstallKey + CEAppName + CEDesktopDir + CEIniFileKey + CECabs + CEIcoFile + DeleteMedia + Component_ +
+ + + AppKey + FileKey + BuildSourcePath +
+ + + AppKey + Name + Platforms +
+ + + AppKey + RegKey + Root + Key + Name + Value + Processor + Platform + Overwrite +
+ + + AppKey + SetupFileKey + Name + Source + Processor + Platform +
+ + + AppKey + ShtCutKey + DisplayName + Destination + Target + Platform + StartScreenIcon +
+ + + Package + SourcePath + ProductCode + Order + Options + InstallCondition + RemoveCondition + InstallProperties + RemoveProperties + ISReleaseFlags + DisplayName +
+ + + Package_ + File + FilePath + Options + Data + ISBuildSourcePath +
+ + + Action_ + Name + Value +
+ + + ISComCatalogObject_ + ItemName + ItemValue +
+ + + ISComCatalogCollection + ISComCatalogObject_ + CollectionName +
+ + + ISComCatalogCollection_ + ISComCatalogObject_ +
+ + + ISComCatalogObject + DisplayName +
+ + + ISComCatalogObject_ + ComputerName + Component_ + ISAttributes + DepFiles +
+ + + ISComPlusApplicationDLL + ISComPlusApplication_ + ISComCatalogObject_ + CLSID + ProgId + DLL + AlterDLL +
+ + + ISComPlusProxy + ISComPlusApplication_ + Component_ + ISAttributes + DepFiles +
+ + + ISComPlusApplication_ + File_ + ISPath +
+ + + File_ + ISComPlusApplicationDLL_ +
+ + + ISComPlusApplication_ + File_ + ISPath +
+ + + File_ + ISComPlusApplicationDLL_ +
+ + + Component_ + OS + Language + FilterProperty + Platforms + FTPLocation + HTTPLocation + Miscellaneous +
SimanticsSysdyn32Files_F8E0099F_A86C_4346_9244_C6419CC06362_FILTER + SimanticsSysdyn64Files_207D72CB_D769_481A_9977_0120195FAB31_FILTER +
+ + + Action_ + Description + FileType + ISCAReferenceFilePath +
+ + + EntryPoint + Type + Source + Target +
+ + + ISDRMFile + File_ + ISDRMLicense_ + Shell +
+ + + ISDRMFile_ + Property + Value +
+ + + ISDRMLicense + Description + ProjectVersion + Attributes + LicenseNumber + RequestCode + ResponseCode +
+ + + ISDependency + Exclude +
+ + + ISDisk1File + ISBuildSourcePath + Disk +
+ + + Component_ + SourceFolder + IncludeFlags + IncludeFiles + ExcludeFiles + ISAttributes + + +
SimanticsSysdyn32Files<PATH_TO_SIMANTICS-SYSDY_FI>4Launcher.exe10SimanticsSysdyn64Files<SYSDYN>\SimanticsSysdyn64410
+ + + Feature_ + Installing + Installed + Uninstalling + Uninstalled + FTPLocation + HTTPLocation + Miscellaneous + StatusText + ISAttributes + Password + CDRomFolder + Moniker +
SimanticsSysdyn32SysdynFeature_Installed + SimanticsSysdyn64SysdynFeature_Installed +
+ + + Feature_ + ModuleID + Language +
+ + + Feature_ + ISMergeModule_ + Language_ +
+ + + Feature_ + ISSetupPrerequisites_ +
+ + + File_ + Manifest_ +
+ + + ISIISItem + ISIISItem_Parent + DisplayName + Type + Component_ +
+ + + ISIISProperty + ISIISItem_ + Schema + FriendlyName + MetaDataProp + MetaDataType + MetaDataUserType + MetaDataAttributes + MetaDataValue + Order + ISAttributes +
+ + + EntryPoint + Type + Source + Target +
+ + + ISLanguage + Included + +
10331
+ + + ISLinkerLibrary + Library + Order + + +
isrt.oblisrt.obl2iswi.obliswi.obl1
+ + + Dialog_ + Control_ + ISLanguage_ + Attributes + X + Y + Width + Height + Binary_ + ISBuildSourcePath +
+ + + Dialog_ + ISLanguage_ + Attributes + TextStyle_ + Width + Height +
+ + + Property + Order + ISLanguage_ + X + Y + Width + Height +
+ + + LockObject + Table + Domain + User + Permission + Attributes +
+ + + DiskId + ISProductConfiguration_ + ISRelease_ + LastSequence + DiskPrompt + Cabinet + VolumeLabel + Source +
+ + + ISLogicalDisk_ + ISProductConfiguration_ + ISRelease_ + Feature_ + Sequence + ISAttributes +
+ + + ISMergeModule + Language + Name + Destination + ISAttributes +
+ + + ISMergeModule_ + Language_ + ModuleConfiguration_ + Value + Format + Type + ContextData + DefaultValue + Attributes + DisplayName + Description + HelpLocation + HelpKeyword +
+ + + ObjectName + Language +
+ + + ObjectName + Property + Value + IncludeInBuild +
+ + + PalmApp + Component +
+ + + PalmApp + FileKey + Destination +
+ + + PatchConfiguration_ + UpgradedImage_ +
+ + + Name + CanPCDiffer + CanPVDiffer + IncludeWholeFiles + LeaveDecompressed + OptimizeForSize + EnablePatchCache + PatchCacheDir + Flags + PatchGuidsToReplace + TargetProductCodes + PatchGuid + OutputPath + MinMsiVersion + Attributes +
+ + + ISPatchConfiguration_ + Property + Value +
+ + + Name + ISUpgradedImage_ + FileKey + FilePath +
+ + + UpgradedImage + FileKey + Component +
+ + + ISPathVariable + Value + TestValue + Type + + + + + + + + + + + + + +
CommonFilesFolder1ISPROJECTDIR1ISProductFolder1ISProjectDataFolder1ISProjectFolder1PATH_TO_BIN.NT_FILES<ROOT>\apros\Apros5\bin.nt2PATH_TO_GRAPHICS_FILES<ROOT>\extra2PATH_TO_SIMANTICS-SYSDY_FI<SYSDYN>\SimanticsSysdyn322ProgramFilesFolder1ROOT<ISProjectFolder>\..\..2SYSDYN<ROOT>\sysdyn2SystemFolder1WindowsFolder1
+ + + ISProductConfiguration + ProductConfigurationFlags + GeneratePackageCode + + +
S3x32sysdyn, sysdyn1S6x64sysdyn, sysdyn1
+ + + ISProductConfiguration_ + InstanceId + Property + Value +
+ + + ISProductConfiguration_ + Property + Value + + + + + + + + + + + + + + +
S3IncludeActionHelp1S3PreProcessorDefinesx32,sysdynS3ProductCode{C0690109-F799-4836-A38F-F77C55C435F8}S3ProductNameSimantics 1.7.0 Sysdyn 32S3SetupFileNameSimantics 1.7.0 Sysdyn 32 setupS3TemplateSummaryIntel;1033S3UpgradeCode{D85384A8-F5DB-454C-94F6-43C20F559884}S6IncludeActionHelp1S6PreProcessorDefinesx64, sysdynS6ProductCode{90CA3AEF-AEB9-48C7-B64D-6492910581ED}S6ProductNameSimantics 1.6.0 Sysdyn 64S6SetupFileNameSimantics 1.6.0 Sysdyn 64 setupS6TemplateSummaryx64;1033S6UpgradeCode{6B14D4A3-D430-4513-A26E-78E15281ABFE}
+ + + ISRelease + ISProductConfiguration_ + BuildLocation + PackageName + Type + SupportedLanguagesUI + MsiSourceType + ReleaseType + Platforms + SupportedLanguagesData + DefaultLanguage + SupportedOSs + DiskSize + DiskSizeUnit + DiskClusterSize + ReleaseFlags + DiskSpanning + SynchMsi + MediaLocation + URLLocation + DigitalURL + DigitalPVK + DigitalSPC + Password + VersionCopyright + Attributes + CDBrowser + DotNetBuildConfiguration + MsiCommandLine + ISSetupPrerequisiteLocation +
S3S3C:\SPackageName1103321Intel103300000MediaLocationhttp://www.vtt.fi<PATH_TO_GRAPHICS_FILES>\vtt_is.pfx8464399 + S6S6C:\SPackageName1103321Intel103300000MediaLocationhttp://www.vtt.fi<PATH_TO_GRAPHICS_FILES>\vtt_is.pfx8464399 +
+ + + ISRelease_ + ISProductConfiguration_ + WebType + WebURL + WebCabSize + OneClickCabName + OneClickHtmlName + WebLocalCachePath + EngineLocation + Win9xMsiUrl + WinNTMsiUrl + ISEngineLocation + ISEngineURL + OneClickTargetBrowser + DigitalCertificateIdNS + DigitalCertificateDBaseNS + DigitalCertificatePasswordNS + DotNetRedistLocation + DotNetRedistURL + DotNetVersion + DotNetBaseLanguage + DotNetLangaugePacks + DotNetFxCmdLine + DotNetLangPackCmdLine + JSharpCmdLine + Attributes + JSharpRedistLocation + MsiEngineVersion + WinMsi30Url + CertPassword + + +
S3S30http://0installinstall[LocalAppDataFolder]Downloaded Installations1http://www.installengine.com/Msiengine20http://www.installengine.com/Msiengine20http://www.installengine.com/cert05/isengine3http://www.installengine.com/cert05/dotnetfx01033104034http://www.installengine.com/Msiengine30ECBEB5CES6S60http://0installinstall[LocalAppDataFolder]Downloaded Installations1http://www.installengine.com/Msiengine20http://www.installengine.com/Msiengine20http://www.installengine.com/cert05/isengine3http://www.installengine.com/cert05/dotnetfx01033104034http://www.installengine.com/Msiengine30ECBEB5CE
+ + + ISRelease_ + ISProductConfiguration_ + Name + Value + + +
S3S3SetupIcon<PATH_TO_SIMANTICS-SYSDY_FI>\puzzle_green.ico,0S6S6SetupIcon<PATH_TO_SIMANTICS-SYSDY_FI>\puzzle_green.ico,0
+ + + ISRelease_ + ISProductConfiguration_ + Repository + DisplayName + Publisher + Description + ISAttributes +
+ + + RequiringFeature + RequiredFeature +
+ + + ISSQLConnection + Server + Database + UserName + Password + Authentication + Attributes + Order + Comments + CmdTimeout + BatchSeparator + ScriptVersion_Table + ScriptVersion_Column +
+ + + ISSQLConnectionDBServer + ISSQLConnection_ + ISSQLDBMetaData_ + Order +
+ + + ISSQLConnection_ + ISSQLScriptFile_ + Order +
+ + + ISSQLDBMetaData + DisplayName + AdoDriverName + AdoCxnDriver + AdoCxnServer + AdoCxnDatabase + AdoCxnUserID + AdoCxnPassword + AdoCxnWindowsSecurity + AdoCxnNetLibrary + TestDatabaseCmd + TestTableCmd + VersionInfoCmd + VersionBeginToken + VersionEndToken + LocalInstanceNames + CreateDbCmd + SwitchDbCmd + ISAttributes + TestTableCmd2 + WinAuthentUserId + DsnODBCName + AdoCxnPort + AdoCxnAdditional + QueryDatabasesCmd + CreateTableCmd + InsertRecordCmd + SelectTableCmd + ScriptVersion_Table + ScriptVersion_Column + ScriptVersion_ColumnType +
+ + + ISSQLRequirement + ISSQLConnection_ + MajorVersion + ServicePackLevel + Attributes + ISSQLConnectionDBServer_ +
+ + + ErrNumber + ISSQLScriptFile_ + ErrHandling + Message + Attributes +
+ + + ISSQLScriptFile + Component_ + Scheduling + InstallText + UninstallText + ISBuildSourcePath + Comments + ErrorHandling + Attributes + Version + Condition +
+ + + ISSQLScriptFile_ + Server + Database + UserName + Password + Authentication + IncludeTables + ExcludeTables + Attributes +
+ + + ISSQLScriptReplace + ISSQLScriptFile_ + Search + Replace + Attributes +
+ + + ISScriptFile + + + +
<ISProjectDataFolder>\Script Files\FeatureEvents.rul<ISProjectDataFolder>\Script Files\Setup.Rul<ISProjectDataFolder>\Script Files\my.rul
+ + + ISSearchReplace + ISSearchReplaceSet_ + Search + Replace + Attributes + Order +
+ + + ISSearchReplaceSet + Component_ + Directory_ + IncludeFiles + ExcludeFiles + Attributes + Order + CodePage +
+ + + FileKey + Cost + Order + CmdLine +
+ + + ISSetupFile + FileName + Stream + Language + Splash + Path + + +
SetupFile1bbrd01.bmp00<SYSDYN>\extra\bbrd01.bmpSetupFile2splash.bmp01<SYSDYN>\extra\splash.bmp
+ + + ISSetupPrerequisites + ISBuildSourcePath + Order + ISSetupLocation + ISReleaseFlags +
+ + + ISSetupType + Description + Display_Name + Display + Comments +
Complete##IDPROP_SETUPTYPE_COMPLETE_DESC####IDPROP_SETUPTYPE_COMPLETE##1 + Custom##IDPROP_SETUPTYPE_CUSTOM_DESC_PRO####IDPROP_SETUPTYPE_CUSTOM##2 +
+ + + ISSetupType_ + Feature_ + + + + +
CompleteSimanticsSysdyn32CompleteSimanticsSysdyn64CustomSimanticsSysdyn32CustomSimanticsSysdyn64
+ + + Name + ISBuildSourcePath +
+ + + ISString + ISLanguage_ + Value + Encoded + Comment + TimeStamp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
COMPANY_NAME1033Simantics Organization0723525133DN_AlwaysInstall1033Always Install0337541408IDPROP_EXPRESS_LAUNCH_CONDITION_COLOR1033The color settings of your system are not adequate for running [ProductName].0337541408IDPROP_EXPRESS_LAUNCH_CONDITION_OS1033The operating system is not adequate for running [ProductName].0337541408IDPROP_EXPRESS_LAUNCH_CONDITION_PROCESSOR1033The processor is not adequate for running [ProductName].0337541408IDPROP_EXPRESS_LAUNCH_CONDITION_RAM1033The amount of RAM is not adequate for running [ProductName].0337541408IDPROP_EXPRESS_LAUNCH_CONDITION_SCREEN1033The screen resolution is not adequate for running [ProductName].0337541408IDPROP_SETUPTYPE_COMPACT1033Compact0337541408IDPROP_SETUPTYPE_COMPACT_DESC1033Compact Description0337541408IDPROP_SETUPTYPE_COMPLETE1033Complete0337541408IDPROP_SETUPTYPE_COMPLETE_DESC1033Complete0337541408IDPROP_SETUPTYPE_CUSTOM1033Custom0337541408IDPROP_SETUPTYPE_CUSTOM_DESC1033Custom Description0337541408IDPROP_SETUPTYPE_CUSTOM_DESC_PRO1033Custom0337541408IDPROP_SETUPTYPE_TYPICAL1033Typical0337541408IDPROP_SETUPTYPE_TYPICAL_DESC1033Typical Description0337541408IDS_ACTIONTEXT_11033[1]0337541408IDS_ACTIONTEXT_1b1033[1]0337541408IDS_ACTIONTEXT_1c1033[1]0337541408IDS_ACTIONTEXT_1d1033[1]0337541408IDS_ACTIONTEXT_Advertising1033Advertising application0337541408IDS_ACTIONTEXT_AllocatingRegistry1033Allocating registry space0337541408IDS_ACTIONTEXT_AppCommandLine1033Application: [1], Command line: [2]0337541408IDS_ACTIONTEXT_AppId1033AppId: [1]{{, AppType: [2]}}0337541408IDS_ACTIONTEXT_AppIdAppTypeRSN1033AppId: [1]{{, AppType: [2], Users: [3], RSN: [4]}}0337541408IDS_ACTIONTEXT_Application1033Application: [1]0337541408IDS_ACTIONTEXT_BindingExes1033Binding executables0337541408IDS_ACTIONTEXT_ClassId1033Class ID: [1]0337541408IDS_ACTIONTEXT_ClsID1033Class ID: [1]0337541408IDS_ACTIONTEXT_ComponentIDQualifier1033Component ID: [1], Qualifier: [2]0337541408IDS_ACTIONTEXT_ComponentIdQualifier21033Component ID: [1], Qualifier: [2]0337541408IDS_ACTIONTEXT_ComputingSpace1033Computing space requirements0337541408IDS_ACTIONTEXT_ComputingSpace21033Computing space requirements0337541408IDS_ACTIONTEXT_ComputingSpace31033Computing space requirements0337541408IDS_ACTIONTEXT_ContentTypeExtension1033MIME Content Type: [1], Extension: [2]0337541408IDS_ACTIONTEXT_ContentTypeExtension21033MIME Content Type: [1], Extension: [2]0337541408IDS_ACTIONTEXT_CopyingNetworkFiles1033Copying files to the network0337541408IDS_ACTIONTEXT_CopyingNewFiles1033Copying new files0337541408IDS_ACTIONTEXT_CreatingDuplicate1033Creating duplicate files0337541408IDS_ACTIONTEXT_CreatingFolders1033Creating folders0337541408IDS_ACTIONTEXT_CreatingIISRoots1033Creating IIS Virtual Roots...0337541408IDS_ACTIONTEXT_CreatingShortcuts1033Creating shortcuts0337541408IDS_ACTIONTEXT_DeletingServices1033Deleting services0337541408IDS_ACTIONTEXT_EnvironmentStrings1033Updating environment strings0337541408IDS_ACTIONTEXT_EvaluateLaunchConditions1033Evaluating launch conditions0337541408IDS_ACTIONTEXT_Extension1033Extension: [1]0337541408IDS_ACTIONTEXT_Extension21033Extension: [1]0337541408IDS_ACTIONTEXT_Feature1033Feature: [1]0337541408IDS_ACTIONTEXT_FeatureColon1033Feature: [1]0337541408IDS_ACTIONTEXT_File1033File: [1]0337541408IDS_ACTIONTEXT_File21033File: [1]0337541408IDS_ACTIONTEXT_FileDependencies1033File: [1], Dependencies: [2]0337541408IDS_ACTIONTEXT_FileDir1033File: [1], Directory: [9]0337541408IDS_ACTIONTEXT_FileDir21033File: [1], Directory: [9]0337541408IDS_ACTIONTEXT_FileDir31033File: [1], Directory: [9]0337541408IDS_ACTIONTEXT_FileDirSize1033File: [1], Directory: [9], Size: [6]0337541408IDS_ACTIONTEXT_FileDirSize21033File: [1], Directory: [9], Size: [6]0337541408IDS_ACTIONTEXT_FileDirSize31033File: [1], Directory: [9], Size: [6]0337541408IDS_ACTIONTEXT_FileDirSize41033File: [1], Directory: [2], Size: [3]0337541408IDS_ACTIONTEXT_FileDirectorySize1033File: [1], Directory: [9], Size: [6]0337541408IDS_ACTIONTEXT_FileFolder1033File: [1], Folder: [2]0337541408IDS_ACTIONTEXT_FileFolder21033File: [1], Folder: [2]0337541408IDS_ACTIONTEXT_FileSectionKeyValue1033File: [1], Section: [2], Key: [3], Value: [4]0337541408IDS_ACTIONTEXT_FileSectionKeyValue21033File: [1], Section: [2], Key: [3], Value: [4]0337541408IDS_ACTIONTEXT_Folder1033Folder: [1]0337541408IDS_ACTIONTEXT_Folder11033Folder: [1]0337541408IDS_ACTIONTEXT_Font1033Font: [1]0337541408IDS_ACTIONTEXT_Font21033Font: [1]0337541408IDS_ACTIONTEXT_FoundApp1033Found application: [1]0337541408IDS_ACTIONTEXT_FreeSpace1033Free space: [1]0337541408IDS_ACTIONTEXT_GeneratingScript1033Generating script operations for action:0337541408IDS_ACTIONTEXT_ISLockPermissionsCost1033Gathering permissions information for objects...0337541408IDS_ACTIONTEXT_ISLockPermissionsInstall1033Applying permissions information for objects...0337541408IDS_ACTIONTEXT_InitializeODBCDirs1033Initializing ODBC directories0337541408IDS_ACTIONTEXT_InstallODBC1033Installing ODBC components0337541408IDS_ACTIONTEXT_InstallServices1033Installing new services0337541408IDS_ACTIONTEXT_InstallingSystemCatalog1033Installing system catalog0337541408IDS_ACTIONTEXT_KeyName1033Key: [1], Name: [2]0337541408IDS_ACTIONTEXT_KeyNameValue1033Key: [1], Name: [2], Value: [3]0337541408IDS_ACTIONTEXT_LibId1033LibID: [1]0337541408IDS_ACTIONTEXT_Libid21033LibID: [1]0337541408IDS_ACTIONTEXT_MigratingFeatureStates1033Migrating feature states from related applications0337541408IDS_ACTIONTEXT_MovingFiles1033Moving files0337541408IDS_ACTIONTEXT_NameValueAction1033Name: [1], Value: [2], Action [3]0337541408IDS_ACTIONTEXT_NameValueAction21033Name: [1], Value: [2], Action [3]0337541408IDS_ACTIONTEXT_PatchingFiles1033Patching files0337541408IDS_ACTIONTEXT_ProgID1033ProgID: [1]0337541408IDS_ACTIONTEXT_ProgID21033ProgID: [1]0337541408IDS_ACTIONTEXT_PropertySignature1033Property: [1], Signature: [2]0337541408IDS_ACTIONTEXT_PublishProductFeatures1033Publishing product features0337541408IDS_ACTIONTEXT_PublishProductInfo1033Publishing product information0337541408IDS_ACTIONTEXT_PublishingQualifiedComponents1033Publishing qualified components0337541408IDS_ACTIONTEXT_RegUser1033Registering user0337541408IDS_ACTIONTEXT_RegisterClassServer1033Registering class servers0337541408IDS_ACTIONTEXT_RegisterExtensionServers1033Registering extension servers0337541408IDS_ACTIONTEXT_RegisterFonts1033Registering fonts0337541408IDS_ACTIONTEXT_RegisterMimeInfo1033Registering MIME info0337541408IDS_ACTIONTEXT_RegisterTypeLibs1033Registering type libraries0337541408IDS_ACTIONTEXT_RegisteringComPlus1033Registering COM+ Applications and Components0337541408IDS_ACTIONTEXT_RegisteringModules1033Registering modules0337541408IDS_ACTIONTEXT_RegisteringProduct1033Registering product0337541408IDS_ACTIONTEXT_RegisteringProgIdentifiers1033Registering program identifiers0337541408IDS_ACTIONTEXT_RemoveApps1033Removing applications0337541408IDS_ACTIONTEXT_RemovingBackup1033Removing backup files0337541408IDS_ACTIONTEXT_RemovingDuplicates1033Removing duplicated files0337541408IDS_ACTIONTEXT_RemovingFiles1033Removing files0337541408IDS_ACTIONTEXT_RemovingFolders1033Removing folders0337541408IDS_ACTIONTEXT_RemovingIISRoots1033Removing IIS Virtual Roots...0337541408IDS_ACTIONTEXT_RemovingIni1033Removing INI file entries0337541408IDS_ACTIONTEXT_RemovingMoved1033Removing moved files0337541408IDS_ACTIONTEXT_RemovingODBC1033Removing ODBC components0337541408IDS_ACTIONTEXT_RemovingRegistry1033Removing system registry values0337541408IDS_ACTIONTEXT_RemovingShortcuts1033Removing shortcuts0337541408IDS_ACTIONTEXT_RollingBack1033Rolling back action:0337541408IDS_ACTIONTEXT_SearchForRelated1033Searching for related applications0337541408IDS_ACTIONTEXT_SearchInstalled1033Searching for installed applications0337541408IDS_ACTIONTEXT_SearchingQualifyingProducts1033Searching for qualifying products0337541408IDS_ACTIONTEXT_SearchingQualifyingProducts21033Searching for qualifying products0337541408IDS_ACTIONTEXT_Service1033Service: [1]0337541408IDS_ACTIONTEXT_Service21033Service: [2]0337541408IDS_ACTIONTEXT_Service31033Service: [1]0337541408IDS_ACTIONTEXT_Service41033Service: [1]0337541408IDS_ACTIONTEXT_Shortcut1033Shortcut: [1]0337541408IDS_ACTIONTEXT_Shortcut11033Shortcut: [1]0337541408IDS_ACTIONTEXT_StartingServices1033Starting services0337541408IDS_ACTIONTEXT_StoppingServices1033Stopping services0337541408IDS_ACTIONTEXT_UnpublishProductFeatures1033Unpublishing product features0337541408IDS_ACTIONTEXT_UnpublishQualified1033Unpublishing Qualified Components0337541408IDS_ACTIONTEXT_UnpublishingProductInfo1033Unpublishing product information0337541408IDS_ACTIONTEXT_UnregTypeLibs1033Unregistering type libraries0337541408IDS_ACTIONTEXT_UnregisterClassServers1033Unregister class servers0337541408IDS_ACTIONTEXT_UnregisterExtensionServers1033Unregistering extension servers0337541408IDS_ACTIONTEXT_UnregisterModules1033Unregistering modules0337541408IDS_ACTIONTEXT_UnregisteringComPlus1033Unregistering COM+ Applications and Components0337541408IDS_ACTIONTEXT_UnregisteringFonts1033Unregistering fonts0337541408IDS_ACTIONTEXT_UnregisteringMimeInfo1033Unregistering MIME info0337541408IDS_ACTIONTEXT_UnregisteringProgramIds1033Unregistering program identifiers0337541408IDS_ACTIONTEXT_UpdateComponentRegistration1033Updating component registration0337541408IDS_ACTIONTEXT_UpdateEnvironmentStrings1033Updating environment strings0337541408IDS_ACTIONTEXT_Validating1033Validating install0337541408IDS_ACTIONTEXT_WritingINI1033Writing INI file values0337541408IDS_ACTIONTEXT_WritingRegistry1033Writing system registry values0337541408IDS_BACK1033< &Back0337541408IDS_CANCEL1033Cancel0337541408IDS_CANCEL21033&Cancel0337541408IDS_CHANGE1033&Change...0337541408IDS_COMPLUS_PROGRESSTEXT_COST1033Costing COM+ application: [1]0337541408IDS_COMPLUS_PROGRESSTEXT_INSTALL1033Installing COM+ application: [1]0337541408IDS_COMPLUS_PROGRESSTEXT_UNINSTALL1033Uninstalling COM+ application: [1]0337541408IDS_DIALOG_TEXT2_DESCRIPTION1033Dialog Normal Description0337541408IDS_DIALOG_TEXT_DESCRIPTION_EXTERIOR1033{&TahomaBold10}Dialog Bold Title0337541408IDS_DIALOG_TEXT_DESCRIPTION_INTERIOR1033{&MSSansBold8}Dialog Bold Title0337541408IDS_DIFX_AMD641033[ProductName] requires an X64 processor. Click OK to exit the wizard.0337541408IDS_DIFX_IA641033[ProductName] requires an IA64 processor. Click OK to exit the wizard.0337541408IDS_DIFX_X861033[ProductName] requires an X86 processor. Click OK to exit the wizard.0337541408IDS_DatabaseFolder_InstallDatabaseTo1033Install [ProductName] database to:0337541408IDS_ERROR_01033{{Fatal error: }}0337541408IDS_ERROR_11033Error [1]. 0337541408IDS_ERROR_101033=== Logging started: [Date] [Time] ===0337541408IDS_ERROR_1001033Could not remove shortcut [2]. Verify that the shortcut file exists and that you can access it.0337541408IDS_ERROR_1011033Could not register type library for file [2]. Contact your support personnel.0337541408IDS_ERROR_1021033Could not unregister type library for file [2]. Contact your support personnel.0337541408IDS_ERROR_1031033Could not update the INI file [2][3]. Verify that the file exists and that you can access it.0337541408IDS_ERROR_1041033Could not schedule file [2] to replace file [3] on reboot. Verify that you have write permissions to file [3].0337541408IDS_ERROR_1051033Error removing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.0337541408IDS_ERROR_1061033Error installing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.0337541408IDS_ERROR_1071033Error removing ODBC driver [4], ODBC error [2]: [3]. Verify that you have sufficient privileges to remove ODBC drivers.0337541408IDS_ERROR_1081033Error installing ODBC driver [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.0337541408IDS_ERROR_1091033Error configuring ODBC data source [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.0337541408IDS_ERROR_111033=== Logging stopped: [Date] [Time] ===0337541408IDS_ERROR_1101033Service [2] ([3]) failed to start. Verify that you have sufficient privileges to start system services.0337541408IDS_ERROR_1111033Service [2] ([3]) could not be stopped. Verify that you have sufficient privileges to stop system services.0337541408IDS_ERROR_1121033Service [2] ([3]) could not be deleted. Verify that you have sufficient privileges to remove system services.0337541408IDS_ERROR_1131033Service [2] ([3]) could not be installed. Verify that you have sufficient privileges to install system services.0337541408IDS_ERROR_1141033Could not update environment variable [2]. Verify that you have sufficient privileges to modify environment variables.0337541408IDS_ERROR_1151033You do not have sufficient privileges to complete this installation for all users of the machine. Log on as an administrator and then retry this installation.0337541408IDS_ERROR_1161033Could not set file security for file [3]. Error: [2]. Verify that you have sufficient privileges to modify the security permissions for this file.0337541408IDS_ERROR_1171033Component Services (COM+ 1.0) are not installed on this computer. This installation requires Component Services in order to complete successfully. Component Services are available on Windows 2000.0337541408IDS_ERROR_1181033Error registering COM+ application. Contact your support personnel for more information.0337541408IDS_ERROR_1191033Error unregistering COM+ application. Contact your support personnel for more information.0337541408IDS_ERROR_121033Action start [Time]: [1].0337541408IDS_ERROR_1201033Removing older versions of this application0337541408IDS_ERROR_1211033Preparing to remove older versions of this application0337541408IDS_ERROR_1221033Error applying patch to file [2]. It has probably been updated by other means, and can no longer be modified by this patch. For more information contact your patch vendor. {{System Error: [3]}}0337541408IDS_ERROR_1231033[2] cannot install one of its required products. Contact your technical support group. {{System Error: [3].}}0337541408IDS_ERROR_1241033The older version of [2] cannot be removed. Contact your technical support group. {{System Error [3].}}0337541408IDS_ERROR_1251033The description for service '[2]' ([3]) could not be changed.0337541408IDS_ERROR_1261033The Windows Installer service cannot update the system file [2] because the file is protected by Windows. You may need to update your operating system for this program to work correctly. {{Package version: [3], OS Protected version: [4]}}0337541408IDS_ERROR_1271033The Windows Installer service cannot update the protected Windows file [2]. {{Package version: [3], OS Protected version: [4], SFP Error: [5]}}0337541408IDS_ERROR_1281033The Windows Installer service cannot update one or more protected Windows files. SFP Error: [2]. List of protected files: [3]0337541408IDS_ERROR_1291033User installations are disabled via policy on the machine.0337541408IDS_ERROR_131033Action ended [Time]: [1]. Return value [2].0337541408IDS_ERROR_1301033This setup requires Internet Information Server 4.0 or higher for configuring IIS Virtual Roots. Please make sure that you have IIS 4.0 or higher.0337541408IDS_ERROR_1311033This setup requires Administrator privileges for configuring IIS Virtual Roots.0337541408IDS_ERROR_13291033A file that is required cannot be installed because the cabinet file [2] is not digitally signed. This may indicate that the cabinet file is corrupt.0337541408IDS_ERROR_13301033A file that is required cannot be installed because the cabinet file [2] has an invalid digital signature. This may indicate that the cabinet file is corrupt.{ Error [3] was returned by WinVerifyTrust.}0337541408IDS_ERROR_13311033Failed to correctly copy [2] file: CRC error.0337541408IDS_ERROR_13321033Failed to correctly patch [2] file: CRC error.0337541408IDS_ERROR_13331033Failed to correctly patch [2] file: CRC error.0337541408IDS_ERROR_13341033The file '[2]' cannot be installed because the file cannot be found in cabinet file '[3]'. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package.0337541408IDS_ERROR_13351033The cabinet file '[2]' required for this installation is corrupt and cannot be used. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package.0337541408IDS_ERROR_13361033There was an error creating a temporary file that is needed to complete this installation. Folder: [3]. System error code: [2]0337541408IDS_ERROR_141033Time remaining: {[1] minutes }{[2] seconds}0337541408IDS_ERROR_151033Out of memory. Shut down other applications before retrying.0337541408IDS_ERROR_161033Installer is no longer responding.0337541408IDS_ERROR_16091033An error occurred while applying security settings. [2] is not a valid user or group. This could be a problem with the package, or a problem connecting to a domain controller on the network. Check your network connection and click Retry, or Cancel to end the install. Unable to locate the user's SID, system error [3]0337541408IDS_ERROR_16511033Admin user failed to apply patch for a per-user managed or a per-machine application which is in advertise state.0337541408IDS_ERROR_171033Installer terminated prematurely.0337541408IDS_ERROR_17151033Installed [2].0337541408IDS_ERROR_17161033Configured [2].0337541408IDS_ERROR_17171033Removed [2].0337541408IDS_ERROR_17181033File [2] was rejected by digital signature policy.0337541408IDS_ERROR_17191033Windows Installer service could not be accessed. Contact your support personnel to verify that it is properly registered and enabled.0337541408IDS_ERROR_17201033There is a problem with this Windows Installer package. A script required for this install to complete could not be run. Contact your support personnel or package vendor. Custom action [2] script error [3], [4]: [5] Line [6], Column [7], [8]0337541408IDS_ERROR_17211033There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: [2], location: [3], command: [4]0337541408IDS_ERROR_17221033There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action [2], location: [3], command: [4]0337541408IDS_ERROR_17231033There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. Action [2], entry: [3], library: [4]0337541408IDS_ERROR_17241033Removal completed successfully.0337541408IDS_ERROR_17251033Removal failed.0337541408IDS_ERROR_17261033Advertisement completed successfully.0337541408IDS_ERROR_17271033Advertisement failed.0337541408IDS_ERROR_17281033Configuration completed successfully.0337541408IDS_ERROR_17291033Configuration failed.0337541408IDS_ERROR_17301033You must be an Administrator to remove this application. To remove this application, you can log on as an administrator, or contact your technical support group for assistance.0337541408IDS_ERROR_17311033The source installation package for the product [2] is out of sync with the client package. Try the installation again using a valid copy of the installation package '[3]'.0337541408IDS_ERROR_17321033In order to complete the installation of [2], you must restart the computer. Other users are currently logged on to this computer, and restarting may cause them to lose their work. Do you want to restart now?0337541408IDS_ERROR_181033Please wait while Windows configures [ProductName]0337541408IDS_ERROR_191033Gathering required information...0337541408IDS_ERROR_19351033An error occurred during the installation of assembly component [2]. HRESULT: [3]. {{assembly interface: [4], function: [5], assembly name: [6]}}0337541408IDS_ERROR_19361033An error occurred during the installation of assembly '[6]'. The assembly is not strongly named or is not signed with the minimal key length. HRESULT: [3]. {{assembly interface: [4], function: [5], component: [2]}}0337541408IDS_ERROR_19371033An error occurred during the installation of assembly '[6]'. The signature or catalog could not be verified or is not valid. HRESULT: [3]. {{assembly interface: [4], function: [5], component: [2]}}0337541408IDS_ERROR_19381033An error occurred during the installation of assembly '[6]'. One or more modules of the assembly could not be found. HRESULT: [3]. {{assembly interface: [4], function: [5], component: [2]}}0337541408IDS_ERROR_21033Warning [1]. 0337541408IDS_ERROR_201033{[ProductName] }Setup completed successfully.0337541408IDS_ERROR_211033{[ProductName] }Setup failed.0337541408IDS_ERROR_21011033Shortcuts not supported by the operating system.0337541408IDS_ERROR_21021033Invalid .ini action: [2]0337541408IDS_ERROR_21031033Could not resolve path for shell folder [2].0337541408IDS_ERROR_21041033Writing .ini file: [3]: System error: [2].0337541408IDS_ERROR_21051033Shortcut Creation [3] Failed. System error: [2].0337541408IDS_ERROR_21061033Shortcut Deletion [3] Failed. System error: [2].0337541408IDS_ERROR_21071033Error [3] registering type library [2].0337541408IDS_ERROR_21081033Error [3] unregistering type library [2].0337541408IDS_ERROR_21091033Section missing for .ini action.0337541408IDS_ERROR_21101033Key missing for .ini action.0337541408IDS_ERROR_21111033Detection of running applications failed, could not get performance data. Registered operation returned : [2].0337541408IDS_ERROR_21121033Detection of running applications failed, could not get performance index. Registered operation returned : [2].0337541408IDS_ERROR_21131033Detection of running applications failed.0337541408IDS_ERROR_221033Error reading from file: [2]. {{ System error [3].}} Verify that the file exists and that you can access it.0337541408IDS_ERROR_22001033Database: [2]. Database object creation failed, mode = [3].0337541408IDS_ERROR_22011033Database: [2]. Initialization failed, out of memory.0337541408IDS_ERROR_22021033Database: [2]. Data access failed, out of memory.0337541408IDS_ERROR_22031033Database: [2]. Cannot open database file. System error [3].0337541408IDS_ERROR_22041033Database: [2]. Table already exists: [3].0337541408IDS_ERROR_22051033Database: [2]. Table does not exist: [3].0337541408IDS_ERROR_22061033Database: [2]. Table could not be dropped: [3].0337541408IDS_ERROR_22071033Database: [2]. Intent violation.0337541408IDS_ERROR_22081033Database: [2]. Insufficient parameters for Execute.0337541408IDS_ERROR_22091033Database: [2]. Cursor in invalid state.0337541408IDS_ERROR_22101033Database: [2]. Invalid update data type in column [3].0337541408IDS_ERROR_22111033Database: [2]. Could not create database table [3].0337541408IDS_ERROR_22121033Database: [2]. Database not in writable state.0337541408IDS_ERROR_22131033Database: [2]. Error saving database tables.0337541408IDS_ERROR_22141033Database: [2]. Error writing export file: [3].0337541408IDS_ERROR_22151033Database: [2]. Cannot open import file: [3].0337541408IDS_ERROR_22161033Database: [2]. Import file format error: [3], Line [4].0337541408IDS_ERROR_22171033Database: [2]. Wrong state to CreateOutputDatabase [3].0337541408IDS_ERROR_22181033Database: [2]. Table name not supplied.0337541408IDS_ERROR_22191033Database: [2]. Invalid Installer database format.0337541408IDS_ERROR_22201033Database: [2]. Invalid row/field data.0337541408IDS_ERROR_22211033Database: [2]. Code page conflict in import file: [3].0337541408IDS_ERROR_22221033Database: [2]. Transform or merge code page [3] differs from database code page [4].0337541408IDS_ERROR_22231033Database: [2]. Databases are the same. No transform generated.0337541408IDS_ERROR_22241033Database: [2]. GenerateTransform: Database corrupt. Table: [3].0337541408IDS_ERROR_22251033Database: [2]. Transform: Cannot transform a temporary table. Table: [3].0337541408IDS_ERROR_22261033Database: [2]. Transform failed.0337541408IDS_ERROR_22271033Database: [2]. Invalid identifier '[3]' in SQL query: [4].0337541408IDS_ERROR_22281033Database: [2]. Unknown table '[3]' in SQL query: [4].0337541408IDS_ERROR_22291033Database: [2]. Could not load table '[3]' in SQL query: [4].0337541408IDS_ERROR_22301033Database: [2]. Repeated table '[3]' in SQL query: [4].0337541408IDS_ERROR_22311033Database: [2]. Missing ')' in SQL query: [3].0337541408IDS_ERROR_22321033Database: [2]. Unexpected token '[3]' in SQL query: [4].0337541408IDS_ERROR_22331033Database: [2]. No columns in SELECT clause in SQL query: [3].0337541408IDS_ERROR_22341033Database: [2]. No columns in ORDER BY clause in SQL query: [3].0337541408IDS_ERROR_22351033Database: [2]. Column '[3]' not present or ambiguous in SQL query: [4].0337541408IDS_ERROR_22361033Database: [2]. Invalid operator '[3]' in SQL query: [4].0337541408IDS_ERROR_22371033Database: [2]. Invalid or missing query string: [3].0337541408IDS_ERROR_22381033Database: [2]. Missing FROM clause in SQL query: [3].0337541408IDS_ERROR_22391033Database: [2]. Insufficient values in INSERT SQL statement.0337541408IDS_ERROR_22401033Database: [2]. Missing update columns in UPDATE SQL statement.0337541408IDS_ERROR_22411033Database: [2]. Missing insert columns in INSERT SQL statement.0337541408IDS_ERROR_22421033Database: [2]. Column '[3]' repeated.0337541408IDS_ERROR_22431033Database: [2]. No primary columns defined for table creation.0337541408IDS_ERROR_22441033Database: [2]. Invalid type specifier '[3]' in SQL query [4].0337541408IDS_ERROR_22451033IStorage::Stat failed with error [3].0337541408IDS_ERROR_22461033Database: [2]. Invalid Installer transform format.0337541408IDS_ERROR_22471033Database: [2] Transform stream read/write failure.0337541408IDS_ERROR_22481033Database: [2] GenerateTransform/Merge: Column type in base table does not match reference table. Table: [3] Col #: [4].0337541408IDS_ERROR_22491033Database: [2] GenerateTransform: More columns in base table than in reference table. Table: [3].0337541408IDS_ERROR_22501033Database: [2] Transform: Cannot add existing row. Table: [3].0337541408IDS_ERROR_22511033Database: [2] Transform: Cannot delete row that does not exist. Table: [3].0337541408IDS_ERROR_22521033Database: [2] Transform: Cannot add existing table. Table: [3].0337541408IDS_ERROR_22531033Database: [2] Transform: Cannot delete table that does not exist. Table: [3].0337541408IDS_ERROR_22541033Database: [2] Transform: Cannot update row that does not exist. Table: [3].0337541408IDS_ERROR_22551033Database: [2] Transform: Column with this name already exists. Table: [3] Col: [4].0337541408IDS_ERROR_22561033Database: [2] GenerateTransform/Merge: Number of primary keys in base table does not match reference table. Table: [3].0337541408IDS_ERROR_22571033Database: [2]. Intent to modify read only table: [3].0337541408IDS_ERROR_22581033Database: [2]. Type mismatch in parameter: [3].0337541408IDS_ERROR_22591033Database: [2] Table(s) Update failed0337541408IDS_ERROR_22601033Storage CopyTo failed. System error: [3].0337541408IDS_ERROR_22611033Could not remove stream [2]. System error: [3].0337541408IDS_ERROR_22621033Stream does not exist: [2]. System error: [3].0337541408IDS_ERROR_22631033Could not open stream [2]. System error: [3].0337541408IDS_ERROR_22641033Could not remove stream [2]. System error: [3].0337541408IDS_ERROR_22651033Could not commit storage. System error: [3].0337541408IDS_ERROR_22661033Could not rollback storage. System error: [3].0337541408IDS_ERROR_22671033Could not delete storage [2]. System error: [3].0337541408IDS_ERROR_22681033Database: [2]. Merge: There were merge conflicts reported in [3] tables.0337541408IDS_ERROR_22691033Database: [2]. Merge: The column count differed in the '[3]' table of the two databases.0337541408IDS_ERROR_22701033Database: [2]. GenerateTransform/Merge: Column name in base table does not match reference table. Table: [3] Col #: [4].0337541408IDS_ERROR_22711033SummaryInformation write for transform failed.0337541408IDS_ERROR_22721033Database: [2]. MergeDatabase will not write any changes because the database is open read-only.0337541408IDS_ERROR_22731033Database: [2]. MergeDatabase: A reference to the base database was passed as the reference database.0337541408IDS_ERROR_22741033Database: [2]. MergeDatabase: Unable to write errors to Error table. Could be due to a non-nullable column in a predefined Error table.0337541408IDS_ERROR_22751033Database: [2]. Specified Modify [3] operation invalid for table joins.0337541408IDS_ERROR_22761033Database: [2]. Code page [3] not supported by the system.0337541408IDS_ERROR_22771033Database: [2]. Failed to save table [3].0337541408IDS_ERROR_22781033Database: [2]. Exceeded number of expressions limit of 32 in WHERE clause of SQL query: [3].0337541408IDS_ERROR_22791033Database: [2] Transform: Too many columns in base table [3].0337541408IDS_ERROR_22801033Database: [2]. Could not create column [3] for table [4].0337541408IDS_ERROR_22811033Could not rename stream [2]. System error: [3].0337541408IDS_ERROR_22821033Stream name invalid [2].0337541408IDS_ERROR_231033Cannot create the file [3]. A directory with this name already exists. Cancel the installation and try installing to a different location.0337541408IDS_ERROR_23021033Patch notify: [2] bytes patched to far.0337541408IDS_ERROR_23031033Error getting volume info. GetLastError: [2].0337541408IDS_ERROR_23041033Error getting disk free space. GetLastError: [2]. Volume: [3].0337541408IDS_ERROR_23051033Error waiting for patch thread. GetLastError: [2].0337541408IDS_ERROR_23061033Could not create thread for patch application. GetLastError: [2].0337541408IDS_ERROR_23071033Source file key name is null.0337541408IDS_ERROR_23081033Destination file name is null.0337541408IDS_ERROR_23091033Attempting to patch file [2] when patch already in progress.0337541408IDS_ERROR_23101033Attempting to continue patch when no patch is in progress.0337541408IDS_ERROR_23151033Missing path separator: [2].0337541408IDS_ERROR_23181033File does not exist: [2].0337541408IDS_ERROR_23191033Error setting file attribute: [3] GetLastError: [2].0337541408IDS_ERROR_23201033File not writable: [2].0337541408IDS_ERROR_23211033Error creating file: [2].0337541408IDS_ERROR_23221033User canceled.0337541408IDS_ERROR_23231033Invalid file attribute.0337541408IDS_ERROR_23241033Could not open file: [3] GetLastError: [2].0337541408IDS_ERROR_23251033Could not get file time for file: [3] GetLastError: [2].0337541408IDS_ERROR_23261033Error in FileToDosDateTime.0337541408IDS_ERROR_23271033Could not remove directory: [3] GetLastError: [2].0337541408IDS_ERROR_23281033Error getting file version info for file: [2].0337541408IDS_ERROR_23291033Error deleting file: [3]. GetLastError: [2].0337541408IDS_ERROR_23301033Error getting file attributes: [3]. GetLastError: [2].0337541408IDS_ERROR_23311033Error loading library [2] or finding entry point [3].0337541408IDS_ERROR_23321033Error getting file attributes. GetLastError: [2].0337541408IDS_ERROR_23331033Error setting file attributes. GetLastError: [2].0337541408IDS_ERROR_23341033Error converting file time to local time for file: [3]. GetLastError: [2].0337541408IDS_ERROR_23351033Path: [2] is not a parent of [3].0337541408IDS_ERROR_23361033Error creating temp file on path: [3]. GetLastError: [2].0337541408IDS_ERROR_23371033Could not close file: [3] GetLastError: [2].0337541408IDS_ERROR_23381033Could not update resource for file: [3] GetLastError: [2].0337541408IDS_ERROR_23391033Could not set file time for file: [3] GetLastError: [2].0337541408IDS_ERROR_23401033Could not update resource for file: [3], Missing resource.0337541408IDS_ERROR_23411033Could not update resource for file: [3], Resource too large.0337541408IDS_ERROR_23421033Could not update resource for file: [3] GetLastError: [2].0337541408IDS_ERROR_23431033Specified path is empty.0337541408IDS_ERROR_23441033Could not find required file IMAGEHLP.DLL to validate file:[2].0337541408IDS_ERROR_23451033[2]: File does not contain a valid checksum value.0337541408IDS_ERROR_23471033User ignore.0337541408IDS_ERROR_23481033Error attempting to read from cabinet stream.0337541408IDS_ERROR_23491033Copy resumed with different info.0337541408IDS_ERROR_23501033FDI server error0337541408IDS_ERROR_23511033File key '[2]' not found in cabinet '[3]'. The installation cannot continue.0337541408IDS_ERROR_23521033Could not initialize cabinet file server. The required file 'CABINET.DLL' may be missing.0337541408IDS_ERROR_23531033Not a cabinet.0337541408IDS_ERROR_23541033Cannot handle cabinet.0337541408IDS_ERROR_23551033Corrupt cabinet.0337541408IDS_ERROR_23561033Could not locate cabinet in stream: [2].0337541408IDS_ERROR_23571033Cannot set attributes.0337541408IDS_ERROR_23581033Error determining whether file is in-use: [3]. GetLastError: [2].0337541408IDS_ERROR_23591033Unable to create the target file - file may be in use.0337541408IDS_ERROR_23601033Progress tick.0337541408IDS_ERROR_23611033Need next cabinet.0337541408IDS_ERROR_23621033Folder not found: [2].0337541408IDS_ERROR_23631033Could not enumerate subfolders for folder: [2].0337541408IDS_ERROR_23641033Bad enumeration constant in CreateCopier call.0337541408IDS_ERROR_23651033Could not BindImage exe file [2].0337541408IDS_ERROR_23661033User failure.0337541408IDS_ERROR_23671033User abort.0337541408IDS_ERROR_23681033Failed to get network resource information. Error [2], network path [3]. Extended error: network provider [5], error code [4], error description [6].0337541408IDS_ERROR_23701033Invalid CRC checksum value for [2] file.{ Its header says [3] for checksum, its computed value is [4].}0337541408IDS_ERROR_23711033Could not apply patch to file [2]. GetLastError: [3].0337541408IDS_ERROR_23721033Patch file [2] is corrupt or of an invalid format. Attempting to patch file [3]. GetLastError: [4].0337541408IDS_ERROR_23731033File [2] is not a valid patch file.0337541408IDS_ERROR_23741033File [2] is not a valid destination file for patch file [3].0337541408IDS_ERROR_23751033Unknown patching error: [2].0337541408IDS_ERROR_23761033Cabinet not found.0337541408IDS_ERROR_23791033Error opening file for read: [3] GetLastError: [2].0337541408IDS_ERROR_23801033Error opening file for write: [3]. GetLastError: [2].0337541408IDS_ERROR_23811033Directory does not exist: [2].0337541408IDS_ERROR_23821033Drive not ready: [2].0337541408IDS_ERROR_241033Please insert the disk: [2]0337541408IDS_ERROR_2401103364-bit registry operation attempted on 32-bit operating system for key [2].0337541408IDS_ERROR_24021033Out of memory.0337541408IDS_ERROR_251033The installer has insufficient privileges to access this directory: [2]. The installation cannot continue. Log on as an administrator or contact your system administrator.0337541408IDS_ERROR_25011033Could not create rollback script enumerator.0337541408IDS_ERROR_25021033Called InstallFinalize when no install in progress.0337541408IDS_ERROR_25031033Called RunScript when not marked in progress.0337541408IDS_ERROR_261033Error writing to file [2]. Verify that you have access to that directory.0337541408IDS_ERROR_26011033Invalid value for property [2]: '[3]'0337541408IDS_ERROR_26021033The [2] table entry '[3]' has no associated entry in the Media table.0337541408IDS_ERROR_26031033Duplicate table name [2].0337541408IDS_ERROR_26041033[2] Property undefined.0337541408IDS_ERROR_26051033Could not find server [2] in [3] or [4].0337541408IDS_ERROR_26061033Value of property [2] is not a valid full path: '[3]'.0337541408IDS_ERROR_26071033Media table not found or empty (required for installation of files).0337541408IDS_ERROR_26081033Could not create security descriptor for object. Error: '[2]'.0337541408IDS_ERROR_26091033Attempt to migrate product settings before initialization.0337541408IDS_ERROR_26111033The file [2] is marked as compressed, but the associated media entry does not specify a cabinet.0337541408IDS_ERROR_26121033Stream not found in '[2]' column. Primary key: '[3]'.0337541408IDS_ERROR_26131033RemoveExistingProducts action sequenced incorrectly.0337541408IDS_ERROR_26141033Could not access IStorage object from installation package.0337541408IDS_ERROR_26151033Skipped unregistration of Module [2] due to source resolution failure.0337541408IDS_ERROR_26161033Companion file [2] parent missing.0337541408IDS_ERROR_26171033Shared component [2] not found in Component table.0337541408IDS_ERROR_26181033Isolated application component [2] not found in Component table.0337541408IDS_ERROR_26191033Isolated components [2], [3] not part of same feature.0337541408IDS_ERROR_26201033Key file of isolated application component [2] not in File table.0337541408IDS_ERROR_26211033Resource DLL or Resource ID information for shortcut [2] set incorrectly.0337541408IDS_ERROR_271033Error reading from file [2]. Verify that the file exists and that you can access it.0337541408IDS_ERROR_27011033The depth of a feature exceeds the acceptable tree depth of [2] levels.0337541408IDS_ERROR_27021033A Feature table record ([2]) references a non-existent parent in the Attributes field.0337541408IDS_ERROR_27031033Property name for root source path not defined: [2]0337541408IDS_ERROR_27041033Root directory property undefined: [2]0337541408IDS_ERROR_27051033Invalid table: [2]; Could not be linked as tree.0337541408IDS_ERROR_27061033Source paths not created. No path exists for entry [2] in Directory table.0337541408IDS_ERROR_27071033Target paths not created. No path exists for entry [2] in Directory table.0337541408IDS_ERROR_27081033No entries found in the file table.0337541408IDS_ERROR_27091033The specified Component name ('[2]') not found in Component table.0337541408IDS_ERROR_27101033The requested 'Select' state is illegal for this Component.0337541408IDS_ERROR_27111033The specified Feature name ('[2]') not found in Feature table.0337541408IDS_ERROR_27121033Invalid return from modeless dialog: [3], in action [2].0337541408IDS_ERROR_27131033Null value in a non-nullable column ('[2]' in '[3]' column of the '[4]' table.0337541408IDS_ERROR_27141033Invalid value for default folder name: [2].0337541408IDS_ERROR_27151033The specified File key ('[2]') not found in the File table.0337541408IDS_ERROR_27161033Could not create a random subcomponent name for component '[2]'.0337541408IDS_ERROR_27171033Bad action condition or error calling custom action '[2]'.0337541408IDS_ERROR_27181033Missing package name for product code '[2]'.0337541408IDS_ERROR_27191033Neither UNC nor drive letter path found in source '[2]'.0337541408IDS_ERROR_27201033Error opening source list key. Error: '[2]'0337541408IDS_ERROR_27211033Custom action [2] not found in Binary table stream.0337541408IDS_ERROR_27221033Custom action [2] not found in File table.0337541408IDS_ERROR_27231033Custom action [2] specifies unsupported type.0337541408IDS_ERROR_27241033The volume label '[2]' on the media you're running from does not match the label '[3]' given in the Media table. This is allowed only if you have only 1 entry in your Media table.0337541408IDS_ERROR_27251033Invalid database tables0337541408IDS_ERROR_27261033Action not found: [2].0337541408IDS_ERROR_27271033The directory entry '[2]' does not exist in the Directory table.0337541408IDS_ERROR_27281033Table definition error: [2]0337541408IDS_ERROR_27291033Install engine not initialized.0337541408IDS_ERROR_27301033Bad value in database. Table: '[2]'; Primary key: '[3]'; Column: '[4]'0337541408IDS_ERROR_27311033Selection Manager not initialized.0337541408IDS_ERROR_27321033Directory Manager not initialized.0337541408IDS_ERROR_27331033Bad foreign key ('[2]') in '[3]' column of the '[4]' table.0337541408IDS_ERROR_27341033Invalid reinstall mode character.0337541408IDS_ERROR_27351033Custom action '[2]' has caused an unhandled exception and has been stopped. This may be the result of an internal error in the custom action, such as an access violation.0337541408IDS_ERROR_27361033Generation of custom action temp file failed: [2].0337541408IDS_ERROR_27371033Could not access custom action [2], entry [3], library [4]0337541408IDS_ERROR_27381033Could not access VBScript run time for custom action [2].0337541408IDS_ERROR_27391033Could not access JavaScript run time for custom action [2].0337541408IDS_ERROR_27401033Custom action [2] script error [3], [4]: [5] Line [6], Column [7], [8].0337541408IDS_ERROR_27411033Configuration information for product [2] is corrupt. Invalid info: [2].0337541408IDS_ERROR_27421033Marshaling to Server failed: [2].0337541408IDS_ERROR_27431033Could not execute custom action [2], location: [3], command: [4].0337541408IDS_ERROR_27441033EXE failed called by custom action [2], location: [3], command: [4].0337541408IDS_ERROR_27451033Transform [2] invalid for package [3]. Expected language [4], found language [5].0337541408IDS_ERROR_27461033Transform [2] invalid for package [3]. Expected product [4], found product [5].0337541408IDS_ERROR_27471033Transform [2] invalid for package [3]. Expected product version < [4], found product version [5].0337541408IDS_ERROR_27481033Transform [2] invalid for package [3]. Expected product version <= [4], found product version [5].0337541408IDS_ERROR_27491033Transform [2] invalid for package [3]. Expected product version == [4], found product version [5].0337541408IDS_ERROR_27501033Transform [2] invalid for package [3]. Expected product version >= [4], found product version [5].0337541408IDS_ERROR_275021033Could not connect to [2] '[3]'. [4]0337541408IDS_ERROR_275031033Error retrieving version string from [2] '[3]'. [4]0337541408IDS_ERROR_275041033SQL version requirements not met: [3]. This installation requires [2] [4] or later.0337541408IDS_ERROR_275051033Could not open SQL script file [2].0337541408IDS_ERROR_275061033Error executing SQL script [2]. Line [3]. [4]0337541408IDS_ERROR_275071033Connection or browsing for database servers requires that MDAC be installed.0337541408IDS_ERROR_275081033Error installing COM+ application [2]. [3]0337541408IDS_ERROR_275091033Error uninstalling COM+ application [2]. [3]0337541408IDS_ERROR_27511033Transform [2] invalid for package [3]. Expected product version > [4], found product version [5].0337541408IDS_ERROR_275101033Error installing COM+ application [2]. Could not load Microsoft(R) .NET class libraries. Registering .NET serviced components requires that Microsoft(R) .NET Framework be installed.0337541408IDS_ERROR_275111033Could not execute SQL script file [2]. Connection not open: [3]0337541408IDS_ERROR_275121033Error beginning transactions for [2] '[3]'. Database [4]. [5]0337541408IDS_ERROR_275131033Error committing transactions for [2] '[3]'. Database [4]. [5]0337541408IDS_ERROR_275141033This installation requires a Microsoft SQL Server. The specified server '[3]' is a Microsoft SQL Server Desktop Engine or SQL Server Express.0337541408IDS_ERROR_275151033Error retrieving schema version from [2] '[3]'. Database: '[4]'. [5]0337541408IDS_ERROR_275161033Error writing schema version to [2] '[3]'. Database: '[4]'. [5]0337541408IDS_ERROR_275171033This installation requires Administrator privileges for installing COM+ applications. Log on as an administrator and then retry this installation.0337541408IDS_ERROR_275181033The COM+ application "[2]" is configured to run as an NT service; this requires COM+ 1.5 or later on the system. Since your system has COM+ 1.0, this application will not be installed.0337541408IDS_ERROR_275191033Error updating XML file [2]. [3]0337541408IDS_ERROR_27521033Could not open transform [2] stored as child storage of package [4].0337541408IDS_ERROR_275201033Error opening XML file [2]. [3]0337541408IDS_ERROR_275211033This setup requires MSXML 3.0 or higher for configuring XML files. Please make sure that you have version 3.0 or higher.0337541408IDS_ERROR_275221033Error creating XML file [2]. [3]0337541408IDS_ERROR_275231033Error loading servers.0337541408IDS_ERROR_275241033Error loading NetApi32.DLL. The ISNetApi.dll needs to have NetApi32.DLL properly loaded and requires an NT based operating system.0337541408IDS_ERROR_275251033Server not found. Verify that the specified server exists. The server name can not be empty.0337541408IDS_ERROR_275261033Unspecified error from ISNetApi.dll.0337541408IDS_ERROR_275271033The buffer is too small.0337541408IDS_ERROR_275281033Access denied. Check administrative rights.0337541408IDS_ERROR_275291033Invalid computer.0337541408IDS_ERROR_27531033The File '[2]' is not marked for installation.0337541408IDS_ERROR_275301033Unknown error returned from NetAPI. System error: [2]0337541408IDS_ERROR_275311033Unhandled exception.0337541408IDS_ERROR_275321033Invalid user name for this server or domain.0337541408IDS_ERROR_275331033The case-sensitive passwords do not match.0337541408IDS_ERROR_275341033The list is empty.0337541408IDS_ERROR_275351033Access violation.0337541408IDS_ERROR_275361033Error getting group.0337541408IDS_ERROR_275371033Error adding user to group. Verify that the group exists for this domain or server.0337541408IDS_ERROR_275381033Error creating user.0337541408IDS_ERROR_275391033ERROR_NETAPI_ERROR_NOT_PRIMARY returned from NetAPI.0337541408IDS_ERROR_27541033The File '[2]' is not a valid patch file.0337541408IDS_ERROR_275401033The specified user already exists.0337541408IDS_ERROR_275411033The specified group already exists.0337541408IDS_ERROR_275421033Invalid password. Verify that the password is in accordance with your network password policy.0337541408IDS_ERROR_275431033Invalid name.0337541408IDS_ERROR_275441033Invalid group.0337541408IDS_ERROR_275451033The user name can not be empty and must be in the format DOMAIN\Username.0337541408IDS_ERROR_275461033Error loading or creating INI file in the user TEMP directory.0337541408IDS_ERROR_275471033ISNetAPI.dll is not loaded or there was an error loading the dll. This dll needs to be loaded for this operation. Verify that the dll is in the SUPPORTDIR directory.0337541408IDS_ERROR_275481033Error deleting INI file containing new user information from the user's TEMP directory.0337541408IDS_ERROR_275491033Error getting the primary domain controller (PDC).0337541408IDS_ERROR_27551033Server returned unexpected error [2] attempting to install package [3].0337541408IDS_ERROR_275501033Every field must have a value in order to create a user.0337541408IDS_ERROR_275511033ODBC driver for [2] not found. This is required to connect to [2] database servers.0337541408IDS_ERROR_275521033Error creating database [4]. Server: [2] [3]. [5]0337541408IDS_ERROR_275531033Error connecting to database [4]. Server: [2] [3]. [5]0337541408IDS_ERROR_275541033Error attempting to open connection [2]. No valid database metadata associated with this connection.0337541408IDS_ERROR_275551033Error attempting to apply permissions to object '[2]'. System error: [3] ([4])0337541408IDS_ERROR_27561033The property '[2]' was used as a directory property in one or more tables, but no value was ever assigned.0337541408IDS_ERROR_27571033Could not create summary info for transform [2].0337541408IDS_ERROR_27581033Transform [2] does not contain an MSI version.0337541408IDS_ERROR_27591033Transform [2] version [3] incompatible with engine; Min: [4], Max: [5].0337541408IDS_ERROR_27601033Transform [2] invalid for package [3]. Expected upgrade code [4], found [5].0337541408IDS_ERROR_27611033Cannot begin transaction. Global mutex not properly initialized.0337541408IDS_ERROR_27621033Cannot write script record. Transaction not started.0337541408IDS_ERROR_27631033Cannot run script. Transaction not started.0337541408IDS_ERROR_27651033Assembly name missing from AssemblyName table : Component: [4].0337541408IDS_ERROR_27661033The file [2] is an invalid MSI storage file.0337541408IDS_ERROR_27671033No more data{ while enumerating [2]}.0337541408IDS_ERROR_27681033Transform in patch package is invalid.0337541408IDS_ERROR_27691033Custom Action [2] did not close [3] MSIHANDLEs.0337541408IDS_ERROR_27701033Cached folder [2] not defined in internal cache folder table.0337541408IDS_ERROR_27711033Upgrade of feature [2] has a missing component.0337541408IDS_ERROR_27721033New upgrade feature [2] must be a leaf feature.0337541408IDS_ERROR_281033Another application has exclusive access to the file [2]. Please shut down all other applications, then click Retry.0337541408IDS_ERROR_28011033Unknown Message -- Type [2]. No action is taken.0337541408IDS_ERROR_28021033No publisher is found for the event [2].0337541408IDS_ERROR_28031033Dialog View did not find a record for the dialog [2].0337541408IDS_ERROR_28041033On activation of the control [3] on dialog [2] CMsiDialog failed to evaluate the condition [3].0337541408IDS_ERROR_28061033The dialog [2] failed to evaluate the condition [3].0337541408IDS_ERROR_28071033The action [2] is not recognized.0337541408IDS_ERROR_28081033Default button is ill-defined on dialog [2].0337541408IDS_ERROR_28091033On the dialog [2] the next control pointers do not form a cycle. There is a pointer from [3] to [4], but there is no further pointer.0337541408IDS_ERROR_28101033On the dialog [2] the next control pointers do not form a cycle. There is a pointer from both [3] and [5] to [4].0337541408IDS_ERROR_28111033On dialog [2] control [3] has to take focus, but it is unable to do so.0337541408IDS_ERROR_28121033The event [2] is not recognized.0337541408IDS_ERROR_28131033The EndDialog event was called with the argument [2], but the dialog has a parent.0337541408IDS_ERROR_28141033On the dialog [2] the control [3] names a nonexistent control [4] as the next control.0337541408IDS_ERROR_28151033ControlCondition table has a row without condition for the dialog [2].0337541408IDS_ERROR_28161033The EventMapping table refers to an invalid control [4] on dialog [2] for the event [3].0337541408IDS_ERROR_28171033The event [2] failed to set the attribute for the control [4] on dialog [3].0337541408IDS_ERROR_28181033In the ControlEvent table EndDialog has an unrecognized argument [2].0337541408IDS_ERROR_28191033Control [3] on dialog [2] needs a property linked to it.0337541408IDS_ERROR_28201033Attempted to initialize an already initialized handler.0337541408IDS_ERROR_28211033Attempted to initialize an already initialized dialog: [2].0337541408IDS_ERROR_28221033No other method can be called on dialog [2] until all the controls are added.0337541408IDS_ERROR_28231033Attempted to initialize an already initialized control: [3] on dialog [2].0337541408IDS_ERROR_28241033The dialog attribute [3] needs a record of at least [2] field(s).0337541408IDS_ERROR_28251033The control attribute [3] needs a record of at least [2] field(s).0337541408IDS_ERROR_28261033Control [3] on dialog [2] extends beyond the boundaries of the dialog [4] by [5] pixels.0337541408IDS_ERROR_28271033The button [4] on the radio button group [3] on dialog [2] extends beyond the boundaries of the group [5] by [6] pixels.0337541408IDS_ERROR_28281033Tried to remove control [3] from dialog [2], but the control is not part of the dialog.0337541408IDS_ERROR_28291033Attempt to use an uninitialized dialog.0337541408IDS_ERROR_28301033Attempt to use an uninitialized control on dialog [2].0337541408IDS_ERROR_28311033The control [3] on dialog [2] does not support [5] the attribute [4].0337541408IDS_ERROR_28321033The dialog [2] does not support the attribute [3].0337541408IDS_ERROR_28331033Control [4] on dialog [3] ignored the message [2].0337541408IDS_ERROR_28341033The next pointers on the dialog [2] do not form a single loop.0337541408IDS_ERROR_28351033The control [2] was not found on dialog [3].0337541408IDS_ERROR_28361033The control [3] on the dialog [2] cannot take focus.0337541408IDS_ERROR_28371033The control [3] on dialog [2] wants the winproc to return [4].0337541408IDS_ERROR_28381033The item [2] in the selection table has itself as a parent.0337541408IDS_ERROR_28391033Setting the property [2] failed.0337541408IDS_ERROR_28401033Error dialog name mismatch.0337541408IDS_ERROR_28411033No OK button was found on the error dialog.0337541408IDS_ERROR_28421033No text field was found on the error dialog.0337541408IDS_ERROR_28431033The ErrorString attribute is not supported for standard dialogs.0337541408IDS_ERROR_28441033Cannot execute an error dialog if the Errorstring is not set.0337541408IDS_ERROR_28451033The total width of the buttons exceeds the size of the error dialog.0337541408IDS_ERROR_28461033SetFocus did not find the required control on the error dialog.0337541408IDS_ERROR_28471033The control [3] on dialog [2] has both the icon and the bitmap style set.0337541408IDS_ERROR_28481033Tried to set control [3] as the default button on dialog [2], but the control does not exist.0337541408IDS_ERROR_28491033The control [3] on dialog [2] is of a type, that cannot be integer valued.0337541408IDS_ERROR_28501033Unrecognized volume type.0337541408IDS_ERROR_28511033The data for the icon [2] is not valid.0337541408IDS_ERROR_28521033At least one control has to be added to dialog [2] before it is used.0337541408IDS_ERROR_28531033Dialog [2] is a modeless dialog. The execute method should not be called on it.0337541408IDS_ERROR_28541033On the dialog [2] the control [3] is designated as first active control, but there is no such control.0337541408IDS_ERROR_28551033The radio button group [3] on dialog [2] has fewer than 2 buttons.0337541408IDS_ERROR_28561033Creating a second copy of the dialog [2].0337541408IDS_ERROR_28571033The directory [2] is mentioned in the selection table but not found.0337541408IDS_ERROR_28581033The data for the bitmap [2] is not valid.0337541408IDS_ERROR_28591033Test error message.0337541408IDS_ERROR_28601033Cancel button is ill-defined on dialog [2].0337541408IDS_ERROR_28611033The next pointers for the radio buttons on dialog [2] control [3] do not form a cycle.0337541408IDS_ERROR_28621033The attributes for the control [3] on dialog [2] do not define a valid icon size. Setting the size to 16.0337541408IDS_ERROR_28631033The control [3] on dialog [2] needs the icon [4] in size [5]x[5], but that size is not available. Loading the first available size.0337541408IDS_ERROR_28641033The control [3] on dialog [2] received a browse event, but there is no configurable directory for the present selection. Likely cause: browse button is not authored correctly.0337541408IDS_ERROR_28651033Control [3] on billboard [2] extends beyond the boundaries of the billboard [4] by [5] pixels.0337541408IDS_ERROR_28661033The dialog [2] is not allowed to return the argument [3].0337541408IDS_ERROR_28671033The error dialog property is not set.0337541408IDS_ERROR_28681033The error dialog [2] does not have the error style bit set.0337541408IDS_ERROR_28691033The dialog [2] has the error style bit set, but is not an error dialog.0337541408IDS_ERROR_28701033The help string [4] for control [3] on dialog [2] does not contain the separator character.0337541408IDS_ERROR_28711033The [2] table is out of date: [3].0337541408IDS_ERROR_28721033The argument of the CheckPath control event on dialog [2] is invalid.0337541408IDS_ERROR_28731033On the dialog [2] the control [3] has an invalid string length limit: [4].0337541408IDS_ERROR_28741033Changing the text font to [2] failed.0337541408IDS_ERROR_28751033Changing the text color to [2] failed.0337541408IDS_ERROR_28761033The control [3] on dialog [2] had to truncate the string: [4].0337541408IDS_ERROR_28771033The binary data [2] was not found0337541408IDS_ERROR_28781033On the dialog [2] the control [3] has a possible value: [4]. This is an invalid or duplicate value.0337541408IDS_ERROR_28791033The control [3] on dialog [2] cannot parse the mask string: [4].0337541408IDS_ERROR_28801033Do not perform the remaining control events.0337541408IDS_ERROR_28811033CMsiHandler initialization failed.0337541408IDS_ERROR_28821033Dialog window class registration failed.0337541408IDS_ERROR_28831033CreateNewDialog failed for the dialog [2].0337541408IDS_ERROR_28841033Failed to create a window for the dialog [2].0337541408IDS_ERROR_28851033Failed to create the control [3] on the dialog [2].0337541408IDS_ERROR_28861033Creating the [2] table failed.0337541408IDS_ERROR_28871033Creating a cursor to the [2] table failed.0337541408IDS_ERROR_28881033Executing the [2] view failed.0337541408IDS_ERROR_28891033Creating the window for the control [3] on dialog [2] failed.0337541408IDS_ERROR_28901033The handler failed in creating an initialized dialog.0337541408IDS_ERROR_28911033Failed to destroy window for dialog [2].0337541408IDS_ERROR_28921033[2] is an integer only control, [3] is not a valid integer value.0337541408IDS_ERROR_28931033The control [3] on dialog [2] can accept property values that are at most [5] characters long. The value [4] exceeds this limit, and has been truncated.0337541408IDS_ERROR_28941033Loading RICHED20.DLL failed. GetLastError() returned: [2].0337541408IDS_ERROR_28951033Freeing RICHED20.DLL failed. GetLastError() returned: [2].0337541408IDS_ERROR_28961033Executing action [2] failed.0337541408IDS_ERROR_28971033Failed to create any [2] font on this system.0337541408IDS_ERROR_28981033For [2] textstyle, the system created a '[3]' font, in [4] character set.0337541408IDS_ERROR_28991033Failed to create [2] textstyle. GetLastError() returned: [3].0337541408IDS_ERROR_291033There is not enough disk space to install the file [2]. Free some disk space and click Retry, or click Cancel to exit.0337541408IDS_ERROR_29011033Invalid parameter to operation [2]: Parameter [3].0337541408IDS_ERROR_29021033Operation [2] called out of sequence.0337541408IDS_ERROR_29031033The file [2] is missing.0337541408IDS_ERROR_29041033Could not BindImage file [2].0337541408IDS_ERROR_29051033Could not read record from script file [2].0337541408IDS_ERROR_29061033Missing header in script file [2].0337541408IDS_ERROR_29071033Could not create secure security descriptor. Error: [2].0337541408IDS_ERROR_29081033Could not register component [2].0337541408IDS_ERROR_29091033Could not unregister component [2].0337541408IDS_ERROR_29101033Could not determine user's security ID.0337541408IDS_ERROR_29111033Could not remove the folder [2].0337541408IDS_ERROR_29121033Could not schedule file [2] for removal on restart.0337541408IDS_ERROR_29191033No cabinet specified for compressed file: [2].0337541408IDS_ERROR_29201033Source directory not specified for file [2].0337541408IDS_ERROR_29241033Script [2] version unsupported. Script version: [3], minimum version: [4], maximum version: [5].0337541408IDS_ERROR_29271033ShellFolder id [2] is invalid.0337541408IDS_ERROR_29281033Exceeded maximum number of sources. Skipping source '[2]'.0337541408IDS_ERROR_29291033Could not determine publishing root. Error: [2].0337541408IDS_ERROR_29321033Could not create file [2] from script data. Error: [3].0337541408IDS_ERROR_29331033Could not initialize rollback script [2].0337541408IDS_ERROR_29341033Could not secure transform [2]. Error [3].0337541408IDS_ERROR_29351033Could not unsecure transform [2]. Error [3].0337541408IDS_ERROR_29361033Could not find transform [2].0337541408IDS_ERROR_29371033Windows Installer cannot install a system file protection catalog. Catalog: [2], Error: [3].0337541408IDS_ERROR_29381033Windows Installer cannot retrieve a system file protection catalog from the cache. Catalog: [2], Error: [3].0337541408IDS_ERROR_29391033Windows Installer cannot delete a system file protection catalog from the cache. Catalog: [2], Error: [3].0337541408IDS_ERROR_29401033Directory Manager not supplied for source resolution.0337541408IDS_ERROR_29411033Unable to compute the CRC for file [2].0337541408IDS_ERROR_29421033BindImage action has not been executed on [2] file.0337541408IDS_ERROR_29431033This version of Windows does not support deploying 64-bit packages. The script [2] is for a 64-bit package.0337541408IDS_ERROR_29441033GetProductAssignmentType failed.0337541408IDS_ERROR_29451033Installation of ComPlus App [2] failed with error [3].0337541408IDS_ERROR_31033Info [1]. 0337541408IDS_ERROR_301033Source file not found: [2]. Verify that the file exists and that you can access it.0337541408IDS_ERROR_30011033The patches in this list contain incorrect sequencing information: [2][3][4][5][6][7][8][9][10][11][12][13][14][15][16].0337541408IDS_ERROR_30021033Patch [2] contains invalid sequencing information. 0337541408IDS_ERROR_311033Error reading from file: [3]. {{ System error [2].}} Verify that the file exists and that you can access it.0337541408IDS_ERROR_321033Error writing to file: [3]. {{ System error [2].}} Verify that you have access to that directory.0337541408IDS_ERROR_331033Source file not found{{(cabinet)}}: [2]. Verify that the file exists and that you can access it.0337541408IDS_ERROR_341033Cannot create the directory [2]. A file with this name already exists. Please rename or remove the file and click Retry, or click Cancel to exit.0337541408IDS_ERROR_351033The volume [2] is currently unavailable. Please select another.0337541408IDS_ERROR_361033The specified path [2] is unavailable.0337541408IDS_ERROR_371033Unable to write to the specified folder [2].0337541408IDS_ERROR_381033A network error occurred while attempting to read from the file [2]0337541408IDS_ERROR_391033An error occurred while attempting to create the directory [2]0337541408IDS_ERROR_41033Internal Error [1]. [2]{, [3]}{, [4]}0337541408IDS_ERROR_401033A network error occurred while attempting to create the directory [2]0337541408IDS_ERROR_411033A network error occurred while attempting to open the source file cabinet [2].0337541408IDS_ERROR_421033The specified path is too long [2].0337541408IDS_ERROR_431033The Installer has insufficient privileges to modify the file [2].0337541408IDS_ERROR_441033A portion of the path [2] exceeds the length allowed by the system.0337541408IDS_ERROR_451033The path [2] contains words that are not valid in folders.0337541408IDS_ERROR_461033The path [2] contains an invalid character.0337541408IDS_ERROR_471033[2] is not a valid short file name.0337541408IDS_ERROR_481033Error getting file security: [3] GetLastError: [2]0337541408IDS_ERROR_491033Invalid Drive: [2]0337541408IDS_ERROR_51033{{Disk full: }}0337541408IDS_ERROR_501033Could not create key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0337541408IDS_ERROR_511033Could not open key: [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0337541408IDS_ERROR_521033Could not delete value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel.0337541408IDS_ERROR_531033Could not delete key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0337541408IDS_ERROR_541033Could not read value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel.0337541408IDS_ERROR_551033Could not write value [2] to key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel.0337541408IDS_ERROR_561033Could not get value names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0337541408IDS_ERROR_571033Could not get sub key names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0337541408IDS_ERROR_581033Could not read security information for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0337541408IDS_ERROR_591033Could not increase the available registry space. [2] KB of free registry space is required for the installation of this application.0337541408IDS_ERROR_61033Action [Time]: [1]. [2]0337541408IDS_ERROR_601033Another installation is in progress. You must complete that installation before continuing this one.0337541408IDS_ERROR_611033Error accessing secured data. Please make sure the Windows Installer is configured properly and try the installation again.0337541408IDS_ERROR_621033User [2] has previously initiated an installation for product [3]. That user will need to run that installation again before using that product. Your current installation will now continue.0337541408IDS_ERROR_631033User [2] has previously initiated an installation for product [3]. That user will need to run that installation again before using that product.0337541408IDS_ERROR_641033Out of disk space -- Volume: '[2]'; required space: [3] KB; available space: [4] KB. Free some disk space and retry.0337541408IDS_ERROR_651033Are you sure you want to cancel?0337541408IDS_ERROR_661033The file [2][3] is being held in use{ by the following process: Name: [4], ID: [5], Window Title: [6]}. Close that application and retry.0337541408IDS_ERROR_671033The product [2] is already installed, preventing the installation of this product. The two products are incompatible.0337541408IDS_ERROR_681033Out of disk space -- Volume: [2]; required space: [3] KB; available space: [4] KB. If rollback is disabled, enough space is available. Click Cancel to quit, Retry to check available disk space again, or Ignore to continue without rollback.0337541408IDS_ERROR_691033Could not access network location [2].0337541408IDS_ERROR_71033[ProductName]0337541408IDS_ERROR_701033The following applications should be closed before continuing the installation:0337541408IDS_ERROR_711033Could not find any previously installed compliant products on the machine for installing this product.0337541408IDS_ERROR_721033The key [2] is not valid. Verify that you entered the correct key.0337541408IDS_ERROR_731033The installer must restart your system before configuration of [2] can continue. Click Yes to restart now or No if you plan to restart later.0337541408IDS_ERROR_741033You must restart your system for the configuration changes made to [2] to take effect. Click Yes to restart now or No if you plan to restart later.0337541408IDS_ERROR_751033An installation for [2] is currently suspended. You must undo the changes made by that installation to continue. Do you want to undo those changes?0337541408IDS_ERROR_761033A previous installation for this product is in progress. You must undo the changes made by that installation to continue. Do you want to undo those changes?0337541408IDS_ERROR_771033No valid source could be found for product [2]. The Windows Installer cannot continue.0337541408IDS_ERROR_781033Installation operation completed successfully.0337541408IDS_ERROR_791033Installation operation failed.0337541408IDS_ERROR_81033{[2]}{, [3]}{, [4]}0337541408IDS_ERROR_801033Product: [2] -- [3]0337541408IDS_ERROR_811033You may either restore your computer to its previous state or continue the installation later. Would you like to restore?0337541408IDS_ERROR_821033An error occurred while writing installation information to disk. Check to make sure enough disk space is available, and click Retry, or Cancel to end the installation.0337541408IDS_ERROR_831033One or more of the files required to restore your computer to its previous state could not be found. Restoration will not be possible.0337541408IDS_ERROR_841033The path [2] is not valid. Please specify a valid path.0337541408IDS_ERROR_851033Out of memory. Shut down other applications before retrying.0337541408IDS_ERROR_861033There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to go back to the previously selected volume.0337541408IDS_ERROR_871033There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to return to the browse dialog and select a different volume.0337541408IDS_ERROR_881033The folder [2] does not exist. Please enter a path to an existing folder.0337541408IDS_ERROR_891033You have insufficient privileges to read this folder.0337541408IDS_ERROR_91033Message type: [1], Argument: [2]0337541408IDS_ERROR_901033A valid destination folder for the installation could not be determined.0337541408IDS_ERROR_911033Error attempting to read from the source installation database: [2].0337541408IDS_ERROR_921033Scheduling reboot operation: Renaming file [2] to [3]. Must reboot to complete operation.0337541408IDS_ERROR_931033Scheduling reboot operation: Deleting file [2]. Must reboot to complete operation.0337541408IDS_ERROR_941033Module [2] failed to register. HRESULT [3]. Contact your support personnel.0337541408IDS_ERROR_951033Module [2] failed to unregister. HRESULT [3]. Contact your support personnel.0337541408IDS_ERROR_961033Failed to cache package [2]. Error: [3]. Contact your support personnel.0337541408IDS_ERROR_971033Could not register font [2]. Verify that you have sufficient permissions to install fonts, and that the system supports this font.0337541408IDS_ERROR_981033Could not unregister font [2]. Verify that you have sufficient permissions to remove fonts.0337541408IDS_ERROR_991033Could not create shortcut [2]. Verify that the destination folder exists and that you can access it.0337541408IDS_INSTALLDIR1033[INSTALLDIR]0337541408IDS_INSTALLSHIELD1033InstallShield0337541408IDS_INSTALLSHIELD_FORMATTED1033{&MSSWhiteSerif8}InstallShield0337541408IDS_ISSCRIPT_VERSION_MISSING1033The InstallScript engine is missing from this machine. If available, please run ISScript.msi, or contact your support personnel for further assistance.0337541408IDS_ISSCRIPT_VERSION_OLD1033The InstallScript engine on this machine is older than the version required to run this setup. If available, please install the latest version of ISScript.msi, or contact your support personnel for further assistance.0337541408IDS_NEXT1033&Next >0337541408IDS_OK1033OK0337541408IDS_PREREQUISITE_SETUP_BROWSE1033Open [ProductName]'s original [SETUPEXENAME]0337541408IDS_PREREQUISITE_SETUP_INVALID1033This executable file does not appear to be the original executable file for [ProductName]. Without using the original [SETUPEXENAME] to install additional dependencies, [ProductName] may not work correctly. Would you like to find the original [SETUPEXENAME]?0337541408IDS_PREREQUISITE_SETUP_SEARCH1033This installation may require additional dependencies. Without its dependencies, [ProductName] may not work correctly. Would you like to find the original [SETUPEXENAME]?0337541408IDS_PREVENT_DOWNGRADE_EXIT1033A newer version of this application is already installed on this computer. If you wish to install this version, please uninstall the newer version first. Click OK to exit the wizard.0337541408IDS_PRINT_BUTTON1033&Print0337541408IDS_PRODUCTNAME_INSTALLSHIELD1033[ProductName] - InstallShield Wizard0337541408IDS_PROGMSG_IIS_CREATEAPPPOOL1033Creating application pool %s0337541408IDS_PROGMSG_IIS_CREATEAPPPOOLS1033Creating application Pools...0337541408IDS_PROGMSG_IIS_CREATEVROOT1033Creating IIS virtual directory %s0337541408IDS_PROGMSG_IIS_CREATEVROOTS1033Creating IIS virtual directories...0337541408IDS_PROGMSG_IIS_CREATEWEBSERVICEEXTENSION1033Creating web service extension0337541408IDS_PROGMSG_IIS_CREATEWEBSERVICEEXTENSIONS1033Creating web service extensions...0337541408IDS_PROGMSG_IIS_CREATEWEBSITE1033Creating IIS website %s0337541408IDS_PROGMSG_IIS_CREATEWEBSITES1033Creating IIS websites...0337541408IDS_PROGMSG_IIS_EXTRACT1033Extracting information for IIS virtual directories...0337541408IDS_PROGMSG_IIS_EXTRACTDONE1033Extracted information for IIS virtual directories...0337541408IDS_PROGMSG_IIS_REMOVEAPPPOOL1033Removing application pool0337541408IDS_PROGMSG_IIS_REMOVEAPPPOOLS1033Removing application pools...0337541408IDS_PROGMSG_IIS_REMOVESITE1033Removing web site at port %d0337541408IDS_PROGMSG_IIS_REMOVEVROOT1033Removing IIS virtual directory %s0337541408IDS_PROGMSG_IIS_REMOVEVROOTS1033Removing IIS virtual directories...0337541408IDS_PROGMSG_IIS_REMOVEWEBSERVICEEXTENSION1033Removing web service extension0337541408IDS_PROGMSG_IIS_REMOVEWEBSERVICEEXTENSIONS1033Removing web service extensions...0337541408IDS_PROGMSG_IIS_REMOVEWEBSITES1033Removing IIS websites...0337541408IDS_PROGMSG_IIS_ROLLBACKAPPPOOLS1033Rolling back application pools...0337541408IDS_PROGMSG_IIS_ROLLBACKVROOTS1033Rolling back virtual directory and web site changes...0337541408IDS_PROGMSG_IIS_ROLLBACKWEBSERVICEEXTENSIONS1033Rolling back web service extensions...0337541408IDS_PROGMSG_TEXTFILECHANGS_REPLACE1033Replacing %s with %s in %s...0337541408IDS_PROGMSG_XML_COSTING1033Costing XML files...0337541408IDS_PROGMSG_XML_CREATE_FILE1033Creating XML file %s...0337541408IDS_PROGMSG_XML_FILES1033Performing XML file changes...0337541408IDS_PROGMSG_XML_REMOVE_FILE1033Removing XML file %s...0337541408IDS_PROGMSG_XML_ROLLBACK_FILES1033Rolling back XML file changes...0337541408IDS_PROGMSG_XML_UPDATE_FILE1033Updating XML file %s...0337541408IDS_SETUPEXE_EXPIRE_MSG1033This setup works until %s. The setup will now exit.0337541408IDS_SQLBROWSE_INTRO1033From the list of servers below, select the database server you would like to target.0337541408IDS_SQLBROWSE_INTRO_DB1033From the list of catalog names below, select the database catalog you would like to target.0337541408IDS_SQLBROWSE_INTRO_TEMPLATE1033[IS_SQLBROWSE_INTRO]0337541408IDS_SQLLOGIN_BROWSE1033B&rowse...0337541408IDS_SQLLOGIN_BROWSE_DB1033Br&owse...0337541408IDS_SQLLOGIN_CATALOG1033&Name of database catalog:0337541408IDS_SQLLOGIN_CONNECT1033Connect using:0337541408IDS_SQLLOGIN_DESC1033Select database server and authentication method0337541408IDS_SQLLOGIN_ID1033&Login ID:0337541408IDS_SQLLOGIN_INTRO1033Select the database server to install to from the list below or click Browse to see a list of all database servers. You can also specify the way to authenticate your login using your current credentials or a SQL Login ID and Password.0337541408IDS_SQLLOGIN_PSWD1033&Password:0337541408IDS_SQLLOGIN_SERVER1033&Database Server:0337541408IDS_SQLLOGIN_SERVER21033&Database server that you are installing to:0337541408IDS_SQLLOGIN_SQL1033S&erver authentication using the Login ID and password below0337541408IDS_SQLLOGIN_TITLE1033{&MSSansBold8}Database Server0337541408IDS_SQLLOGIN_WIN1033&Windows authentication credentials of current user0337541408IDS_SQLSCRIPT_INSTALLING1033Executing SQL Install Script...0337541408IDS_SQLSCRIPT_UNINSTALLING1033Executing SQL Uninstall Script...0337541408IDS_STANDARD_USE_SETUPEXE1033This installation cannot be run by directly launching the MSI package. You must run setup.exe.0337541408IDS_SetupTips_Advertise1033Will be installed on first use. (Available only if the feature supports this option.)0337541408IDS_SetupTips_AllInstalledLocal1033Will be completely installed to the local hard drive.0337541408IDS_SetupTips_CustomSetup1033{&MSSansBold8}Custom Setup Tips0337541408IDS_SetupTips_CustomSetupDescription1033Custom Setup allows you to selectively install program features.0337541408IDS_SetupTips_IconInstallState1033The icon next to the feature name indicates the install state of the feature. Click the icon to drop down the install state menu for each feature.0337541408IDS_SetupTips_InstallState1033This install state means the feature...0337541408IDS_SetupTips_Network1033Will be installed to run from the network. (Available only if the feature supports this option.)0337541408IDS_SetupTips_OK1033OK0337541408IDS_SetupTips_SubFeaturesInstalledLocal1033Will have some subfeatures installed to the local hard drive. (Available only if the feature has subfeatures.)0337541408IDS_SetupTips_WillNotBeInstalled1033Will not be installed.0337541408IDS_UITEXT_Available1033Available0337541408IDS_UITEXT_Bytes1033bytes0337541408IDS_UITEXT_CompilingFeaturesCost1033Compiling cost for this feature...0337541408IDS_UITEXT_Differences1033Differences0337541408IDS_UITEXT_DiskSize1033Disk Size0337541408IDS_UITEXT_FeatureCompletelyRemoved1033This feature will be completely removed.0337541408IDS_UITEXT_FeatureContinueNetwork1033This feature will continue to be run from the network0337541408IDS_UITEXT_FeatureFreeSpace1033This feature frees up [1] on your hard drive.0337541408IDS_UITEXT_FeatureInstalledCD1033This feature, and all subfeatures, will be installed to run from the CD.0337541408IDS_UITEXT_FeatureInstalledCD21033This feature will be installed to run from CD.0337541408IDS_UITEXT_FeatureInstalledLocal1033This feature, and all subfeatures, will be installed on local hard drive.0337541408IDS_UITEXT_FeatureInstalledLocal21033This feature will be installed on local hard drive.0337541408IDS_UITEXT_FeatureInstalledNetwork1033This feature, and all subfeatures, will be installed to run from the network.0337541408IDS_UITEXT_FeatureInstalledNetwork21033This feature will be installed to run from network.0337541408IDS_UITEXT_FeatureInstalledRequired1033Will be installed when required.0337541408IDS_UITEXT_FeatureInstalledWhenRequired1033This feature will be set to be installed when required.0337541408IDS_UITEXT_FeatureInstalledWhenRequired21033This feature will be installed when required.0337541408IDS_UITEXT_FeatureLocal1033This feature will be installed on the local hard drive.0337541408IDS_UITEXT_FeatureLocal21033This feature will be installed on your local hard drive.0337541408IDS_UITEXT_FeatureNetwork1033This feature will be installed to run from the network.0337541408IDS_UITEXT_FeatureNetwork21033This feature will be available to run from the network.0337541408IDS_UITEXT_FeatureNotAvailable1033This feature will not be available.0337541408IDS_UITEXT_FeatureOnCD1033This feature will be installed to run from CD.0337541408IDS_UITEXT_FeatureOnCD21033This feature will be available to run from CD.0337541408IDS_UITEXT_FeatureRemainLocal1033This feature will remain on your local hard drive.0337541408IDS_UITEXT_FeatureRemoveNetwork1033This feature will be removed from your local hard drive, but will be still available to run from the network.0337541408IDS_UITEXT_FeatureRemovedCD1033This feature will be removed from your local hard drive but will still be available to run from CD.0337541408IDS_UITEXT_FeatureRemovedUnlessRequired1033This feature will be removed from your local hard drive but will be set to be installed when required.0337541408IDS_UITEXT_FeatureRequiredSpace1033This feature requires [1] on your hard drive.0337541408IDS_UITEXT_FeatureRunFromCD1033This feature will continue to be run from the CD0337541408IDS_UITEXT_FeatureSpaceFree1033This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.0337541408IDS_UITEXT_FeatureSpaceFree21033This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.0337541408IDS_UITEXT_FeatureSpaceFree31033This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.0337541408IDS_UITEXT_FeatureSpaceFree41033This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.0337541408IDS_UITEXT_FeatureUnavailable1033This feature will become unavailable.0337541408IDS_UITEXT_FeatureUninstallNoNetwork1033This feature will be uninstalled completely, and you won't be able to run it from the network.0337541408IDS_UITEXT_FeatureWasCD1033This feature was run from the CD but will be set to be installed when required.0337541408IDS_UITEXT_FeatureWasCDLocal1033This feature was run from the CD but will be installed on the local hard drive.0337541408IDS_UITEXT_FeatureWasOnNetworkInstalled1033This feature was run from the network but will be installed when required.0337541408IDS_UITEXT_FeatureWasOnNetworkLocal1033This feature was run from the network but will be installed on the local hard drive.0337541408IDS_UITEXT_FeatureWillBeUninstalled1033This feature will be uninstalled completely, and you won't be able to run it from CD.0337541408IDS_UITEXT_Folder1033Fldr|New Folder0337541408IDS_UITEXT_GB1033GB0337541408IDS_UITEXT_KB1033KB0337541408IDS_UITEXT_MB1033MB0337541408IDS_UITEXT_Required1033Required0337541408IDS_UITEXT_TimeRemaining1033Time remaining: {[1] min }{[2] sec}0337541408IDS_UITEXT_Volume1033Volume0337541408IDS__AgreeToLicense_01033I &do not accept the terms in the license agreement0337541408IDS__AgreeToLicense_11033I &accept the terms in the license agreement0337541408IDS__DatabaseFolder_ChangeFolder1033Click Next to install to this folder, or click Change to install to a different folder.0337541408IDS__DatabaseFolder_DatabaseDir1033[DATABASEDIR]0337541408IDS__DatabaseFolder_DatabaseFolder1033{&MSSansBold8}Database Folder0337541408IDS__DestinationFolder_Change1033&Change...0337541408IDS__DestinationFolder_ChangeFolder1033Click Next to install to this folder, or click Change to install to a different folder.0337541408IDS__DestinationFolder_DestinationFolder1033{&MSSansBold8}Destination Folder0337541408IDS__DestinationFolder_InstallTo1033Install [ProductName] to:0337541408IDS__DisplayName_Custom1033Custom0337541408IDS__DisplayName_Minimal1033Minimal0337541408IDS__DisplayName_Typical1033Typical0337541408IDS__IsAdminInstallBrowse_1110330337541408IDS__IsAdminInstallBrowse_410330337541408IDS__IsAdminInstallBrowse_810330337541408IDS__IsAdminInstallBrowse_BrowseDestination1033Browse to the destination folder.0337541408IDS__IsAdminInstallBrowse_ChangeDestination1033{&MSSansBold8}Change Current Destination Folder0337541408IDS__IsAdminInstallBrowse_CreateFolder1033Create new folder|0337541408IDS__IsAdminInstallBrowse_FolderName1033&Folder name:0337541408IDS__IsAdminInstallBrowse_LookIn1033&Look in:0337541408IDS__IsAdminInstallBrowse_UpOneLevel1033Up one level|0337541408IDS__IsAdminInstallPointWelcome_ServerImage1033The InstallShield(R) Wizard will create a server image of [ProductName] at a specified network location. To continue, click Next.0337541408IDS__IsAdminInstallPointWelcome_Wizard1033{&TahomaBold10}Welcome to the InstallShield Wizard for [ProductName]0337541408IDS__IsAdminInstallPoint_Change1033&Change...0337541408IDS__IsAdminInstallPoint_EnterNetworkLocation1033Enter the network location or click Change to browse to a location. Click Install to create a server image of [ProductName] at the specified network location or click Cancel to exit the wizard.0337541408IDS__IsAdminInstallPoint_Install1033&Install0337541408IDS__IsAdminInstallPoint_NetworkLocation1033&Network location:0337541408IDS__IsAdminInstallPoint_NetworkLocationFormatted1033{&MSSansBold8}Network Location0337541408IDS__IsAdminInstallPoint_SpecifyNetworkLocation1033Specify a network location for the server image of the product.0337541408IDS__IsBrowseButton1033&Browse...0337541408IDS__IsBrowseFolderDlg_1110330337541408IDS__IsBrowseFolderDlg_410330337541408IDS__IsBrowseFolderDlg_810330337541408IDS__IsBrowseFolderDlg_BrowseDestFolder1033Browse to the destination folder.0337541408IDS__IsBrowseFolderDlg_ChangeCurrentFolder1033{&MSSansBold8}Change Current Destination Folder0337541408IDS__IsBrowseFolderDlg_CreateFolder1033Create New Folder|0337541408IDS__IsBrowseFolderDlg_FolderName1033&Folder name:0337541408IDS__IsBrowseFolderDlg_LookIn1033&Look in:0337541408IDS__IsBrowseFolderDlg_OK1033OK0337541408IDS__IsBrowseFolderDlg_UpOneLevel1033Up One Level|0337541408IDS__IsBrowseForAccount1033Browse for a User Account0337541408IDS__IsBrowseGroup1033Select a Group0337541408IDS__IsBrowseUsernameTitle1033Select a User Name0337541408IDS__IsCancelDlg_ConfirmCancel1033Are you sure you want to cancel [ProductName] installation?0337541408IDS__IsCancelDlg_No1033&No0337541408IDS__IsCancelDlg_Yes1033&Yes0337541408IDS__IsConfirmPassword1033Con&firm password:0337541408IDS__IsCreateNewUserTitle1033New User Information0337541408IDS__IsCreateUserBrowse1033N&ew User Information...0337541408IDS__IsCustomSelectionDlg_Change1033&Change...0337541408IDS__IsCustomSelectionDlg_ClickFeatureIcon1033Click on an icon in the list below to change how a feature is installed.0337541408IDS__IsCustomSelectionDlg_CustomSetup1033{&MSSansBold8}Custom Setup0337541408IDS__IsCustomSelectionDlg_FeatureDescription1033Feature Description0337541408IDS__IsCustomSelectionDlg_FeaturePath1033<selected feature path>0337541408IDS__IsCustomSelectionDlg_FeatureSize1033Feature size0337541408IDS__IsCustomSelectionDlg_Help1033&Help0337541408IDS__IsCustomSelectionDlg_InstallTo1033Install to:0337541408IDS__IsCustomSelectionDlg_MultilineDescription1033Multiline description of the currently selected item0337541408IDS__IsCustomSelectionDlg_SelectFeatures1033Select the program features you want installed.0337541408IDS__IsCustomSelectionDlg_Space1033&Space0337541408IDS__IsDiskSpaceDlg_DiskSpace1033Disk space required for the installation exceeds available disk space.0337541408IDS__IsDiskSpaceDlg_HighlightedVolumes1033The highlighted volumes do not have enough disk space available for the currently selected features. You can remove files from the highlighted volumes, choose to install fewer features onto local drives, or select different destination drives.0337541408IDS__IsDiskSpaceDlg_Numbers1033{120}{70}{70}{70}{70}0337541408IDS__IsDiskSpaceDlg_OK1033OK0337541408IDS__IsDiskSpaceDlg_OutOfDiskSpace1033{&MSSansBold8}Out of Disk Space0337541408IDS__IsDomainOrServer1033&Domain or server:0337541408IDS__IsErrorDlg_Abort1033&Abort0337541408IDS__IsErrorDlg_ErrorText1033<error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here>0337541408IDS__IsErrorDlg_Ignore1033&Ignore0337541408IDS__IsErrorDlg_InstallerInfo1033[ProductName] Installer Information0337541408IDS__IsErrorDlg_NO1033&No0337541408IDS__IsErrorDlg_OK1033&OK0337541408IDS__IsErrorDlg_Retry1033&Retry0337541408IDS__IsErrorDlg_Yes1033&Yes0337541408IDS__IsExitDialog_Finish1033&Finish0337541408IDS__IsExitDialog_InstallSuccess1033The InstallShield Wizard has successfully installed [ProductName]. Click Finish to exit the wizard.0337541408IDS__IsExitDialog_LaunchProgram1033Launch the program0337541408IDS__IsExitDialog_ShowReadMe1033Show the readme file0337541408IDS__IsExitDialog_UninstallSuccess1033The InstallShield Wizard has successfully uninstalled [ProductName]. Click Finish to exit the wizard.0337541408IDS__IsExitDialog_Update_InternetConnection1033Your Internet connection can be used to make sure that you have the latest updates.0337541408IDS__IsExitDialog_Update_PossibleUpdates1033Some program files might have been updated since you purchased your copy of [ProductName].0337541408IDS__IsExitDialog_Update_SetupFinished1033Setup has finished installing [ProductName].0337541408IDS__IsExitDialog_Update_YesCheckForUpdates1033&Yes, check for program updates (Recommended) after the setup completes.0337541408IDS__IsExitDialog_WizardCompleted1033{&TahomaBold10}InstallShield Wizard Completed0337541408IDS__IsFatalError_ClickFinish1033Click Finish to exit the wizard.0337541408IDS__IsFatalError_Finish1033&Finish0337541408IDS__IsFatalError_KeepOrRestore1033You can either keep any existing installed elements on your system to continue this installation at a later time or you can restore your system to its original state prior to the installation.0337541408IDS__IsFatalError_NotModified1033Your system has not been modified. To complete installation at another time, please run setup again.0337541408IDS__IsFatalError_RestoreOrContinueLater1033Click Restore or Continue Later to exit the wizard.0337541408IDS__IsFatalError_WizardCompleted1033{&TahomaBold10}InstallShield Wizard Completed0337541408IDS__IsFatalError_WizardInterrupted1033The wizard was interrupted before [ProductName] could be completely installed.0337541408IDS__IsFeatureDetailsDlg_DiskSpaceRequirements1033{&MSSansBold8}Disk Space Requirements0337541408IDS__IsFeatureDetailsDlg_Numbers1033{120}{70}{70}{70}{70}0337541408IDS__IsFeatureDetailsDlg_OK1033OK0337541408IDS__IsFeatureDetailsDlg_SpaceRequired1033The disk space required for the installation of the selected features.0337541408IDS__IsFeatureDetailsDlg_VolumesTooSmall1033The highlighted volumes do not have enough disk space available for the currently selected features. You can remove files from the highlighted volumes, choose to install fewer features onto local drives, or select different destination drives.0337541408IDS__IsFilesInUse_ApplicationsUsingFiles1033The following applications are using files that need to be updated by this setup. Close these applications and click Retry to continue.0337541408IDS__IsFilesInUse_Exit1033&Exit0337541408IDS__IsFilesInUse_FilesInUse1033{&MSSansBold8}Files in Use0337541408IDS__IsFilesInUse_FilesInUseMessage1033Some files that need to be updated are currently in use.0337541408IDS__IsFilesInUse_Ignore1033&Ignore0337541408IDS__IsFilesInUse_Retry1033&Retry0337541408IDS__IsGroup1033&Group:0337541408IDS__IsGroupLabel1033Gr&oup:0337541408IDS__IsInitDlg_110330337541408IDS__IsInitDlg_210330337541408IDS__IsInitDlg_PreparingWizard1033[ProductName] Setup is preparing the InstallShield Wizard which will guide you through the program setup process. Please wait.0337541408IDS__IsInitDlg_WelcomeWizard1033{&TahomaBold10}Welcome to the InstallShield Wizard for [ProductName]0337541408IDS__IsLicenseDlg_LicenseAgreement1033{&MSSansBold8}License Agreement0337541408IDS__IsLicenseDlg_ReadLicenseAgreement1033Please read the following license agreement carefully.0337541408IDS__IsLogonInfoDescription1033Specify the user name and password of the user account that will logon to use this application. The user account must be in the form DOMAIN\Username.0337541408IDS__IsLogonInfoTitle1033{&MSSansBold8}Logon Information0337541408IDS__IsLogonInfoTitleDescription1033Specify a user name and password0337541408IDS__IsLogonNewUserDescription1033Select the button below to specify information about a new user that will be created during the installation.0337541408IDS__IsMaintenanceDlg_ChangeFeatures1033Change which program features are installed. This option displays the Custom Selection dialog in which you can change the way features are installed.0337541408IDS__IsMaintenanceDlg_MaitenanceOptions1033Modify, repair, or remove the program.0337541408IDS__IsMaintenanceDlg_Modify1033{&MSSansBold8}&Modify0337541408IDS__IsMaintenanceDlg_ProgramMaintenance1033{&MSSansBold8}Program Maintenance0337541408IDS__IsMaintenanceDlg_Remove1033{&MSSansBold8}&Remove0337541408IDS__IsMaintenanceDlg_RemoveProductName1033Remove [ProductName] from your computer.0337541408IDS__IsMaintenanceDlg_Repair1033{&MSSansBold8}Re&pair0337541408IDS__IsMaintenanceDlg_RepairMessage1033Repair installation errors in the program. This option fixes missing or corrupt files, shortcuts, and registry entries.0337541408IDS__IsMaintenanceWelcome_MaintenanceOptionsDescription1033The InstallShield(R) Wizard will allow you to modify, repair, or remove [ProductName]. To continue, click Next.0337541408IDS__IsMaintenanceWelcome_WizardWelcome1033{&TahomaBold10}Welcome to the InstallShield Wizard for [ProductName]0337541408IDS__IsMsiRMFilesInUse_ApplicationsUsingFiles1033The following applications are using files that need to be updated by this setup.0337541408IDS__IsMsiRMFilesInUse_CloseRestart1033Automatically close and attempt to restart applications.0337541408IDS__IsMsiRMFilesInUse_RebootAfter1033Do not close applications. (A reboot will be required.)0337541408IDS__IsPatchDlg_PatchClickUpdate1033The InstallShield(R) Wizard will install the Patch for [ProductName] on your computer. To continue, click Update.0337541408IDS__IsPatchDlg_PatchWizard1033[ProductName] Patch - InstallShield Wizard0337541408IDS__IsPatchDlg_Update1033&Update >0337541408IDS__IsPatchDlg_WelcomePatchWizard1033{&TahomaBold10}Welcome to the Patch for [ProductName]0337541408IDS__IsProgressDlg_210330337541408IDS__IsProgressDlg_Hidden1033(Hidden for now)0337541408IDS__IsProgressDlg_HiddenTimeRemaining1033)Hidden for now)Estimated time remaining:0337541408IDS__IsProgressDlg_InstallingProductName1033{&MSSansBold8}Installing [ProductName]0337541408IDS__IsProgressDlg_ProgressDone1033Progress done0337541408IDS__IsProgressDlg_SecHidden1033(Hidden for now)Sec.0337541408IDS__IsProgressDlg_Status1033Status:0337541408IDS__IsProgressDlg_Uninstalling1033{&MSSansBold8}Uninstalling [ProductName]0337541408IDS__IsProgressDlg_UninstallingFeatures1033The program features you selected are being uninstalled.0337541408IDS__IsProgressDlg_UninstallingFeatures21033The program features you selected are being installed.0337541408IDS__IsProgressDlg_WaitUninstall1033Please wait while the InstallShield Wizard uninstalls [ProductName]. This may take several minutes.0337541408IDS__IsProgressDlg_WaitUninstall21033Please wait while the InstallShield Wizard installs [ProductName]. This may take several minutes.0337541408IDS__IsReadmeDlg_Cancel1033&Cancel0337541408IDS__IsReadmeDlg_PleaseReadInfo1033Please read the following readme information carefully.0337541408IDS__IsReadmeDlg_ReadMeInfo1033{&MSSansBold8}Readme Information0337541408IDS__IsRegisterUserDlg_1610330337541408IDS__IsRegisterUserDlg_Anyone1033&Anyone who uses this computer (all users)0337541408IDS__IsRegisterUserDlg_CustomerInformation1033{&MSSansBold8}Customer Information0337541408IDS__IsRegisterUserDlg_InstallFor1033Install this application for:0337541408IDS__IsRegisterUserDlg_OnlyMe1033Only for &me ([USERNAME])0337541408IDS__IsRegisterUserDlg_Organization1033&Organization:0337541408IDS__IsRegisterUserDlg_PleaseEnterInfo1033Please enter your information.0337541408IDS__IsRegisterUserDlg_SerialNumber1033&Serial Number:0337541408IDS__IsRegisterUserDlg_Tahoma501033{\Tahoma8}{50}0337541408IDS__IsRegisterUserDlg_Tahoma801033{\Tahoma8}{80}0337541408IDS__IsRegisterUserDlg_UserName1033&User Name:0337541408IDS__IsResumeDlg_ResumeSuspended1033The InstallShield(R) Wizard will complete the suspended installation of [ProductName] on your computer. To continue, click Next.0337541408IDS__IsResumeDlg_Resuming1033{&TahomaBold10}Resuming the InstallShield Wizard for [ProductName]0337541408IDS__IsResumeDlg_WizardResume1033The InstallShield(R) Wizard will complete the installation of [ProductName] on your computer. To continue, click Next.0337541408IDS__IsSelectDomainOrServer1033Select a Domain or Server0337541408IDS__IsSelectDomainUserInstructions1033Use the browse buttons to select a domain\server and a user name.0337541408IDS__IsSetupComplete_ShowMsiLog1033Show the Windows Installer log0337541408IDS__IsSetupTypeMinDlg_1310330337541408IDS__IsSetupTypeMinDlg_AllFeatures1033All program features will be installed. (Requires the most disk space.)0337541408IDS__IsSetupTypeMinDlg_ChooseFeatures1033Choose which program features you want installed and where they will be installed. Recommended for advanced users.0337541408IDS__IsSetupTypeMinDlg_ChooseSetupType1033Choose the setup type that best suits your needs.0337541408IDS__IsSetupTypeMinDlg_Complete1033{&MSSansBold8}&Complete0337541408IDS__IsSetupTypeMinDlg_Custom1033{&MSSansBold8}Cu&stom0337541408IDS__IsSetupTypeMinDlg_Minimal1033{&MSSansBold8}&Minimal0337541408IDS__IsSetupTypeMinDlg_MinimumFeatures1033Minimum required features will be installed.0337541408IDS__IsSetupTypeMinDlg_SelectSetupType1033Please select a setup type.0337541408IDS__IsSetupTypeMinDlg_SetupType1033{&MSSansBold8}Setup Type0337541408IDS__IsSetupTypeMinDlg_Typical1033{&MSSansBold8}&Typical0337541408IDS__IsUserExit_ClickFinish1033Click Finish to exit the wizard.0337541408IDS__IsUserExit_Finish1033&Finish0337541408IDS__IsUserExit_KeepOrRestore1033You can either keep any existing installed elements on your system to continue this installation at a later time or you can restore your system to its original state prior to the installation.0337541408IDS__IsUserExit_NotModified1033Your system has not been modified. To install this program at a later time, please run the installation again.0337541408IDS__IsUserExit_RestoreOrContinue1033Click Restore or Continue Later to exit the wizard.0337541408IDS__IsUserExit_WizardCompleted1033{&TahomaBold10}InstallShield Wizard Completed0337541408IDS__IsUserExit_WizardInterrupted1033The wizard was interrupted before [ProductName] could be completely installed.0337541408IDS__IsUserNameLabel1033&User name:0337541408IDS__IsVerifyReadyDlg_BackOrCancel1033If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard.0337541408IDS__IsVerifyReadyDlg_ClickInstall1033Click Install to begin the installation.0337541408IDS__IsVerifyReadyDlg_Company1033Company: [COMPANYNAME]0337541408IDS__IsVerifyReadyDlg_CurrentSettings1033Current Settings:0337541408IDS__IsVerifyReadyDlg_DestFolder1033Destination Folder:0337541408IDS__IsVerifyReadyDlg_Install1033&Install0337541408IDS__IsVerifyReadyDlg_Installdir1033[INSTALLDIR]0337541408IDS__IsVerifyReadyDlg_ModifyReady1033{&MSSansBold8}Ready to Modify the Program0337541408IDS__IsVerifyReadyDlg_ReadyInstall1033{&MSSansBold8}Ready to Install the Program0337541408IDS__IsVerifyReadyDlg_ReadyRepair1033{&MSSansBold8}Ready to Repair the Program0337541408IDS__IsVerifyReadyDlg_SelectedSetupType1033[SelectedSetupType]0337541408IDS__IsVerifyReadyDlg_Serial1033Serial: [ISX_SERIALNUM]0337541408IDS__IsVerifyReadyDlg_SetupType1033Setup Type:0337541408IDS__IsVerifyReadyDlg_UserInfo1033User Information:0337541408IDS__IsVerifyReadyDlg_UserName1033Name: [USERNAME]0337541408IDS__IsVerifyReadyDlg_WizardReady1033The wizard is ready to begin installation.0337541408IDS__IsVerifyRemoveAllDlg_ChoseRemoveProgram1033You have chosen to remove the program from your system.0337541408IDS__IsVerifyRemoveAllDlg_ClickBack1033If you want to review or change any settings, click Back.0337541408IDS__IsVerifyRemoveAllDlg_ClickRemove1033Click Remove to remove [ProductName] from your computer. After removal, this program will no longer be available for use.0337541408IDS__IsVerifyRemoveAllDlg_Remove1033&Remove0337541408IDS__IsVerifyRemoveAllDlg_RemoveProgram1033{&MSSansBold8}Remove the Program0337541408IDS__IsWelcomeDlg_InstallProductName1033The InstallShield(R) Wizard will install [ProductName] on your computer. To continue, click Next.0337541408IDS__IsWelcomeDlg_WarningCopyright1033WARNING: This program is protected by copyright law and international treaties.0337541408IDS__IsWelcomeDlg_WelcomeProductName1033{&TahomaBold10}Welcome to the InstallShield Wizard for [ProductName]0337541408IDS__TargetReq_DESC_COLOR1033The color settings of your system are not adequate for running [ProductName].0337541408IDS__TargetReq_DESC_OS1033The operating system is not adequate for running [ProductName].0337541408IDS__TargetReq_DESC_PROCESSOR1033The processor is not adequate for running [ProductName].0337541408IDS__TargetReq_DESC_RAM1033The amount of RAM is not adequate for running [ProductName].0337541408IDS__TargetReq_DESC_RESOLUTION1033The screen resolution is not adequate for running [ProductName].0337541408ID_STRING11033http://www.simantics.org0186638349ID_STRING101033The Simantics system dynamics application.0723530385ID_STRING21033SIMANT~1|Simantics0-224422991ID_STRING31033Sysdyn0-224459791ID_STRING41033Sysdyn0186587916ID_STRING51033Sysdyn0186620941ID_STRING61033Sysdyn0186592301ID_STRING71033Simantics Sysdyn Feature0723518097ID_STRING81033The Simantics system dynamics application.0723544781ID_STRING91033Simantics Sysdyn Feature0723546769IIDS_UITEXT_FeatureUninstalled1033This feature will remain uninstalled.0337541408
+ + + UpgradedImage_ + Name + MsiPath + Order + Flags + IgnoreMissingFiles +
+ + + UpgradeItem + ObjectSetupPath + ISReleaseFlags + ISAttributes +
+ + + Name + MsiPath + Family +
+ + + Directory_ + Name + Value +
+ + + File_ + Name + Value +
+ + + Name + Value +
+ + + Registry_ + Name + Value +
+ + + ISRelease_ + ISProductConfiguration_ + Name + Value +
+ + + Shortcut_ + Name + Value +
+ + + ISXmlElement + ISXmlFile_ + ISXmlElement_Parent + XPath + Content + ISAttributes +
+ + + ISXmlElementAttrib + ISXmlElement_ + Name + Value + ISAttributes +
+ + + ISXmlFile + FileName + Component_ + Directory + ISAttributes + SelectionNamespaces + Encoding +
+ + + Signature_ + Parent + Element + Attribute + ISAttributes +
+ + + Name + Data + ISBuildSourcePath + ISIconIndex + +
ARPPRODUCTICON.exe<PATH_TO_SIMANTICS-SYSDY_FI>\puzzle_green.ico0
+ + + IniFile + FileName + DirProperty + Section + Key + Value + Action + Component_ +
+ + + Signature_ + FileName + Section + Key + Field + Type +
+ + + Action + Condition + Sequence + ISComments + ISAttributes +
AllocateRegistrySpaceNOT Installed1550AllocateRegistrySpace + AppSearch400AppSearch + BindImage4300BindImage + CCPSearchCCP_TEST500CCPSearch + CostFinalize1000CostFinalize + CostInitialize800CostInitialize + CreateFolders3700CreateFolders + CreateShortcuts4500CreateShortcuts + DeleteServicesVersionNT2000DeleteServices + DuplicateFiles4210DuplicateFiles + FileCost900FileCost + FindRelatedProductsNOT ISSETUPDRIVEN420FindRelatedProducts + ISPreventDowngradeISFOUNDNEWERPRODUCTVERSION450ISPreventDowngrade + ISSelfRegisterCosting2201 + ISSelfRegisterFiles5601 + ISSelfRegisterFinalize6601 + ISSetupFilesCleanup6602 + ISSetupFilesExtract3 + ISUnSelfRegisterFiles2202 + InstallFiles4000InstallFiles + InstallFinalize6600InstallFinalize + InstallInitialize1501InstallInitialize + InstallODBC5400InstallODBC + InstallServicesVersionNT5800InstallServices + InstallValidate1400InstallValidate + IsolateComponents950IsolateComponents + LaunchConditionsNot Installed410LaunchConditions + MigrateFeatureStates1010MigrateFeatureStates + MoveFiles3800MoveFiles + MsiConfigureServicesVersionMsi >= "5.00"5850MSI5 MsiConfigureServices + MsiPublishAssemblies6250MsiPublishAssemblies + MsiUnpublishAssemblies1750MsiUnpublishAssemblies + PatchFiles4090PatchFiles + ProcessComponents1600ProcessComponents + PublishComponents6200PublishComponents + PublishFeatures6300PublishFeatures + PublishProduct6400PublishProduct + RMCCPSearchNot CCP_SUCCESS And CCP_TEST600RMCCPSearch + RegisterClassInfo4600RegisterClassInfo + RegisterComPlus5700RegisterComPlus + RegisterExtensionInfo4700RegisterExtensionInfo + RegisterFonts5300RegisterFonts + RegisterMIMEInfo4900RegisterMIMEInfo + RegisterProduct6100RegisterProduct + RegisterProgIdInfo4800RegisterProgIdInfo + RegisterTypeLibraries5500RegisterTypeLibraries + RegisterUser6000RegisterUser + RemoveDuplicateFiles3400RemoveDuplicateFiles + RemoveEnvironmentStrings3300RemoveEnvironmentStrings + RemoveExistingProducts1410RemoveExistingProducts + RemoveFiles3500RemoveFiles + RemoveFolders3600RemoveFolders + RemoveIniValues3100RemoveIniValues + RemoveODBC2400RemoveODBC + RemoveRegistryValues2600RemoveRegistryValues + RemoveShortcuts3200RemoveShortcuts + ResolveSourceNot Installed850ResolveSource + ScheduleRebootISSCHEDULEREBOOT6410ScheduleReboot + SelfRegModules5600SelfRegModules + SelfUnregModules2200SelfUnregModules + SetARPINSTALLLOCATION1100SetARPINSTALLLOCATION + SetAllUsersProfileNTVersionNT = 400970 + SetODBCFolders1200SetODBCFolders + StartServicesVersionNT5900StartServices + StopServicesVersionNT1900StopServices + UnpublishComponents1700UnpublishComponents + UnpublishFeatures1800UnpublishFeatures + UnregisterClassInfo2700UnregisterClassInfo + UnregisterComPlus2100UnregisterComPlus + UnregisterExtensionInfo2800UnregisterExtensionInfo + UnregisterFonts2500UnregisterFonts + UnregisterMIMEInfo3000UnregisterMIMEInfo + UnregisterProgIdInfo2900UnregisterProgIdInfo + UnregisterTypeLibraries2300UnregisterTypeLibraries + ValidateProductID700ValidateProductID + WriteEnvironmentStrings5200WriteEnvironmentStrings + WriteIniValues5100WriteIniValues + WriteRegistryValues5000WriteRegistryValues + setAllUsersProfile2KVersionNT >= 500980 + setUserProfileNTVersionNT960 +
+ + + Property + Value + + + + + + + + + + + + + + + + + + + + + + + + +
ActiveLanguage1033Comments + CurrentMedia +UwAzAAEAUwAzAA== + DialogSizeType1DoMaintenance0ISCompilerOption_CompileBeforeBuild1ISCompilerOption_Debug0ISCompilerOption_IncludePath + ISCompilerOption_LibraryPath + ISCompilerOption_MaxErrors50ISCompilerOption_MaxWarnings50ISCompilerOption_OutputPath<ISProjectDataFolder>\Script FilesISCompilerOption_PreProcessor_ISSCRIPT_NEW_STYLE_DLG_DEFSISCompilerOption_WarningLevel3ISCompilerOption_WarningsAsErrors1ISThemeInstallShield Blue.themeISUSLock{1ADA6D22-A47C-4CCE-A448-3E6B1FECB511}ISUSSignature{E8E916BB-8489-4623-B8FD-22E7804B70E6}LockPermissionMode1MsiExecCmdLineOptions + MsiLogFile + OnUpgrade1Owner + PatchFamilyMyPatchFamily1PatchSequence1.0.0SaveAsSchema + SccEnabled0SccPath + SchemaVersion771Script1TypeMSIUseMSI45EmbeddedUI0
+ + + Action + Condition + Sequence + ISComments + ISAttributes +
AppSearch400AppSearch + CCPSearchCCP_TEST500CCPSearch + CostFinalize1000CostFinalize + CostInitialize800CostInitialize + ExecuteAction1300ExecuteAction + FileCost955FileCost + FindRelatedProducts430FindRelatedProducts + ISPreventDowngradeISFOUNDNEWERPRODUCTVERSION450ISPreventDowngrade + ISSetupFilesCleanup1301 + ISSetupFilesExtract3 + ISVerifyScriptingRuntimeNOT AFTERREBOOT AND NOT ISSETUPDRIVEN1ISVerifyScriptingRuntime + IsolateComponents950IsolateComponents + LaunchConditionsNot Installed410LaunchConditions + MigrateFeatureStates1200MigrateFeatureStates + RMCCPSearchNot CCP_SUCCESS And CCP_TEST600RMCCPSearch + ResolveSourceNot Installed990ResolveSource + SetAllUsersProfileNTVersionNT = 400970 + ValidateProductID700ValidateProductID + setAllUsersProfile2KVersionNT >= 500980 + setUserProfileNTVersionNT960 +
+ + + Component_Shared + Component_Application +
+ + + Condition + Description +
+ + + Property + Order + Value + Text +
+ + + Property + Order + Value + Text + Binary_ +
+ + + LockObject + Table + Domain + User + Permission +
+ + + ContentType + Extension_ + CLSID +
+ + + DiskId + LastSequence + DiskPrompt + Cabinet + VolumeLabel + Source +
+ + + FileKey + Component_ + SourceName + DestName + SourceFolder + DestFolder + Options +
+ + + Component_ + Feature_ + File_Manifest + File_Application + Attributes +
+ + + Component_ + Name + Value +
+ + + DigitalCertificate + CertData +
+ + + Table + SignObject + DigitalCertificate_ + Hash +
+ + + Component + Flags + Sequence + ReferenceComponents +
+ + + MsiEmbeddedChainer + Condition + CommandLine + Source + Type +
+ + + MsiEmbeddedUI + FileName + Attributes + MessageFilter + Data + ISBuildSourcePath +
+ + + File_ + Options + HashPart1 + HashPart2 + HashPart3 + HashPart4 +
+ + + MsiLockPermissionsEx + LockObject + Table + SDDLText + Condition +
+ + + PackageCertificate + DigitalCertificate_ +
+ + + PatchCertificate + DigitalCertificate_ +
+ + + PatchConfiguration_ + Company + Property + Value +
+ + + File_ + Assembly_ +
+ + + Assembly + Name + Value +
+ + + PatchConfiguration_ + PatchFamily + Target + Sequence + Supersede +
+ + + MsiServiceConfig + Name + Event + ConfigType + Argument + Component_ +
+ + + MsiServiceConfigFailureActions + Name + Event + ResetPeriod + RebootMessage + Command + Actions + DelayActions + Component_ +
+ + + MsiShortcutProperty + Shortcut_ + PropertyKey + PropVariantValue +
+ + + Driver_ + Attribute + Value +
+ + + DataSource + Component_ + Description + DriverDescription + Registration +
+ + + Driver + Component_ + Description + File_ + File_Setup +
+ + + DataSource_ + Attribute + Value +
+ + + Translator + Component_ + Description + File_ + File_Setup +
+ + + File_ + Sequence + PatchSize + Attributes + Header + StreamRef_ + ISBuildSourcePath +
+ + + PatchId + Media_ +
+ + + ProgId + ProgId_Parent + Class_ + Description + Icon_ + IconIndex + ISAttributes +
+ + + Property + Value + ISComments +
ALLUSERS1 + ARPNOMODIFY1 + ARPPRODUCTICONARPPRODUCTICON.exe + ARPURLINFOABOUT##ID_STRING1## + DWUSINTERVAL30 + DWUSLINKCEEB009F49DCB088C9AC008F3E0B978F99BBF08FFE6CB048CEBCE0B8993CF098DEFBC7C8BEAC + DefaultUIFontTahoma8 + DiskPrompt[1] + ISENABLEDWUSFINISHDIALOG + ISVROOT_PORT_NO0 + IS_COMPLUS_PROGRESSTEXT_COST##IDS_COMPLUS_PROGRESSTEXT_COST## + IS_COMPLUS_PROGRESSTEXT_INSTALL##IDS_COMPLUS_PROGRESSTEXT_INSTALL## + IS_COMPLUS_PROGRESSTEXT_UNINSTALL##IDS_COMPLUS_PROGRESSTEXT_UNINSTALL## + IS_PREVENT_DOWNGRADE_EXIT##IDS_PREVENT_DOWNGRADE_EXIT## + IS_PROGMSG_TEXTFILECHANGS_REPLACE##IDS_PROGMSG_TEXTFILECHANGS_REPLACE## + IS_PROGMSG_XML_COSTING##IDS_PROGMSG_XML_COSTING## + IS_PROGMSG_XML_CREATE_FILE##IDS_PROGMSG_XML_CREATE_FILE## + IS_PROGMSG_XML_FILES##IDS_PROGMSG_XML_FILES## + IS_PROGMSG_XML_REMOVE_FILE##IDS_PROGMSG_XML_REMOVE_FILE## + IS_PROGMSG_XML_ROLLBACK_FILES##IDS_PROGMSG_XML_ROLLBACK_FILES## + IS_PROGMSG_XML_UPDATE_FILE##IDS_PROGMSG_XML_UPDATE_FILE## + IS_SQLSERVER_AUTHENTICATION0 + IS_SQLSERVER_DATABASE + IS_SQLSERVER_PASSWORD + IS_SQLSERVER_SERVER + IS_SQLSERVER_USERNAMEsa + Manufacturer##COMPANY_NAME## + PROGMSG_IIS_CREATEAPPPOOL##IDS_PROGMSG_IIS_CREATEAPPPOOL## + PROGMSG_IIS_CREATEAPPPOOLS##IDS_PROGMSG_IIS_CREATEAPPPOOLS## + PROGMSG_IIS_CREATEVROOT##IDS_PROGMSG_IIS_CREATEVROOT## + PROGMSG_IIS_CREATEVROOTS##IDS_PROGMSG_IIS_CREATEVROOTS## + PROGMSG_IIS_CREATEWEBSERVICEEXTENSION##IDS_PROGMSG_IIS_CREATEWEBSERVICEEXTENSION## + PROGMSG_IIS_CREATEWEBSERVICEEXTENSIONS##IDS_PROGMSG_IIS_CREATEWEBSERVICEEXTENSIONS## + PROGMSG_IIS_CREATEWEBSITE##IDS_PROGMSG_IIS_CREATEWEBSITE## + PROGMSG_IIS_CREATEWEBSITES##IDS_PROGMSG_IIS_CREATEWEBSITES## + PROGMSG_IIS_EXTRACT##IDS_PROGMSG_IIS_EXTRACT## + PROGMSG_IIS_EXTRACTDONE##IDS_PROGMSG_IIS_EXTRACTDONE## + PROGMSG_IIS_EXTRACTDONEz##IDS_PROGMSG_IIS_EXTRACTDONE## + PROGMSG_IIS_EXTRACTzDONE##IDS_PROGMSG_IIS_EXTRACTDONE## + PROGMSG_IIS_REMOVEAPPPOOL##IDS_PROGMSG_IIS_REMOVEAPPPOOL## + PROGMSG_IIS_REMOVEAPPPOOLS##IDS_PROGMSG_IIS_REMOVEAPPPOOLS## + PROGMSG_IIS_REMOVESITE##IDS_PROGMSG_IIS_REMOVESITE## + PROGMSG_IIS_REMOVEVROOT##IDS_PROGMSG_IIS_REMOVEVROOT## + PROGMSG_IIS_REMOVEVROOTS##IDS_PROGMSG_IIS_REMOVEVROOTS## + PROGMSG_IIS_REMOVEWEBSERVICEEXTENSION##IDS_PROGMSG_IIS_REMOVEWEBSERVICEEXTENSION## + PROGMSG_IIS_REMOVEWEBSERVICEEXTENSIONS##IDS_PROGMSG_IIS_REMOVEWEBSERVICEEXTENSIONS## + PROGMSG_IIS_REMOVEWEBSITES##IDS_PROGMSG_IIS_REMOVEWEBSITES## + PROGMSG_IIS_ROLLBACKAPPPOOLS##IDS_PROGMSG_IIS_ROLLBACKAPPPOOLS## + PROGMSG_IIS_ROLLBACKVROOTS##IDS_PROGMSG_IIS_ROLLBACKVROOTS## + PROGMSG_IIS_ROLLBACKWEBSERVICEEXTENSIONS##IDS_PROGMSG_IIS_ROLLBACKWEBSERVICEEXTENSIONS## + ProductCode{70ECF476-1489-4173-8EBD-503B4085A023} + ProductNameSimantics Sysdyn + ProductVersion1.7.0.19 + REBOOTSuppress + STANDARD_USE_SETUPEXE##IDS_STANDARD_USE_SETUPEXE## + SecureCustomPropertiesISALWAYSINSTALLELEVATED;ISSETUPDRIVEN;ARPSYSTEMCOMPONENT;ARPNOMODIFY;ARPNOREMOVE;INSTALLDIR;ISFOUNDNEWERPRODUCTVERSION;USERNAME;COMPANYNAME;ISX_SERIALNUM;IS_SQLSERVER_LIST;IS_SQLSERVER_DATABASE;IS_SQLSERVER_AUTHENTICATION;IS_SQLSERVER_USERNAME;IS_SQLSERVER_SERVER;IS_SQLSERVER_PASSWORD;IS_NET_API_LOGON_USERNAME;IS_NET_API_LOGON_PASSWORD;IS_NEW_USER_CONFIRM_TEXT;IS_NEW_USER_SERVER_TEXT;IS_NEW_USER_GROUP_TEXT;IS_NEW_USER_NAME_TEXT;IS_NET_API_NEW_USER_PASSWORD;IS_NET_API_NEW_USER_NAME;IS_NET_API_NEW_USER_CONFIRM;IS_NEW_USER_PASSWORD_TEXT;IS_NET_API_NEW_USER_SERVER;IS_NET_API_NEW_USER_GROUP;IS_NET_API_GROUP_LIST;IS_NET_API_SERVER_LIST;IS_NET_API_SERVER_NEW_USER_LIST;IS_NET_API_USER_LIST;IS_NET_API_LOGON_DOMAIN_TOKEN;IS_NET_API_LOGON_USERNAME_TOKEN;SUPPORTDIR;SYSDYN64 + UpgradeCode{28D93A0D-FFD5-46CF-B959-1C4D7588F3F9} +
+ + + ComponentId + Qualifier + Component_ + AppData + Feature_ +
+ + + Property + Order + Value + X + Y + Width + Height + Text + Help + ISControlId +
+ + + Signature_ + Root + Key + Name + Type +
+ + + Registry + Root + Key + Name + Value + Component_ + ISAttributes +
+ + + FileKey + Component_ + FileName + DirProperty + InstallMode +
+ + + RemoveIniFile + FileName + DirProperty + Section + Key + Value + Action + Component_ +
+ + + RemoveRegistry + Root + Key + Name + Component_ +
+ + + ReserveKey + Component_ + ReserveFolder + ReserveLocal + ReserveSource +
+ + + SFPCatalog + Catalog + Dependency +
+ + + File_ + Cost +
+ + + ServiceControl + Name + Event + Arguments + Wait + Component_ +
+ + + ServiceInstall + Name + DisplayName + ServiceType + StartType + ErrorControl + LoadOrderGroup + Dependencies + StartName + Password + Arguments + Component_ + Description +
+ + + Shortcut + Directory_ + Name + Component_ + Target + Arguments + Description + Hotkey + Icon_ + IconIndex + ShowCmd + WkDir + DisplayResourceDLL + DisplayResourceId + DescriptionResourceDLL + DescriptionResourceId + ISComments + ISShortcutName + ISAttributes +
+ + + Signature + FileName + MinVersion + MaxVersion + MinSize + MaxSize + MinDate + MaxDate + Languages +
+ + + TextStyle + FaceName + Size + Color + StyleBits + + + + +
Arial8Arial8 + Arial9Arial9 + CourierNew8Courier New8 + CourierNew9Courier New9 + MSGothic9MS Gothic9 + MSSansBold8Tahoma81MSSansSerif8MS Sans Serif8 + MSSansSerif9MS Sans Serif9 + Tahoma10Tahoma10 + Tahoma8Tahoma8 + Tahoma9Tahoma9 + TahomaBold10Tahoma101TahomaBold8Tahoma81Times8Times New Roman8 + Times9Times New Roman9 + TimesItalic12Times New Roman122
+ + + LibID + Language + Component_ + Version + Description + Directory_ + Feature_ + Cost +
+ + + Key + Text + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AbsentPath + GB##IDS_UITEXT_GB##KB##IDS_UITEXT_KB##MB##IDS_UITEXT_MB##MenuAbsent##IDS_UITEXT_FeatureNotAvailable##MenuAdvertise##IDS_UITEXT_FeatureInstalledWhenRequired2##MenuAllCD##IDS_UITEXT_FeatureInstalledCD##MenuAllLocal##IDS_UITEXT_FeatureInstalledLocal##MenuAllNetwork##IDS_UITEXT_FeatureInstalledNetwork##MenuCD##IDS_UITEXT_FeatureInstalledCD2##MenuLocal##IDS_UITEXT_FeatureInstalledLocal2##MenuNetwork##IDS_UITEXT_FeatureInstalledNetwork2##NewFolder##IDS_UITEXT_Folder##SelAbsentAbsent##IDS_UITEXT_GB##SelAbsentAdvertise##IDS_UITEXT_FeatureInstalledWhenRequired##SelAbsentCD##IDS_UITEXT_FeatureOnCD##SelAbsentLocal##IDS_UITEXT_FeatureLocal##SelAbsentNetwork##IDS_UITEXT_FeatureNetwork##SelAdvertiseAbsent##IDS_UITEXT_FeatureUnavailable##SelAdvertiseAdvertise##IDS_UITEXT_FeatureInstalledRequired##SelAdvertiseCD##IDS_UITEXT_FeatureOnCD2##SelAdvertiseLocal##IDS_UITEXT_FeatureLocal2##SelAdvertiseNetwork##IDS_UITEXT_FeatureNetwork2##SelCDAbsent##IDS_UITEXT_FeatureWillBeUninstalled##SelCDAdvertise##IDS_UITEXT_FeatureWasCD##SelCDCD##IDS_UITEXT_FeatureRunFromCD##SelCDLocal##IDS_UITEXT_FeatureWasCDLocal##SelChildCostNeg##IDS_UITEXT_FeatureFreeSpace##SelChildCostPos##IDS_UITEXT_FeatureRequiredSpace##SelCostPending##IDS_UITEXT_CompilingFeaturesCost##SelLocalAbsent##IDS_UITEXT_FeatureCompletelyRemoved##SelLocalAdvertise##IDS_UITEXT_FeatureRemovedUnlessRequired##SelLocalCD##IDS_UITEXT_FeatureRemovedCD##SelLocalLocal##IDS_UITEXT_FeatureRemainLocal##SelLocalNetwork##IDS_UITEXT_FeatureRemoveNetwork##SelNetworkAbsent##IDS_UITEXT_FeatureUninstallNoNetwork##SelNetworkAdvertise##IDS_UITEXT_FeatureWasOnNetworkInstalled##SelNetworkLocal##IDS_UITEXT_FeatureWasOnNetworkLocal##SelNetworkNetwork##IDS_UITEXT_FeatureContinueNetwork##SelParentCostNegNeg##IDS_UITEXT_FeatureSpaceFree##SelParentCostNegPos##IDS_UITEXT_FeatureSpaceFree2##SelParentCostPosNeg##IDS_UITEXT_FeatureSpaceFree3##SelParentCostPosPos##IDS_UITEXT_FeatureSpaceFree4##TimeRemaining##IDS_UITEXT_TimeRemaining##VolumeCostAvailable##IDS_UITEXT_Available##VolumeCostDifference##IDS_UITEXT_Differences##VolumeCostRequired##IDS_UITEXT_Required##VolumeCostSize##IDS_UITEXT_DiskSize##VolumeCostVolume##IDS_UITEXT_Volume##bytes##IDS_UITEXT_Bytes##
+ + + UpgradeCode + VersionMin + VersionMax + Language + Attributes + Remove + ActionProperty + ISDisplayName + +
{00000000-0000-0000-0000-000000000000}***ALL_VERSIONS***2ISFOUNDNEWERPRODUCTVERSIONISPreventDowngrade
+ + + Extension_ + Verb + Sequence + Command + Argument +
+ + + Table + Column + Nullable + MinValue + MaxValue + KeyTable + KeyColumn + Category + Set + Description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ActionTextActionNIdentifierName of action to be described.ActionTextDescriptionYTextLocalized description displayed in progress dialog and log when action is executing.ActionTextTemplateYTemplateOptional localized format template used to format action data records for display during action execution.AdminExecuteSequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL.AdminExecuteSequenceConditionYConditionOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.AdminExecuteSequenceISAttributesYThis is used to store MM Custom Action TypesAdminExecuteSequenceISCommentsYTextAuthor’s comments on this Sequence.AdminExecuteSequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.AdminUISequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL.AdminUISequenceConditionYConditionOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.AdminUISequenceISAttributesYThis is used to store MM Custom Action TypesAdminUISequenceISCommentsYTextAuthor’s comments on this Sequence.AdminUISequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.AdvtExecuteSequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL.AdvtExecuteSequenceConditionYConditionOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.AdvtExecuteSequenceISAttributesYThis is used to store MM Custom Action TypesAdvtExecuteSequenceISCommentsYTextAuthor’s comments on this Sequence.AdvtExecuteSequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.AdvtUISequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL.AdvtUISequenceConditionYConditionOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.AdvtUISequenceISAttributesYThis is used to store MM Custom Action TypesAdvtUISequenceISCommentsYTextAuthor’s comments on this Sequence.AdvtUISequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.AppIdActivateAtStorageY01 + AppIdAppIdNGuid + AppIdDllSurrogateYText + AppIdLocalServiceYText + AppIdRemoteServerNameYFormatted + AppIdRunAsInteractiveUserY01 + AppIdServiceParametersYText + AppSearchPropertyNIdentifierThe property associated with a SignatureAppSearchSignature_NISXmlLocator;Signature1IdentifierThe Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.BBControlAttributesY02147483647A 32-bit word that specifies the attribute flags to be applied to this control.BBControlBBControlNIdentifierName of the control. This name must be unique within a billboard, but can repeat on different billboard.BBControlBillboard_NBillboard1IdentifierExternal key to the Billboard table, name of the billboard.BBControlHeightN032767Height of the bounding rectangle of the control.BBControlTextYTextA string used to set the initial text contained within a control (if appropriate).BBControlTypeNIdentifierThe type of the control.BBControlWidthN032767Width of the bounding rectangle of the control.BBControlXN032767Horizontal coordinate of the upper left corner of the bounding rectangle of the control.BBControlYN032767Vertical coordinate of the upper left corner of the bounding rectangle of the control.BillboardActionYIdentifierThe name of an action. The billboard is displayed during the progress messages received from this action.BillboardBillboardNIdentifierName of the billboard.BillboardFeature_NFeature1IdentifierAn external key to the Feature Table. The billboard is shown only if this feature is being installed.BillboardOrderingY032767A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column.BinaryDataYBinaryBinary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.BinaryISBuildSourcePathYTextFull path to the ICO or EXE file.BinaryNameNIdentifierUnique key identifying the binary data.BindImageFile_NFile1IdentifierThe index into the File table. This must be an executable file.BindImagePathYPathsA list of ; delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] .CCPSearchSignature_NSignature1IdentifierThe Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.CheckBoxPropertyNIdentifierA named property to be tied to the item.CheckBoxValueYFormattedThe value string associated with the item.ClassAppId_YAppId1GuidOptional AppID containing DCOM information for associated application (string GUID).ClassArgumentYFormattedoptional argument for LocalServers.ClassAttributesY32767Class registration attributes.ClassCLSIDNGuidThe CLSID of an OLE factory.ClassComponent_NComponent1IdentifierRequired foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.ClassContextNIdentifierThe numeric server context for this server. CLSCTX_xxxxClassDefInprocHandlerYText1;2;3Optional default inproc handler. Only optionally provided if Context=CLSCTX_LOCAL_SERVER. Typically "ole32.dll" or "mapi32.dll"ClassDescriptionYTextLocalized description for the Class.ClassFeature_NFeature1IdentifierRequired foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.ClassFileTypeMaskYTextOptional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2...ClassIconIndexY-3276732767Optional icon index.ClassIcon_YIcon1IdentifierOptional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key.ClassProgId_DefaultYProgId1TextOptional ProgId associated with this CLSID.ComboBoxOrderN132767A positive integer used to determine the ordering of the items within one list. The integers do not have to be consecutive.ComboBoxPropertyNIdentifierA named property to be tied to this item. All the items tied to the same property become part of the same combobox.ComboBoxTextYFormattedThe visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.ComboBoxValueNFormattedThe value string associated with this item. Selecting the line will set the associated property to this value.CompLocatorComponentIdNGuidA string GUID unique to this component, version, and language.CompLocatorSignature_NSignature1IdentifierThe table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.CompLocatorTypeY01A boolean value that determines if the registry value is a filename or a directory location.ComplusComponent_NComponent1IdentifierForeign key referencing Component that controls the ComPlus component.ComplusExpTypeY032767ComPlus component attributes.ComponentAttributesNRemote execution option, one of irsEnumComponentComponentNIdentifierPrimary key used to identify a particular component record.ComponentComponentIdYGuidA string GUID unique to this component, version, and language.ComponentConditionYConditionA conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component.ComponentDirectory_NDirectory1IdentifierRequired key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table.ComponentISAttributesYThis is used to store Installshield custom properties of a component.ComponentISCommentsYTextUser Comments.ComponentISDotNetInstallerArgsCommitYTextArguments passed to the key file of the component if if implements the .NET Installer classComponentISDotNetInstallerArgsInstallYTextArguments passed to the key file of the component if if implements the .NET Installer classComponentISDotNetInstallerArgsRollbackYTextArguments passed to the key file of the component if if implements the .NET Installer classComponentISDotNetInstallerArgsUninstallYTextArguments passed to the key file of the component if if implements the .NET Installer classComponentISRegFileToMergeAtBuildYTextPath and File name of a .REG file to merge into the component at build time.ComponentISScanAtBuildFileYTextFile used by the Dot Net scanner to populate dependant assemblies' File_Application field.ComponentKeyPathYFile;ODBCDataSource;Registry1IdentifierEither the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it.ConditionConditionYConditionExpression evaluated to determine if Level in the Feature table is to change.ConditionFeature_NFeature1IdentifierReference to a Feature entry in Feature table.ConditionLevelN032767New selection Level to set in Feature table if Condition evaluates to TRUE.ControlAttributesY02147483647A 32-bit word that specifies the attribute flags to be applied to this control.ControlBinary_YBinary1IdentifierExternal key to the Binary table.ControlControlNIdentifierName of the control. This name must be unique within a dialog, but can repeat on different dialogs.ControlControl_NextYControl2IdentifierThe name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles!ControlDialog_NDialog1IdentifierExternal key to the Dialog table, name of the dialog.ControlHeightN032767Height of the bounding rectangle of the control.ControlHelpYTextThe help strings used with the button. The text is optional.ControlISBuildSourcePathYTextFull path to .rtf file for scrollable text controlControlISControlIdYA number used to represent the control ID of the Control, Used in Dialog exportControlISWindowStyleY02147483647A 32-bit word that specifies non-MSI window styles to be applied to this control.ControlPropertyYIdentifierThe name of a defined property to be linked to this control.ControlTextYFormattedA string used to set the initial text contained within a control (if appropriate).ControlTypeNIdentifierThe type of the control.ControlWidthN032767Width of the bounding rectangle of the control.ControlXN032767Horizontal coordinate of the upper left corner of the bounding rectangle of the control.ControlYN032767Vertical coordinate of the upper left corner of the bounding rectangle of the control.ControlConditionActionNDefault;Disable;Enable;Hide;ShowThe desired action to be taken on the specified control.ControlConditionConditionNConditionA standard conditional statement that specifies under which conditions the action should be triggered.ControlConditionControl_NControl2IdentifierA foreign key to the Control table, name of the control.ControlConditionDialog_NDialog1IdentifierA foreign key to the Dialog table, name of the dialog.ControlEventArgumentNFormattedA value to be used as a modifier when triggering a particular event.ControlEventConditionYConditionA standard conditional statement that specifies under which conditions an event should be triggered.ControlEventControl_NControl2IdentifierA foreign key to the Control table, name of the controlControlEventDialog_NDialog1IdentifierA foreign key to the Dialog table, name of the dialog.ControlEventEventNFormattedAn identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries.ControlEventOrderingY02147483647An integer used to order several events tied to the same control. Can be left blank.CreateFolderComponent_NComponent1IdentifierForeign key into the Component table.CreateFolderDirectory_NDirectory1IdentifierPrimary key, could be foreign key into the Directory table.CustomActionActionNIdentifierPrimary key, name of action, normally appears in sequence table unless private use.CustomActionExtendedTypeY02147483647The numeric custom action type info flags.CustomActionISCommentsYTextAuthor’s comments for this custom action.CustomActionSourceYCustomSourceThe table reference of the source of the code.CustomActionTargetYISDLLWrapper;ISInstallScriptAction1FormattedExcecution parameter, depends on the type of custom actionCustomActionTypeN132767The numeric custom action type, consisting of source location, code type, entry, option flags.DialogAttributesY02147483647A 32-bit word that specifies the attribute flags to be applied to this dialog.DialogControl_CancelYControl2IdentifierDefines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button.DialogControl_DefaultYControl2IdentifierDefines the default control. Hitting return is equivalent to pushing this button.DialogControl_FirstNControl2IdentifierDefines the control that has the focus when the dialog is created.DialogDialogNIdentifierName of the dialog.DialogHCenteringN0100Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center.DialogHeightN032767Height of the bounding rectangle of the dialog.DialogISCommentsYTextAuthor’s comments for this dialog.DialogISResourceIdYA Number the Specifies the Dialog ID to be used in Dialog ExportDialogISWindowStyleYA 32-bit word that specifies non-MSI window styles to be applied to this control. This is only used in Script Based Setups.DialogTextStyle_YIdentifierForeign Key into TextStyle table, only used in Script Based Projects.DialogTitleYFormattedA text string specifying the title to be displayed in the title bar of the dialog's window.DialogVCenteringN0100Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center.DialogWidthN032767Width of the bounding rectangle of the dialog.DirectoryDefaultDirNTextThe default sub-path under parent's path.DirectoryDirectoryNIdentifierUnique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory.DirectoryDirectory_ParentYDirectory1IdentifierReference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree.DirectoryISAttributesY0;1;2;3;4;5;6;7This is used to store Installshield custom properties of a directory. Currently the only one is Shortcut.DirectoryISDescriptionYTextDescription of folderDirectoryISFolderNameYTextThis is used in Pro projects because the pro identifier used in the tree wasn't necessarily unique.DrLocatorDepthY032767The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.DrLocatorParentYIdentifierThe parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.DrLocatorPathYAnyPathThe path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.DrLocatorSignature_NSignature1IdentifierThe Signature_ represents a unique file signature and is also the foreign key in the Signature table.DuplicateFileComponent_NComponent1IdentifierForeign key referencing Component that controls the duplicate file.DuplicateFileDestFolderYIdentifierName of a property whose value is assumed to resolve to the full pathname to a destination folder.DuplicateFileDestNameYTextFilename to be given to the duplicate file.DuplicateFileFileKeyNIdentifierPrimary key used to identify a particular file entryDuplicateFileFile_NFile1IdentifierForeign key referencing the source file to be duplicated.EnvironmentComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the installing of the environmental value.EnvironmentEnvironmentNIdentifierUnique identifier for the environmental variable settingEnvironmentNameNTextThe name of the environmental value.EnvironmentValueYFormattedThe value to set in the environmental settings.ErrorErrorN032767Integer error number, obtained from header file IError(...) macros.ErrorMessageYTemplateError formatting template, obtained from user ed. or localizers.EventMappingAttributeNIdentifierThe name of the control attribute, that is set when this event is received.EventMappingControl_NControl2IdentifierA foreign key to the Control table, name of the control.EventMappingDialog_NDialog1IdentifierA foreign key to the Dialog table, name of the Dialog.EventMappingEventNIdentifierAn identifier that specifies the type of the event that the control subscribes to.ExtensionComponent_NComponent1IdentifierRequired foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.ExtensionExtensionNTextThe extension associated with the table row.ExtensionFeature_NFeature1IdentifierRequired foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.ExtensionMIME_YMIME1TextOptional Context identifier, typically "type/format" associated with the extensionExtensionProgId_YProgId1TextOptional ProgId associated with this extension.FeatureAttributesN0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54Feature attributesFeatureDescriptionYTextLonger descriptive text describing a visible feature item.FeatureDirectory_YDirectory1UpperCaseThe name of the Directory that can be configured by the UI. A non-null value will enable the browse button.FeatureDisplayY032767Numeric sort order, used to force a specific display ordering.FeatureFeatureNIdentifierPrimary key used to identify a particular feature record.FeatureFeature_ParentYFeature1IdentifierOptional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item.FeatureISCommentsYCommentsFeatureISFeatureCabNameYName of CAB used when compressing CABs by Feature. Used to override build generated name for CAB file.FeatureISProFeatureNameYTextThe name of the feature used by pro projects. This doesn't have to be unique.FeatureISReleaseFlagsYRelease Flags that specify whether this feature will be built in a particular release.FeatureLevelN032767The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display.FeatureTitleYTextShort text identifying a visible feature item.FeatureComponentsComponent_NComponent1IdentifierForeign key into Component table.FeatureComponentsFeature_NFeature1IdentifierForeign key into Feature table.FileAttributesY032767Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses)FileComponent_NComponent1IdentifierForeign key referencing Component that controls the file.FileFileNIdentifierPrimary key, non-localized token, must match identifier in cabinet. For uncompressed files, this field is ignored.FileFileNameNTextFile name used for installation. This may contain a "short name|long name" pair. It may be just a long name, hence it cannot be of the Filename data type.FileFileSizeN02147483647Size of file in bytes (long integer).FileISAttributesY02147483647This field contains the following attributes: UseSystemSettings(0x1)FileISBuildSourcePathYTextFull path, the category is of Text instead of Path because of potential use of path variables.FileISComponentSubFolder_YIdentifierForeign key referencing component subfolder containing this file. Only for Pro.FileLanguageYLanguageList of decimal language Ids, comma-separated if more than one.FileSequenceN132767Sequence with respect to the media images; order must track cabinet order.FileVersionYFile1VersionVersion string for versioned files; Blank for unversioned files.FileSFPCatalogFile_NFile1IdentifierFile associated with the catalogFileSFPCatalogSFPCatalog_NSFPCatalog1TextCatalog associated with the fileFontFile_NFile1IdentifierPrimary key, foreign key into File table referencing font file.FontFontTitleYTextFont name.ISAliasAliasY + ISAliasIdentifierY + ISAliasTableY + ISAssistantTagDataY + ISAssistantTagTagN + ISCEAppAppKeyN + ISCEAppAppNameN + ISCEAppAttributesY + ISCEAppCompanyNameN + ISCEAppComponent_YComponent1 + ISCEAppDefDirN + ISCEAppDeleteMediaN + ISCEAppDescriptionY + ISCEAppDesktopTargetDirN + ISCEAppDeviceFileY + ISCEAppIconIndexY + ISCEAppIconPathY + ISCEAppInstallNetCFY + ISCEAppInstallNetCF2Y + ISCEAppInstallSQLClientY + ISCEAppInstallSQLClient2Y + ISCEAppInstallSQLDevY + ISCEAppInstallSQLDev2Y + ISCEAppInstallSQLServerY + ISCEAppInstallSQLServer2Y + ISCEAppNoUninstallY + ISCEAppPVKFileY + ISCEAppPostXMLY + ISCEAppPreXMLY + ISCEAppRawDeviceFileY + ISCEAppSPCFileY + ISCEAppSPCPwdY + ISCEDirAppKeyN + ISCEDirDirKeyN + ISCEDirDirParentN + ISCEDirDirValueN + ISCEFileAdvancedOptionsY + ISCEFileAppKeyN + ISCEFileCopyOptionN + ISCEFileDestinationN + ISCEFileFileKeyN + ISCEFileFileOptionN + ISCEFileNameN + ISCEFilePlatformN + ISCEFileProcessorN + ISCEFileSourceN + ISCEFileExtAppKeyN + ISCEFileExtDescriptionY + ISCEFileExtExtKeyN + ISCEFileExtExtensionN + ISCEFileExtFileKeyN + ISCEFileExtIconIndexN + ISCEInstallCEAppNameN + ISCEInstallCECabsN + ISCEInstallCEDesktopDirN + ISCEInstallCEIcoFileN + ISCEInstallCEIniFileKeyN + ISCEInstallCEInstallKeyN + ISCEInstallComponent_Y + ISCEInstallDeleteMediaN + ISCEOtherAppCABsAppKeyN + ISCEOtherAppCABsBuildSourcePathN + ISCEOtherAppCABsFileKeyN + ISCERedistAppKeyN + ISCERedistNameY + ISCERedistPlatformsY + ISCERegistryAppKeyN + ISCERegistryKeyN + ISCERegistryNameY + ISCERegistryOverwriteN + ISCERegistryPlatformN + ISCERegistryProcessorN + ISCERegistryRegKeyN + ISCERegistryRootN + ISCERegistryValueY + ISCESetupFileAppKeyN + ISCESetupFileNameN + ISCESetupFilePlatformN + ISCESetupFileProcessorN + ISCESetupFileSetupFileKeyN + ISCESetupFileSourceN + ISCEShtCutAppKeyN + ISCEShtCutDestinationN + ISCEShtCutDisplayNameN + ISCEShtCutPlatformN + ISCEShtCutShtCutKeyN + ISCEShtCutStartScreenIconY + ISCEShtCutTargetN + ISChainPackageDisplayNameYTextDisplay name for the chained package. Used only in the IDE.ISChainPackageISReleaseFlagsY + ISChainPackageInstallConditionYCondition + ISChainPackageInstallPropertiesYFormatted + ISChainPackageOptionsNInteger + ISChainPackageOrderNInteger + ISChainPackagePackageNIdentifier + ISChainPackageProductCodeY + ISChainPackageRemoveConditionYCondition + ISChainPackageRemovePropertiesYFormatted + ISChainPackageSourcePathY + ISChainPackageDataDataYBinaryBinary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.ISChainPackageDataFileNIdentifier + ISChainPackageDataFilePathNFormatted + ISChainPackageDataISBuildSourcePathYTextFull path to the ICO or EXE file.ISChainPackageDataOptionsY + ISChainPackageDataPackage_NISChainPackage1Identifier + ISClrWrapAction_NCustomAction1IdentifierForeign key into CustomAction tableISClrWrapNameNTextProperty associated with this ActionISClrWrapValueYTextValue associated with this PropertyISComCatalogAttributeISComCatalogObject_NISComCatalogObject1IdentifierForeign key into the ISComCatalogObject table.ISComCatalogAttributeItemNameNTextThe named attribute for a catalog object.ISComCatalogAttributeItemValueYTextA value associated with the attribute defined in the ItemName column.ISComCatalogCollectionCollectionNameNTextA catalog collection name.ISComCatalogCollectionISComCatalogCollectionNIdentifierA unique key for the ISComCatalogCollection table.ISComCatalogCollectionISComCatalogObject_NISComCatalogObject1IdentifierForeign key into the ISComCatalogObject table.ISComCatalogCollectionObjectsISComCatalogCollection_NISComCatalogCollection1IdentifierA unique key for the ISComCatalogCollection table.ISComCatalogCollectionObjectsISComCatalogObject_NISComCatalogObject1IdentifierForeign key into the ISComCatalogObject table.ISComCatalogObjectDisplayNameNThe display name of a catalog object.ISComCatalogObjectISComCatalogObjectNIdentifierA unique key for the ISComCatalogObject table.ISComPlusApplicationComponent_NComponent1IdentifierForeign key into the Component table that a COM+ application belongs to.ISComPlusApplicationComputerNameYTextComputer name that a COM+ application belongs to.ISComPlusApplicationDepFilesYTextList of the dependent files.ISComPlusApplicationISAttributesYInstallShield custom attributes associated with a COM+ application.ISComPlusApplicationISComCatalogObject_NISComCatalogObject1IdentifierForeign key into the ISComCatalogObject table.ISComPlusApplicationDLLAlterDLLYTextAlternate filename of the COM+ application component. Will be used for a .NET serviced component.ISComPlusApplicationDLLCLSIDNTextCLSID of the COM+ application component.ISComPlusApplicationDLLDLLYTextFilename of the COM+ application component.ISComPlusApplicationDLLISComCatalogObject_NISComCatalogObject1IdentifierForeign key into the ISComCatalogObject table.ISComPlusApplicationDLLISComPlusApplicationDLLNIdentifierA unique key for the ISComPlusApplicationDLL table.ISComPlusApplicationDLLISComPlusApplication_NISComPlusApplication1IdentifierForeign key into the ISComPlusApplication table.ISComPlusApplicationDLLProgIdYTextProgId of the COM+ application component.ISComPlusProxyComponent_YComponent1IdentifierForeign key into the Component table that a COM+ application proxy belongs to.ISComPlusProxyDepFilesYTextList of the dependent files.ISComPlusProxyISAttributesYInstallShield custom attributes associated with a COM+ application proxy.ISComPlusProxyISComPlusApplication_NISComPlusApplication1IdentifierForeign key into the ISComPlusApplication table that a COM+ application proxy belongs to.ISComPlusProxyISComPlusProxyNIdentifierA unique key for the ISComPlusProxy table.ISComPlusProxyDepFileFile_NFile1IdentifierForeign key into the File table.ISComPlusProxyDepFileISComPlusApplication_NISComPlusApplication1IdentifierForeign key into the ISComPlusApplication table.ISComPlusProxyDepFileISPathYTextFull path of the dependent file.ISComPlusProxyFileFile_NFile1IdentifierForeign key into the File table.ISComPlusProxyFileISComPlusApplicationDLL_NISComPlusApplicationDLL1IdentifierForeign key into the ISComPlusApplicationDLL table.ISComPlusServerDepFileFile_NFile1IdentifierForeign key into the File table.ISComPlusServerDepFileISComPlusApplication_NISComPlusApplication1IdentifierForeign key into the ISComPlusApplication table.ISComPlusServerDepFileISPathYTextFull path of the dependent file.ISComPlusServerFileFile_NFile1IdentifierForeign key into the File table.ISComPlusServerFileISComPlusApplicationDLL_NISComPlusApplicationDLL1IdentifierForeign key into the ISComPlusApplicationDLL table.ISComponentExtendedComponent_NComponent1IdentifierPrimary key used to identify a particular component record.ISComponentExtendedFTPLocationYTextFTP LocationISComponentExtendedFilterPropertyNIdentifierProperty to set if you want to filter a componentISComponentExtendedHTTPLocationYTextHTTP LocationISComponentExtendedLanguageYTextLanguageISComponentExtendedMiscellaneousYTextMiscellaneousISComponentExtendedOSYbitwise addition of OSsISComponentExtendedPlatformsYbitwise addition of Platforms.ISCustomActionReferenceAction_NCustomAction1IdentifierForeign key into theICustomAction table.ISCustomActionReferenceDescriptionYTextContents of the file speciifed in ISCAReferenceFilePath. This column is only used by MSI.ISCustomActionReferenceFileTypeYTextfile type of the file specified ISCAReferenceFilePath. This column is only used by MSI.ISCustomActionReferenceISCAReferenceFilePathYTextFull path, the category is of Text instead of Path because of potential use of path variables. This column only exists in ISM.ISDLLWrapperEntryPointNTextThis is a foreign key to the target column in the CustomAction tableISDLLWrapperSourceNFormattedThis is column points to the source file for the DLLWrapper Custom ActionISDLLWrapperTargetNTextThe function signatureISDLLWrapperTypeYTypeISDRMFileFile_YFile1IdentifierForeign key into File table. A null value will cause a build warning.ISDRMFileISDRMFileNIdentifierUnique identifier for this item.ISDRMFileISDRMLicense_YISDRMLicense1IdentifierForeign key referencing License that packages this file.ISDRMFileShellNTextText indicating the activation shell used at runtime.ISDRMFileAttributeISDRMFile_NISDRMFile1IdentifierPrimary foreign key into ISDRMFile table.ISDRMFileAttributePropertyNTextThe name of the attributeISDRMFileAttributeValueYTextThe value of the attributeISDRMLicenseAttributesYNumberBitwise field used to specify binary attributes of this license.ISDRMLicenseDescriptionYTextAn internal description of this license.ISDRMLicenseISDRMLicenseNIdentifierUnique key identifying the license record.ISDRMLicenseLicenseNumberYTextThe license number.ISDRMLicenseProjectVersionYTextThe version of the project that this license is tied to.ISDRMLicenseRequestCodeYTextThe request code.ISDRMLicenseResponseCodeYTextThe response code.ISDependencyExcludeY + ISDependencyISDependencyY + ISDisk1FileDiskY-1;0;1Used to differentiate between disk1(1), last disk(-1), and other(0).ISDisk1FileISBuildSourcePathNTextFull path of file to be copied to Disk1 folderISDisk1FileISDisk1FileNIdentifierPrimary key for ISDisk1File tableISDynamicFileComponent_NComponent1IdentifierForeign key referencing Component that controls the file.ISDynamicFileExcludeFilesYTextWildcards for excluded files.ISDynamicFileISAttributesY0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15This is used to store Installshield custom properties of a dynamic filet. Currently the only one is SelfRegister.ISDynamicFileIncludeFilesYTextWildcards for included files.ISDynamicFileIncludeFlagsYInclude flags.ISDynamicFileSourceFolderNTextFull path, the category is of Text instead of Path because of potential use of path variables.ISFeatureExtendedCDRomFolderYTextFiles in this feature will be placed in this subfolder if your media is the CD-ROM type.ISFeatureExtendedFTPLocationYTextFTP LocationISFeatureExtendedFeature_NFeature1IdentifierForeign key to the feature tableISFeatureExtendedHTTPLocationYTextHTTP LocationISFeatureExtendedISAttributesYNon-msi feature attributes. Mostly used by pro projects.ISFeatureExtendedInstalledYTextName of the Features Installed EventISFeatureExtendedInstallingYTextName of the Features Installing EventISFeatureExtendedMiscellaneousYTextMiscellaneousISFeatureExtendedMonikerYTextUsed by pro to identify objects.ISFeatureExtendedPasswordYTextThe password for this feature.ISFeatureExtendedStatusTextYTextText displayed during file transfer in pro projects.ISFeatureExtendedUninstalledYTextName of the Features UnInstalled EventISFeatureExtendedUninstallingYTextName of the Features UnInstalling EventISFeatureMergeModuleExcludesFeature_NIdentifierForeign key into Feature table.ISFeatureMergeModuleExcludesLanguageNForeign key into ISMergeModule table.ISFeatureMergeModuleExcludesModuleIDNIdentifierForeign key into ISMergeModule table.ISFeatureMergeModulesFeature_NFeature1IdentifierForeign key into Feature table.ISFeatureMergeModulesISMergeModule_NISMergeModule1TextForeign key into ISMergeModule table.ISFeatureMergeModulesLanguage_NISMergeModule2Foreign key into ISMergeModule table.ISFeatureSetupPrerequisitesFeature_NFeature1IdentifierForeign key into Feature table.ISFeatureSetupPrerequisitesISSetupPrerequisites_NISSetupPrerequisites1 + ISFileManifestsFile_NIdentifierForeign key into File table.ISFileManifestsManifest_NIdentifierForeign key into File table.ISIISItemComponent_YComponent1IdentifierForeign key to Component table.ISIISItemDisplayNameYTextLocalizable Item Name.ISIISItemISIISItemNIdentifierPrimary key for each item.ISIISItemISIISItem_ParentYISIISItem1IdentifierThis record's parent record.ISIISItemTypeNIIS resource type.ISIISPropertyFriendlyNameYTextIIS property name.ISIISPropertyISAttributesYFlags.ISIISPropertyISIISItem_NISIISItem1IdentifierPrimary key for table, foreign key into ISIISItem.ISIISPropertyISIISPropertyNIdentifierPrimary key for table.ISIISPropertyMetaDataAttributesYIIS property attributes.ISIISPropertyMetaDataPropYIIS property ID.ISIISPropertyMetaDataTypeYIIS property data type.ISIISPropertyMetaDataUserTypeYIIS property user data type.ISIISPropertyMetaDataValueYTextIIS property value.ISIISPropertyOrderYOrder sequencing.ISIISPropertySchemaYTextIIS7 schema information.ISInstallScriptActionEntryPointNTextThis is a foreign key to the target column in the CustomAction tableISInstallScriptActionSourceNFormattedThis is column points to the source file for the DLLWrapper Custom ActionISInstallScriptActionTargetYTextThe function signatureISInstallScriptActionTypeYTypeISLanguageISLanguageNTextThis is the language ID.ISLanguageIncludedY0;1Specify whether this language should be included.ISLinkerLibraryISLinkerLibraryNIdentifierUnique identifier for the link library.ISLinkerLibraryLibraryNTextFull path of the object library (.obl file).ISLinkerLibraryOrderNOrder of the LibraryISLocalControlAttributesYA 32-bit word that specifies the attribute flags to be applied to this control.ISLocalControlBinary_YBinary1IdentifierExternal key to the Binary table.ISLocalControlControl_NControl2IdentifierName of the control. This name must be unique within a dialog, but can repeat on different dialogs.ISLocalControlDialog_NDialog1IdentifierExternal key to the Dialog table, name of the dialog.ISLocalControlHeightYHeight of the bounding rectangle of the control.ISLocalControlISBuildSourcePathYTextFull path to .rtf file for scrollable text controlISLocalControlISLanguage_NISLanguage1TextThis is a foreign key to the ISLanguage table.ISLocalControlWidthYWidth of the bounding rectangle of the control.ISLocalControlXYHorizontal coordinate of the upper left corner of the bounding rectangle of the control.ISLocalControlYYVertical coordinate of the upper left corner of the bounding rectangle of the control.ISLocalDialogAttributesYA 32-bit word that specifies the attribute flags to be applied to this dialog.ISLocalDialogDialog_YDialog1IdentifierName of the dialog.ISLocalDialogHeightN032767Height of the bounding rectangle of the dialog.ISLocalDialogISLanguage_YISLanguage1TextThis is a foreign key to the ISLanguage table.ISLocalDialogTextStyle_YIdentifierForeign Key into TextStyle table, only used in Script Based Projects.ISLocalDialogWidthN032767Width of the bounding rectangle of the dialog.ISLocalRadioButtonHeightN032767The height of the button.ISLocalRadioButtonISLanguage_NISLanguage1TextThis is a foreign key to the ISLanguage table.ISLocalRadioButtonOrderN132767RadioButton2A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.ISLocalRadioButtonPropertyNRadioButton1IdentifierA named property to be tied to this radio button. All the buttons tied to the same property become part of the same group.ISLocalRadioButtonWidthN032767The width of the button.ISLocalRadioButtonXN032767The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button.ISLocalRadioButtonYN032767The vertical coordinate of the upper left corner of the bounding rectangle of the radio button.ISLockPermissionsAttributesY-21474836472147483647Permissions attributes mask, 1==Deny access; 2==No inheritISLockPermissionsDomainYTextDomain name for user whose permissions are being set.ISLockPermissionsLockObjectNIdentifierForeign key into CreateFolder, Registry, or File tableISLockPermissionsPermissionY-21474836472147483647Permission Access mask.ISLockPermissionsTableNIdentifierCreateFolder;File;RegistryReference to another table nameISLockPermissionsUserNTextUser for permissions to be set. This can be a property, hardcoded named, or SID stringISLogicalDiskCabinetYCabinetIf some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet.ISLogicalDiskDiskIdN132767Primary key, integer to determine sort order for table.ISLogicalDiskDiskPromptYTextDisk name: the visible text actually printed on the disk. This will be used to prompt the user when this disk needs to be inserted.ISLogicalDiskISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table.ISLogicalDiskISRelease_NISRelease1TextForeign key into the ISRelease table.ISLogicalDiskLastSequenceN032767File sequence number for the last file for this media.ISLogicalDiskSourceYPropertyThe property defining the location of the cabinet file.ISLogicalDiskVolumeLabelYTextThe label attributed to the volume.ISLogicalDiskFeaturesFeature_YFeature1IdentifierRequired foreign key into the Feature Table,ISLogicalDiskFeaturesISAttributesYThis is used to store Installshield custom properties, like Compressed, etc.ISLogicalDiskFeaturesISLogicalDisk_N132767ISLogicalDisk1IdentifierForeign key into the ISLogicalDisk table.ISLogicalDiskFeaturesISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table.ISLogicalDiskFeaturesISRelease_NISRelease1TextForeign key into the ISRelease table.ISLogicalDiskFeaturesSequenceN032767File sequence number for the file for this media.ISMergeModuleDestinationYTextDestination.ISMergeModuleISAttributesYThis is used to store Installshield custom properties of a merge module.ISMergeModuleISMergeModuleNTextThe GUID identifying the merge module.ISMergeModuleLanguageNDefault decimal language of module.ISMergeModuleNameNTextName of the merge module.ISMergeModuleCfgValuesAttributesYAttributes (from configurable merge module)ISMergeModuleCfgValuesContextDataYTextContextData (from configurable merge module)ISMergeModuleCfgValuesDefaultValueYTextDefaultValue (from configurable merge module)ISMergeModuleCfgValuesDescriptionYTextDescription (from configurable merge module)ISMergeModuleCfgValuesDisplayNameYTextDisplayName (from configurable merge module)ISMergeModuleCfgValuesFormatNFormat (from configurable merge module)ISMergeModuleCfgValuesHelpKeywordYTextHelpKeyword (from configurable merge module)ISMergeModuleCfgValuesHelpLocationYTextHelpLocation (from configurable merge module)ISMergeModuleCfgValuesISMergeModule_NISMergeModule1TextThe module signature, a foreign key into the ISMergeModule tableISMergeModuleCfgValuesLanguage_NISMergeModule2Default decimal language of module.ISMergeModuleCfgValuesModuleConfiguration_NIdentifierIdentifier, foreign key into ModuleConfiguration table (ModuleConfiguration.Name)ISMergeModuleCfgValuesTypeYTextType (from configurable merge module)ISMergeModuleCfgValuesValueYTextValue for this item.ISObjectLanguageNText + ISObjectObjectNameNText + ISObjectPropertyIncludeInBuildYBoolean, 0 for false non 0 for trueISObjectPropertyObjectNameYISObject1Text + ISObjectPropertyPropertyYText + ISObjectPropertyValueYText + ISPalmAppComponentNComponent1 + ISPalmAppPalmAppN + ISPalmAppFileDestinationN + ISPalmAppFileFileKeyNFile1 + ISPalmAppFilePalmAppNISPalmApp1 + ISPatchConfigImagePatchConfiguration_YISPatchConfiguration1TextForeign key to the ISPatchConfigurationTableISPatchConfigImageUpgradedImage_NISUpgradedImage1TextForeign key to the ISUpgradedImageTableISPatchConfigurationAttributesYPatchConfiguration attributesISPatchConfigurationCanPCDifferNThis is determine whether Product Codes may differISPatchConfigurationCanPVDifferNThis is determine whether the Major Product Version may differISPatchConfigurationEnablePatchCacheNThis is determine whether to Enable Patch cacheingISPatchConfigurationFlagsNPatching API FlagsISPatchConfigurationIncludeWholeFilesNThis is determine whether to build a binary level patchISPatchConfigurationLeaveDecompressedNThis is determine whether to leave intermediate files devcompressed when finishedISPatchConfigurationMinMsiVersionNMinimum Required MSI VersionISPatchConfigurationNameNTextName of the Patch ConfigurationISPatchConfigurationOptimizeForSizeNThis is determine whether to Optimize for large filesISPatchConfigurationOutputPathNTextBuild LocationISPatchConfigurationPatchCacheDirYTextDirectory to recieve the Patch Cache informationISPatchConfigurationPatchGuidNTextUnique Patch IdentifierISPatchConfigurationPatchGuidsToReplaceYTextList Of Patch Guids to unregisterISPatchConfigurationTargetProductCodesNTextList Of target Product CodesISPatchConfigurationPropertyISPatchConfiguration_YISPatchConfiguration1TextName of the Patch ConfigurationISPatchConfigurationPropertyPropertyYTextName of the Patch Configuration Property valueISPatchConfigurationPropertyValueYTextValue of the Patch Configuration PropertyISPatchExternalFileFileKeyNTextFilekeyISPatchExternalFileFilePathNTextFilepathISPatchExternalFileISUpgradedImage_NISUpgradedImage1TextForeign key to the isupgraded image tableISPatchExternalFileNameNTextUniqu name to identify this record.ISPatchWholeFileComponentYTextComponent containing file keyISPatchWholeFileFileKeyNTextKey of file to be included as wholeISPatchWholeFileUpgradedImageNISUpgradedImage1TextForeign key to ISUpgradedImage TableISPathVariableISPathVariableNThe name of the path variable.ISPathVariableTestValueYTextThe test value of the path variable.ISPathVariableTypeN1;2;4;8The type of the path variable.ISPathVariableValueYTextThe value of the path variable.ISProductConfigurationGeneratePackageCodeYNumber0;1Indicates whether or not to generate a package code.ISProductConfigurationISProductConfigurationNTextThe name of the product configuration.ISProductConfigurationProductConfigurationFlagsYTextProduct configuration (release) flags.ISProductConfigurationInstanceISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table.ISProductConfigurationInstanceInstanceIdN032767Identifies the instance number of this instance. This value is stored in the Property InstanceId.ISProductConfigurationInstancePropertyNTextProduct Congiuration property nameISProductConfigurationInstanceValueNTextString value for property.ISProductConfigurationPropertyISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table.ISProductConfigurationPropertyPropertyNProperty1TextProduct Congiuration property nameISProductConfigurationPropertyValueYTextString value for property. Never null or empty.ISReleaseAttributesNBitfield holding boolean values for various release attributes.ISReleaseBuildLocationNTextBuild location.ISReleaseCDBrowserYTextDemoshield browser location.ISReleaseDefaultLanguageNTextDefault language for setup.ISReleaseDigitalPVKYTextDigital signing private key (.pvk) file.ISReleaseDigitalSPCYTextDigital signing Software Publisher Certificate (.spc) file.ISReleaseDigitalURLYTextDigital signing URL.ISReleaseDiskClusterSizeNDisk cluster size.ISReleaseDiskSizeNTextDisk size.ISReleaseDiskSizeUnitN0;1;2Disk size units (KB or MB).ISReleaseDiskSpanningN0;1;2Disk spanning (automatic, enforce size, etc.).ISReleaseDotNetBuildConfigurationYTextBuild Configuration for .NET solutions.ISReleaseISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table.ISReleaseISReleaseNTextThe name of the release.ISReleaseISSetupPrerequisiteLocationY0;1;2;3Location the Setup Prerequisites will be placed inISReleaseMediaLocationNTextMedia location on disk.ISReleaseMsiCommandLineYTextCommand line passed to the msi package from setup.exeISReleaseMsiSourceTypeN-14MSI media source type.ISReleasePackageNameNTextPackage name.ISReleasePasswordYTextPassword.ISReleasePlatformsNTextPlatforms supported (Intel, Alpha, etc.).ISReleaseReleaseFlagsYTextRelease flags.ISReleaseReleaseTypeN1;2;4Release type (single, uncompressed, etc.).ISReleaseSupportedLanguagesDataYTextLanguages supported (for component filtering).ISReleaseSupportedLanguagesUINTextUI languages supported.ISReleaseSupportedOSsNIndicate which operating systmes are supported.ISReleaseSynchMsiYTextMSI file to synchronize file keys and other data with (patch-like functionality).ISReleaseTypeN06Release type (CDROM, Network, etc.).ISReleaseURLLocationYTextMedia location via URL.ISReleaseVersionCopyrightYTextVersion stamp information.ISReleaseExtendedAttributesYBitfield holding boolean values for various release attributes.ISReleaseExtendedCertPasswordYTextDigital certificate passwordISReleaseExtendedDigitalCertificateDBaseNSYTextPath to cerificate database for Netscape digital signatureISReleaseExtendedDigitalCertificateIdNSYTextPath to cerificate ID for Netscape digital signatureISReleaseExtendedDigitalCertificatePasswordNSYTextPassword for Netscape digital signatureISReleaseExtendedDotNetBaseLanguageYTextBase Languge of .NET RedistISReleaseExtendedDotNetFxCmdLineYTextCommand Line to pass to DotNetFx.exeISReleaseExtendedDotNetLangPackCmdLineYTextCommand Line to pass to LangPack.exeISReleaseExtendedDotNetLangaugePacksYText.NET Redist language packs to includeISReleaseExtendedDotNetRedistLocationY03Location of .NET framework Redist (Web, SetupExe, Source, None)ISReleaseExtendedDotNetRedistURLYTextURL to .NET framework RedistISReleaseExtendedDotNetVersionY02Version of .NET framework Redist (1.0, 1.1)ISReleaseExtendedEngineLocationY02Location of msi engine (Web, SetupExe...)ISReleaseExtendedISEngineLocationY02Location of ISScript engine (Web, SetupExe...)ISReleaseExtendedISEngineURLYTextURL to InstallShield scripting engineISReleaseExtendedISProductConfiguration_NTextForeign key into the ISProductConfiguration table.ISReleaseExtendedISRelease_NTextThe name of the release.ISReleaseExtendedJSharpCmdLineYTextCommand Line to pass to vjredist.exeISReleaseExtendedJSharpRedistLocationY03Location of J# framework Redist (Web, SetupExe, Source, None)ISReleaseExtendedMsiEngineVersionYBitfield holding selected MSI engine versions included in this releaseISReleaseExtendedOneClickCabNameYTextFile name of generated cabfileISReleaseExtendedOneClickHtmlNameYTextFile name of generated html pageISReleaseExtendedOneClickTargetBrowserY02Target browser (IE, Netscape, both...)ISReleaseExtendedWebCabSizeY02147483647Size of the cabfileISReleaseExtendedWebLocalCachePathYTextDirectory to cache downloaded packageISReleaseExtendedWebTypeY02Type of web install (One Executable, Downloader...)ISReleaseExtendedWebURLYTextURL to .msi packageISReleaseExtendedWin9xMsiUrlYTextURL to Ansi MSI engineISReleaseExtendedWinMsi30UrlYTextURL to MSI 3.0 engineISReleaseExtendedWinNTMsiUrlYTextURL to Unicode MSI engineISReleasePropertyISProductConfiguration_NTextForeign key into ISProductConfiguration table.ISReleasePropertyISRelease_NTextForeign key into ISRelease table.ISReleasePropertyNameNProperty nameISReleasePropertyValueNProperty valueISReleasePublishInfoDescriptionYTextRepository item descriptionISReleasePublishInfoDisplayNameYTextRepository item display nameISReleasePublishInfoISAttributesYBitfield holding various attributesISReleasePublishInfoISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table.ISReleasePublishInfoISRelease_NISRelease1TextThe name of the release.ISReleasePublishInfoPublisherYTextRepository item publisherISReleasePublishInfoRepositoryYTextRepository which to publish the built merge moduleISRequiredFeatureRequiredFeatureNFeature1IdentifierThis feature is required by the feature in the RequiringFeature columnISRequiredFeatureRequiringFeatureNFeature1IdentifierThis feature requires the feature in the RequiredFeature columnISSQLConnectionAttributesN + ISSQLConnectionAuthenticationN + ISSQLConnectionBatchSeparatorY + ISSQLConnectionCmdTimeoutY + ISSQLConnectionCommentsY + ISSQLConnectionDatabaseN + ISSQLConnectionISSQLConnectionNIdentifierPrimary key used to identify a particular ISSQLConnection record.ISSQLConnectionOrderN + ISSQLConnectionPasswordN + ISSQLConnectionScriptVersion_ColumnY + ISSQLConnectionScriptVersion_TableY + ISSQLConnectionServerN + ISSQLConnectionUserNameN + ISSQLConnectionDBServerISSQLConnectionDBServerNIdentifierPrimary key used to identify a particular ISSQLConnectionDBServer record.ISSQLConnectionDBServerISSQLConnection_NISSQLConnection1IdentifierForeign key into ISSQLConnection table.ISSQLConnectionDBServerISSQLDBMetaData_NISSQLDBMetaData1IdentifierForeign key into ISSQLDBMetaData table.ISSQLConnectionDBServerOrderN + ISSQLConnectionScriptISSQLConnection_NISSQLConnection1IdentifierForeign key into ISSQLConnection table.ISSQLConnectionScriptISSQLScriptFile_NISSQLScriptFile1IdentifierForeign key into ISSQLScriptFile table.ISSQLConnectionScriptOrderN + ISSQLDBMetaDataAdoCxnAdditionalY + ISSQLDBMetaDataAdoCxnDatabaseY + ISSQLDBMetaDataAdoCxnDriverY + ISSQLDBMetaDataAdoCxnNetLibraryY + ISSQLDBMetaDataAdoCxnPasswordY + ISSQLDBMetaDataAdoCxnPortY + ISSQLDBMetaDataAdoCxnServerY + ISSQLDBMetaDataAdoCxnUserIDY + ISSQLDBMetaDataAdoCxnWindowsSecurityY + ISSQLDBMetaDataAdoDriverNameY + ISSQLDBMetaDataCreateDbCmdY + ISSQLDBMetaDataCreateTableCmdY + ISSQLDBMetaDataDisplayNameY + ISSQLDBMetaDataDsnODBCNameY + ISSQLDBMetaDataISAttributesY + ISSQLDBMetaDataISSQLDBMetaDataNIdentifierPrimary key used to identify a particular ISSQLDBMetaData record.ISSQLDBMetaDataInsertRecordCmdY + ISSQLDBMetaDataLocalInstanceNamesY + ISSQLDBMetaDataQueryDatabasesCmdY + ISSQLDBMetaDataScriptVersion_ColumnY + ISSQLDBMetaDataScriptVersion_ColumnTypeY + ISSQLDBMetaDataScriptVersion_TableY + ISSQLDBMetaDataSelectTableCmdY + ISSQLDBMetaDataSwitchDbCmdY + ISSQLDBMetaDataTestDatabaseCmdY + ISSQLDBMetaDataTestTableCmdY + ISSQLDBMetaDataTestTableCmd2Y + ISSQLDBMetaDataVersionBeginTokenY + ISSQLDBMetaDataVersionEndTokenY + ISSQLDBMetaDataVersionInfoCmdY + ISSQLDBMetaDataWinAuthentUserIdY + ISSQLRequirementAttributesN + ISSQLRequirementISSQLConnectionDBServer_YISSQLConnectionDBServer1IdentifierForeign key into ISSQLConnectionDBServer table.ISSQLRequirementISSQLConnection_NISSQLConnection1IdentifierForeign key into ISSQLConnection table.ISSQLRequirementISSQLRequirementNIdentifierPrimary key used to identify a particular ISSQLRequirement record.ISSQLRequirementMajorVersionY + ISSQLRequirementServicePackLevelY + ISSQLScriptErrorAttributesN + ISSQLScriptErrorErrHandlingN + ISSQLScriptErrorErrNumberN + ISSQLScriptErrorISSQLScriptFile_YISSQLScriptFile1IdentifierForeign key into ISSQLScriptFile tableISSQLScriptErrorMessageYTextCustom end-user message. Reserved for future use.ISSQLScriptFileAttributesN + ISSQLScriptFileCommentsYTextCommentsISSQLScriptFileComponent_NComponent1IdentifierForeign key referencing Component that controls the SQL script.ISSQLScriptFileConditionYConditionA conditional statement that will disable this script if the specified condition evaluates to the 'False' state. If a script is disabled, it will not be installed regardless of the 'Action' state associated with the component.ISSQLScriptFileErrorHandlingN + ISSQLScriptFileISBuildSourcePathYTextFull path, the category is of Text instead of Path because of potential use of path variables.ISSQLScriptFileISSQLScriptFileNIdentifierThis is the primary key to the ISSQLScriptFile tableISSQLScriptFileInstallTextYTextFeedback end-user text at installISSQLScriptFileSchedulingN + ISSQLScriptFileUninstallTextYTextFeedback end-user text at UninstallISSQLScriptFileVersionYTextSchema Version (####.#####.####)ISSQLScriptImportAttributesN + ISSQLScriptImportAuthenticationN + ISSQLScriptImportDatabaseY + ISSQLScriptImportExcludeTablesY + ISSQLScriptImportISSQLScriptFile_NISSQLScriptFile1IdentifierForeign key into ISSQLScriptFile table.ISSQLScriptImportIncludeTablesY + ISSQLScriptImportPasswordY + ISSQLScriptImportServerY + ISSQLScriptImportUserNameY + ISSQLScriptReplaceAttributesN + ISSQLScriptReplaceISSQLScriptFile_NISSQLScriptFile1IdentifierForeign key into ISSQLScriptFile table.ISSQLScriptReplaceISSQLScriptReplaceNIdentifierPrimary key used to identify a particular ISSQLScriptReplace record.ISSQLScriptReplaceReplaceY + ISSQLScriptReplaceSearchY + ISScriptFileISScriptFileNTextThis is the full path of the script file. The path portion may be expressed in path variable form.ISSearchReplaceAttributesN + ISSearchReplaceISSearchReplaceNIdentifierPrimary key used to identify a particular ISSearchReplace record.ISSearchReplaceISSearchReplaceSet_NISSearchReplaceSet1IdentifierForeign key referencing ISSearchReplaceSet.ISSearchReplaceOrderN + ISSearchReplaceReplaceY + ISSearchReplaceSearchY + ISSearchReplaceSetAttributesN + ISSearchReplaceSetCodePageN + ISSearchReplaceSetComponent_NComponent1IdentifierForeign key referencing Component that controls the text file change.ISSearchReplaceSetDirectory_NDirectory1IdentifierForeign key referencing Directory that contains the text files.ISSearchReplaceSetExcludeFilesY + ISSearchReplaceSetISSearchReplaceSetNIdentifierPrimary key used to identify a particular ISSearchReplaceSet record.ISSearchReplaceSetIncludeFilesY + ISSearchReplaceSetOrderN + ISSelfRegCmdLineY + ISSelfRegCostY + ISSelfRegFileKeyNFile1IdentifierForeign key to the file tableISSelfRegOrderY + ISSetupFileFileNameYTextThis is the file name to use when streaming the file to the support files locationISSetupFileISSetupFileNIdentifierThis is the primary key to the ISSetupFile tableISSetupFileLanguageYTextFour digit language identifier. 0 for Language NeutralISSetupFilePathYTextLink to the source file on the build machineISSetupFileSplashYShortBoolean value indication whether his setup file entry belongs in the Splasc Screen sectionISSetupFileStreamYBinaryBinary stream. The bits to stream to the support locationISSetupPrerequisitesISBuildSourcePathY + ISSetupPrerequisitesISReleaseFlagsYRelease Flags that specify whether this prereq will be included in a particular release.ISSetupPrerequisitesISSetupLocationY0;1;2 + ISSetupPrerequisitesISSetupPrerequisitesN + ISSetupPrerequisitesOrderY + ISSetupTypeCommentsYTextUser Comments.ISSetupTypeDescriptionYTextLonger descriptive text describing a visible feature item.ISSetupTypeDisplayN032767Numeric sort order, used to force a specific display ordering.ISSetupTypeDisplay_NameYFormattedA string used to set the initial text contained within a control (if appropriate).ISSetupTypeISSetupTypeNIdentifierPrimary key used to identify a particular feature record.ISSetupTypeFeaturesFeature_NFeature1IdentifierForeign key into Feature table.ISSetupTypeFeaturesISSetupType_NISSetupType1IdentifierForeign key into ISSetupType table.ISStoragesISBuildSourcePathYPath to the file to stream into sub-storageISStoragesNameNName of the sub-storage keyISStringCommentYTextCommentISStringEncodedYEncoding for multi-byte strings.ISStringISLanguage_NTextThis is a foreign key to the ISLanguage table.ISStringISStringNTextString id.ISStringTimeStampYTime/DateTime Stamp. MSI's Time/Date column type is just an int, with bits packed in a certain order.ISStringValueYTextreal string value.ISTargetImageFlagsYrelative order of the target imageISTargetImageIgnoreMissingFilesNIf true, ignore missing source files when creating patchISTargetImageMsiPathNTextPath to the target imageISTargetImageNameNIdentifierName of the TargetImageISTargetImageOrderNrelative order of the target imageISTargetImageUpgradedImage_NISUpgradedImage1Textforeign key to the upgraded Image tableISUpgradeMsiItemISAttributesN0;1 + ISUpgradeMsiItemISReleaseFlagsY + ISUpgradeMsiItemObjectSetupPathNTextThe path to the setup you want to upgrade.ISUpgradeMsiItemUpgradeItemNTextThe name of the Upgrade Item.ISUpgradedImageFamilyNTextName of the image familyISUpgradedImageMsiPathNTextPath to the upgraded imageISUpgradedImageNameNIdentifierName of the UpgradedImageISVirtualDirectoryDirectory_NDirectory1IdentifierForeign key into Directory table.ISVirtualDirectoryNameNIdentifierProperty nameISVirtualDirectoryValueNProperty valueISVirtualFileFile_NFile1IdentifierForeign key into File table.ISVirtualFileNameNIdentifierProperty nameISVirtualFileValueNProperty valueISVirtualPackageNameNIdentifierProperty nameISVirtualPackageValueNProperty valueISVirtualRegistryNameNIdentifierProperty nameISVirtualRegistryRegistry_NRegistry1IdentifierForeign key into Registry table.ISVirtualRegistryValueNProperty valueISVirtualReleaseISProductConfiguration_NTextForeign key into ISProductConfiguration table.ISVirtualReleaseISRelease_NTextForeign key into ISRelease table.ISVirtualReleaseNameNProperty nameISVirtualReleaseValueNProperty valueISVirtualShortcutNameNIdentifierProperty nameISVirtualShortcutShortcut_NShortcut1IdentifierForeign key into Shortcut table.ISVirtualShortcutValueNProperty valueISXmlElementContentYTextElement contentsISXmlElementISAttributesYNumberInternal XML element attributesISXmlElementISXmlElementNIdentifierPrimary key, non-localized, internal token for Xml elementISXmlElementISXmlElement_ParentYISXmlElement1IdentifierForeign key into ISXMLElement table.ISXmlElementISXmlFile_NISXmlFile1IdentifierForeign key into XmlFile table.ISXmlElementXPathYTextXPath fragment including any operatorsISXmlElementAttribISAttributesYNumberInternal XML elementattib attributesISXmlElementAttribISXmlElementAttribNIdentifierPrimary key, non-localized, internal token for Xml element attributeISXmlElementAttribISXmlElement_NISXmlElement1IdentifierForeign key into ISXMLElement table.ISXmlElementAttribNameYTextLocalized attribute nameISXmlElementAttribValueYTextLocalized attribute valueISXmlFileComponent_NComponent1IdentifierForeign key into Component table.ISXmlFileDirectoryNIdentifierForeign key into Directory table.ISXmlFileEncodingYTextXML File EncodingISXmlFileFileNameNTextLocalized XML file nameISXmlFileISAttributesYNumberInternal XML file attributesISXmlFileISXmlFileNIdentifierPrimary key, non-localized,internal token for Xml fileISXmlFileSelectionNamespacesYTextSelection namespacesISXmlLocatorAttributeYThe name of an attribute within the XML element.ISXmlLocatorElementYXPath query that will locate an element in an XML file.ISXmlLocatorISAttributesY0;1;2 + ISXmlLocatorParentYIdentifierThe parent file signature. It is also a foreign key in the Signature table.ISXmlLocatorSignature_NIdentifierThe Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, ISXmlLocator, CompLocator and the DrLocator tables.IconDataYBinaryBinary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.IconISBuildSourcePathYTextFull path to the ICO or EXE file.IconISIconIndexY-3276732767Optional icon index to be extracted.IconNameNIdentifierPrimary key. Name of the icon file.IniFileActionN0;1;3The type of modification to be made, one of iifEnumIniFileComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the installing of the .INI value.IniFileDirPropertyYIdentifierForeign key into the Directory table denoting the directory where the .INI file is.IniFileFileNameNTextThe .INI file name in which to write the informationIniFileIniFileNIdentifierPrimary key, non-localized token.IniFileKeyNFormattedThe .INI file key below Section.IniFileSectionNFormattedThe .INI file Section.IniFileValueNFormattedThe value to be written.IniLocatorFieldY032767The field in the .INI line. If Field is null or 0 the entire line is read.IniLocatorFileNameNTextThe .INI file name.IniLocatorKeyNTextKey value (followed by an equals sign in INI file).IniLocatorSectionNTextSection name within in file (within square brackets in INI file).IniLocatorSignature_NSignature1IdentifierThe table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.IniLocatorTypeY02An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation.InstallExecuteSequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL.InstallExecuteSequenceConditionYConditionOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.InstallExecuteSequenceISAttributesYThis is used to store MM Custom Action TypesInstallExecuteSequenceISCommentsYTextAuthor’s comments on this Sequence.InstallExecuteSequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.InstallShieldPropertyNIdentifierName of property, uppercase if settable by launcher or loader.InstallShieldValueYTextString value for property.InstallUISequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL.InstallUISequenceConditionYConditionOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.InstallUISequenceISAttributesYThis is used to store MM Custom Action TypesInstallUISequenceISCommentsYTextAuthor’s comments on this Sequence.InstallUISequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.IsolatedComponentComponent_ApplicationNComponent1IdentifierKey to Component table item for applicationIsolatedComponentComponent_SharedNComponent1IdentifierKey to Component table item to be isolatedLaunchConditionConditionNConditionExpression which must evaluate to TRUE in order for install to commence.LaunchConditionDescriptionNTextLocalizable text to display when condition fails and install must abort.ListBoxOrderN132767A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.ListBoxPropertyNIdentifierA named property to be tied to this item. All the items tied to the same property become part of the same listbox.ListBoxTextYTextThe visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.ListBoxValueNFormattedThe value string associated with this item. Selecting the line will set the associated property to this value.ListViewBinary_YBinary1IdentifierThe name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table.ListViewOrderN132767A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.ListViewPropertyNIdentifierA named property to be tied to this item. All the items tied to the same property become part of the same listview.ListViewTextYTextThe visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.ListViewValueNTextThe value string associated with this item. Selecting the line will set the associated property to this value.LockPermissionsDomainYTextDomain name for user whose permissions are being set. (usually a property)LockPermissionsLockObjectNIdentifierForeign key into Registry or File tableLockPermissionsPermissionY-21474836472147483647Permission Access mask. Full Control = 268435456 (GENERIC_ALL = 0x10000000)LockPermissionsTableNIdentifierDirectory;File;RegistryReference to another table nameLockPermissionsUserNTextUser for permissions to be set. (usually a property)MIMECLSIDYClass1GuidOptional associated CLSID.MIMEContentTypeNTextPrimary key. Context identifier, typically "type/format".MIMEExtension_NExtension1TextOptional associated extension (without dot)MediaCabinetYCabinetIf some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet.MediaDiskIdN132767Primary key, integer to determine sort order for table.MediaDiskPromptYTextDisk name: the visible text actually printed on the disk. This will be used to prompt the user when this disk needs to be inserted.MediaLastSequenceN032767File sequence number for the last file for this media.MediaSourceYPropertyThe property defining the location of the cabinet file.MediaVolumeLabelYTextThe label attributed to the volume.MoveFileComponent_NComponent1IdentifierIf this component is not "selected" for installation or removal, no action will be taken on the associated MoveFile entryMoveFileDestFolderNIdentifierName of a property whose value is assumed to resolve to the full path to the destination directoryMoveFileDestNameYTextName to be given to the original file after it is moved or copied. If blank, the destination file will be given the same name as the source fileMoveFileFileKeyNIdentifierPrimary key that uniquely identifies a particular MoveFile recordMoveFileOptionsN01Integer value specifying the MoveFile operating mode, one of imfoEnumMoveFileSourceFolderYIdentifierName of a property whose value is assumed to resolve to the full path to the source directoryMoveFileSourceNameYTextName of the source file(s) to be moved or copied. Can contain the '*' or '?' wildcards.MsiAssemblyAttributesYAssembly attributesMsiAssemblyComponent_NComponent1IdentifierForeign key into Component table.MsiAssemblyFeature_NFeature1IdentifierForeign key into Feature table.MsiAssemblyFile_ApplicationYFile1IdentifierForeign key into File table, denoting the application context for private assemblies. Null for global assemblies.MsiAssemblyFile_ManifestYFile1IdentifierForeign key into the File table denoting the manifest file for the assembly.MsiAssemblyNameComponent_NComponent1IdentifierForeign key into Component table.MsiAssemblyNameNameNTextThe name part of the name-value pairs for the assembly name.MsiAssemblyNameValueNTextThe value part of the name-value pairs for the assembly name.MsiDigitalCertificateCertDataNBinaryA certificate context blob for a signer certificateMsiDigitalCertificateDigitalCertificateNMsiPackageCertificate2IdentifierA unique identifier for the rowMsiDigitalSignatureDigitalCertificate_NMsiDigitalCertificate1IdentifierForeign key to MsiDigitalCertificate table identifying the signer certificateMsiDigitalSignatureHashYBinaryThe encoded hash blob from the digital signatureMsiDigitalSignatureSignObjectNTextForeign key to Media tableMsiDigitalSignatureTableNIdentifierReference to another table name (only Media table is supported)MsiDriverPackagesComponentNComponent1IdentifierPrimary key used to identify a particular component record.MsiDriverPackagesFlagsNDriver package flagsMsiDriverPackagesReferenceComponentsY + MsiDriverPackagesSequenceYInstallation sequence numberMsiEmbeddedChainerCommandLineYFormatted + MsiEmbeddedChainerConditionYCondition + MsiEmbeddedChainerMsiEmbeddedChainerNIdentifier + MsiEmbeddedChainerSourceNCustomSource + MsiEmbeddedChainerTypeYInteger2;18;50 + MsiEmbeddedUIAttributesN03IntegerInformation about the data in the Data column.MsiEmbeddedUIDataYBinaryThis column contains binary information.MsiEmbeddedUIFileNameNFilenameThe name of the file that receives the binary information in the Data column.MsiEmbeddedUIISBuildSourcePathYText + MsiEmbeddedUIMessageFilterY0234913791IntegerSpecifies the types of messages that are sent to the user interface DLL. This column is only relevant for rows with the msidbEmbeddedUI attribute.MsiEmbeddedUIMsiEmbeddedUINIdentifierThe primary key for the table.MsiFileHashFile_NFile1IdentifierPrimary key, foreign key into File table referencing file with this hashMsiFileHashHashPart1NSize of file in bytes (long integer).MsiFileHashHashPart2NSize of file in bytes (long integer).MsiFileHashHashPart3NSize of file in bytes (long integer).MsiFileHashHashPart4NSize of file in bytes (long integer).MsiFileHashOptionsN032767Various options and attributes for this hash.MsiLockPermissionsExConditionYFormattedExpression which must evaluate to TRUE in order for this set of permissions to be appliedMsiLockPermissionsExLockObjectNIdentifierForeign key into Registry, File, CreateFolder, or ServiceInstall tableMsiLockPermissionsExMsiLockPermissionsExNIdentifierPrimary key, non-localized tokenMsiLockPermissionsExSDDLTextNFormattedSDDLTextString to indicate permissions to be applied to the LockObjectMsiLockPermissionsExTableNIdentifierCreateFolder;File;Registry;ServiceInstallReference to another table nameMsiPackageCertificateDigitalCertificate_NIdentifierA foreign key to the digital certificate tableMsiPackageCertificatePackageCertificateNIdentifierA unique identifier for the rowMsiPatchCertificateDigitalCertificate_NMsiDigitalCertificate1IdentifierA foreign key to the digital certificate tableMsiPatchCertificatePatchCertificateNIdentifierA unique identifier for the rowMsiPatchMetadataCompanyYTextOptional company nameMsiPatchMetadataPatchConfiguration_NISPatchConfiguration1TextForeign key to the ISPatchConfiguration tableMsiPatchMetadataPropertyNTextName of the metadataMsiPatchMetadataValueYTextValue of the metadataMsiPatchOldAssemblyFileAssembly_YMsiPatchOldAssemblyName1 + MsiPatchOldAssemblyFileFile_NFile1 + MsiPatchOldAssemblyNameAssemblyN + MsiPatchOldAssemblyNameNameN + MsiPatchOldAssemblyNameValueY + MsiPatchSequencePatchConfiguration_NISPatchConfiguration1TextForeign key to the patch configuration tableMsiPatchSequencePatchFamilyNTextName of the family to which this patch belongsMsiPatchSequenceSequenceNVersionThe version of this patch in this familyMsiPatchSequenceSupersedeNIntegerSupersedeMsiPatchSequenceTargetYTextTarget product codes for this patch familyMsiServiceConfigArgumentYTextArgument(s) for service configuration. Value depends on the content of the ConfigType fieldMsiServiceConfigComponent_NComponent1IdentifierRequired foreign key into the Component Table that controls the configuration of the serviceMsiServiceConfigConfigTypeN-21474836472147483647Service Configuration OptionMsiServiceConfigEventN07Bit field: 0x1 = Install, 0x2 = Uninstall, 0x4 = ReinstallMsiServiceConfigMsiServiceConfigNIdentifierPrimary key, non-localized token.MsiServiceConfigNameNFormattedName of a service. /, \, comma and space are invalidMsiServiceConfigFailureActionsActionsYTextA list of integer actions separated by [~] delimiters: 0 = SC_ACTION_NONE, 1 = SC_ACTION_RESTART, 2 = SC_ACTION_REBOOT, 3 = SC_ACTION_RUN_COMMAND. Terminate with [~][~]MsiServiceConfigFailureActionsCommandYFormattedCommand line of the process to CreateProcess function to executeMsiServiceConfigFailureActionsComponent_NComponent1IdentifierRequired foreign key into the Component Table that controls the configuration of the serviceMsiServiceConfigFailureActionsDelayActionsYTextA list of delays (time in milli-seconds), separated by [~] delmiters, to wait before taking the corresponding Action. Terminate with [~][~]MsiServiceConfigFailureActionsEventN07Bit field: 0x1 = Install, 0x2 = Uninstall, 0x4 = ReinstallMsiServiceConfigFailureActionsMsiServiceConfigFailureActionsNIdentifierPrimary key, non-localized tokenMsiServiceConfigFailureActionsNameNFormattedName of a service. /, \, comma and space are invalidMsiServiceConfigFailureActionsRebootMessageYFormattedMessage to be broadcast to server users before rebootingMsiServiceConfigFailureActionsResetPeriodY02147483647Time in seconds after which to reset the failure count to zero. Leave blank if it should never be resetMsiShortcutPropertyMsiShortcutPropertyNIdentifierPrimary key, non-localized tokenMsiShortcutPropertyPropVariantValueNFormattedString representation of the value in the propertyMsiShortcutPropertyPropertyKeyNFormattedCanonical string representation of the Property Key being setMsiShortcutPropertyShortcut_NShortcut1IdentifierForeign key into the Shortcut tableODBCAttributeAttributeNTextName of ODBC driver attributeODBCAttributeDriver_NODBCDriver1IdentifierReference to ODBC driver in ODBCDriver tableODBCAttributeValueYTextValue for ODBC driver attributeODBCDataSourceComponent_NComponent1IdentifierReference to associated componentODBCDataSourceDataSourceNIdentifierPrimary key, non-localized.internal token for data sourceODBCDataSourceDescriptionNTextText used as registered name for data sourceODBCDataSourceDriverDescriptionNTextReference to driver description, may be existing driverODBCDataSourceRegistrationN01Registration option: 0=machine, 1=user, others t.b.d.ODBCDriverComponent_NComponent1IdentifierReference to associated componentODBCDriverDescriptionNTextText used as registered name for driver, non-localizedODBCDriverDriverNIdentifierPrimary key, non-localized.internal token for driverODBCDriverFile_NFile1IdentifierReference to key driver fileODBCDriverFile_SetupYFile1IdentifierOptional reference to key driver setup DLLODBCSourceAttributeAttributeNTextName of ODBC data source attributeODBCSourceAttributeDataSource_NODBCDataSource1IdentifierReference to ODBC data source in ODBCDataSource tableODBCSourceAttributeValueYTextValue for ODBC data source attributeODBCTranslatorComponent_NComponent1IdentifierReference to associated componentODBCTranslatorDescriptionNTextText used as registered name for translatorODBCTranslatorFile_NFile1IdentifierReference to key translator fileODBCTranslatorFile_SetupYFile1IdentifierOptional reference to key translator setup DLLODBCTranslatorTranslatorNIdentifierPrimary key, non-localized.internal token for translatorPatchAttributesN032767Integer containing bit flags representing patch attributesPatchFile_NFile1IdentifierPrimary key, non-localized token, foreign key to File table, must match identifier in cabinet.PatchHeaderYBinaryBinary stream. The patch header, used for patch validation.PatchISBuildSourcePathYTextFull path to patch header.PatchPatchSizeN02147483647Size of patch in bytes (long integer).PatchSequenceN032767Primary key, sequence with respect to the media images; order must track cabinet order.PatchStreamRef_YIdentifierExternal key into the MsiPatchHeaders table specifying the row that contains the patch header stream.PatchPackageMedia_N032767Foreign key to DiskId column of Media table. Indicates the disk containing the patch package.PatchPackagePatchIdNGuidA unique string GUID representing this patch.ProgIdClass_YClass1GuidThe CLSID of an OLE factory corresponding to the ProgId.ProgIdDescriptionYTextLocalized description for the Program identifier.ProgIdISAttributesYThis is used to store Installshield custom properties of a component, like ExtractIcon, etc.ProgIdIconIndexY-3276732767Optional icon index.ProgIdIcon_YIcon1IdentifierOptional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key.ProgIdProgIdNTextThe Program Identifier. Primary key.ProgIdProgId_ParentYProgId1TextThe Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id.PropertyISCommentsYTextUser Comments.PropertyPropertyNIdentifierName of property, uppercase if settable by launcher or loader.PropertyValueYTextString value for property.PublishComponentAppDataYTextThis is localisable Application specific data that can be associated with a Qualified Component.PublishComponentComponentIdNGuidA string GUID that represents the component id that will be requested by the alien product.PublishComponentComponent_NComponent1IdentifierForeign key into the Component table.PublishComponentFeature_NFeature1IdentifierForeign key into the Feature table.PublishComponentQualifierNTextThis is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect.RadioButtonHeightN032767The height of the button.RadioButtonHelpYTextThe help strings used with the button. The text is optional.RadioButtonISControlIdYA number used to represent the control ID of the Control, Used in Dialog exportRadioButtonOrderN132767A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.RadioButtonPropertyNIdentifierA named property to be tied to this radio button. All the buttons tied to the same property become part of the same group.RadioButtonTextYTextThe visible title to be assigned to the radio button.RadioButtonValueNFormattedThe value string associated with this button. Selecting the button will set the associated property to this value.RadioButtonWidthN032767The width of the button.RadioButtonXN032767The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button.RadioButtonYN032767The vertical coordinate of the upper left corner of the bounding rectangle of the radio button.RegLocatorKeyNRegPathThe key for the registry value.RegLocatorNameYFormattedThe registry value name.RegLocatorRootN03The predefined root key for the registry value, one of rrkEnum.RegLocatorSignature_NSignature1IdentifierThe table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key.RegLocatorTypeY018An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation.RegistryComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the installing of the registry value.RegistryISAttributesYThis is used to store Installshield custom properties of a registry item. Currently the only one is Automatic.RegistryKeyNRegPathThe key for the registry value.RegistryNameYFormattedThe registry value name.RegistryRegistryNIdentifierPrimary key, non-localized token.RegistryRootN-13The predefined root key for the registry value, one of rrkEnum.RegistryValueYTextThe registry value.RemoveFileComponent_NComponent1IdentifierForeign key referencing Component that controls the file to be removed.RemoveFileDirPropertyNIdentifierName of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed.RemoveFileFileKeyNIdentifierPrimary key used to identify a particular file entryRemoveFileFileNameYTextName of the file to be removed.RemoveFileInstallModeN1;2;3Installation option, one of iimEnum.RemoveIniFileActionN2;4The type of modification to be made, one of iifEnum.RemoveIniFileComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the deletion of the .INI value.RemoveIniFileDirPropertyYIdentifierForeign key into the Directory table denoting the directory where the .INI file is.RemoveIniFileFileNameNTextThe .INI file name in which to delete the informationRemoveIniFileKeyNFormattedThe .INI file key below Section.RemoveIniFileRemoveIniFileNIdentifierPrimary key, non-localized token.RemoveIniFileSectionNFormattedThe .INI file Section.RemoveIniFileValueYFormattedThe value to be deleted. The value is required when Action is iifIniRemoveTagRemoveRegistryComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the deletion of the registry value.RemoveRegistryKeyNRegPathThe key for the registry value.RemoveRegistryNameYFormattedThe registry value name.RemoveRegistryRemoveRegistryNIdentifierPrimary key, non-localized token.RemoveRegistryRootN-13The predefined root key for the registry value, one of rrkEnumReserveCostComponent_NComponent1IdentifierReserve a specified amount of space if this component is to be installed.ReserveCostReserveFolderYIdentifierName of a property whose value is assumed to resolve to the full path to the destination directoryReserveCostReserveKeyNIdentifierPrimary key that uniquely identifies a particular ReserveCost recordReserveCostReserveLocalN02147483647Disk space to reserve if linked component is installed locally.ReserveCostReserveSourceN02147483647Disk space to reserve if linked component is installed to run from the source location.SFPCatalogCatalogYBinarySFP CatalogSFPCatalogDependencyYFormattedParent catalog - only used by SFPSFPCatalogSFPCatalogNFilenameFile name for the catalog.SelfRegCostY032767The cost of registering the module.SelfRegFile_NFile1IdentifierForeign key into the File table denoting the module that needs to be registered.ServiceControlArgumentsYFormattedArguments for the service. Separate by [~].ServiceControlComponent_NComponent1IdentifierRequired foreign key into the Component Table that controls the startup of the serviceServiceControlEventN0187Bit field: Install: 0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = DeleteServiceControlNameNFormattedName of a service. /, \, comma and space are invalidServiceControlServiceControlNIdentifierPrimary key, non-localized token.ServiceControlWaitY01Boolean for whether to wait for the service to fully startServiceInstallArgumentsYFormattedArguments to include in every start of the service, passed to WinMainServiceInstallComponent_NComponent1IdentifierRequired foreign key into the Component Table that controls the startup of the serviceServiceInstallDependenciesYFormattedOther services this depends on to start. Separate by [~], and end with [~][~]ServiceInstallDescriptionYTextDescription of service.ServiceInstallDisplayNameYFormattedExternal Name of the ServiceServiceInstallErrorControlN-21474836472147483647Severity of error if service fails to startServiceInstallLoadOrderGroupYFormattedLoadOrderGroupServiceInstallNameNFormattedInternal Name of the ServiceServiceInstallPasswordYFormattedpassword to run service with. (with StartName)ServiceInstallServiceInstallNIdentifierPrimary key, non-localized token.ServiceInstallServiceTypeN-21474836472147483647Type of the serviceServiceInstallStartNameYFormattedUser or object name to run service asServiceInstallStartTypeN04Type of the serviceShortcutArgumentsYFormattedThe command-line arguments for the shortcut.ShortcutComponent_NComponent1IdentifierForeign key into the Component table denoting the component whose selection gates the the shortcut creation/deletion.ShortcutDescriptionYTextThe description for the shortcut.ShortcutDescriptionResourceDLLYFormattedThis field contains a Formatted string value for the full path to the language neutral file that contains the MUI manifest.ShortcutDescriptionResourceIdY032767The description name index for the shortcut.ShortcutDirectory_NDirectory1IdentifierForeign key into the Directory table denoting the directory where the shortcut file is created.ShortcutDisplayResourceDLLYFormattedThis field contains a Formatted string value for the full path to the language neutral file that contains the MUI manifest.ShortcutDisplayResourceIdY032767The display name index for the shortcut.ShortcutHotkeyY032767The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte.ShortcutISAttributesYThis is used to store Installshield custom properties of a shortcut. Mainly used in pro project types.ShortcutISCommentsYTextAuthor’s comments on this Shortcut.ShortcutISShortcutNameYTextA non-unique name for the shortcut. Mainly used by pro pro project types.ShortcutIconIndexY-3276732767The icon index for the shortcut.ShortcutIcon_YIcon1IdentifierForeign key into the File table denoting the external icon file for the shortcut.ShortcutNameNTextThe name of the shortcut to be created.ShortcutShortcutNIdentifierPrimary key, non-localized token.ShortcutShowCmdY1;3;7The show command for the application window.The following values may be used.ShortcutTargetNShortcutThe shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to.ShortcutWkDirYIdentifierName of property defining location of working directory.SignatureFileNameNTextThe name of the file. This may contain a "short name|long name" pair.SignatureLanguagesYLanguageThe languages supported by the file.SignatureMaxDateY02147483647The maximum creation date of the file.SignatureMaxSizeY02147483647The maximum size of the file.SignatureMaxVersionYTextThe maximum version of the file.SignatureMinDateY02147483647The minimum creation date of the file.SignatureMinSizeY02147483647The minimum size of the file.SignatureMinVersionYTextThe minimum version of the file.SignatureSignatureNIdentifierThe table key. The Signature represents a unique file signature.TextStyleColorY016777215A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B).TextStyleFaceNameNTextA string indicating the name of the font used. Required. The string must be at most 31 characters long.TextStyleSizeN032767The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size.TextStyleStyleBitsY015A combination of style bits.TextStyleTextStyleNIdentifierName of the style. The primary key of this table. This name is embedded in the texts to indicate a style change.TypeLibComponent_NComponent1IdentifierRequired foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.TypeLibCostY02147483647The cost associated with the registration of the typelib. This column is currently optional.TypeLibDescriptionYText + TypeLibDirectory_YDirectory1IdentifierOptional. The foreign key into the Directory table denoting the path to the help file for the type library.TypeLibFeature_NFeature1IdentifierRequired foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational.TypeLibLanguageN032767The language of the library.TypeLibLibIDNGuidThe GUID that represents the library.TypeLibVersionY02147483647The version of the library. The major version is in the upper 8 bits of the short integer. The minor version is in the lower 8 bits.UITextKeyNIdentifierA unique key that identifies the particular string.UITextTextYTextThe localized version of the string.UpgradeActionPropertyNUpperCaseThe property to set when a product in this set is found.UpgradeAttributesN02147483647The attributes of this product set.UpgradeISDisplayNameYISUpgradeMsiItem1 + UpgradeLanguageYLanguageA comma-separated list of languages for either products in this set or products not in this set.UpgradeRemoveYFormattedThe list of features to remove when uninstalling a product from this set. The default is "ALL".UpgradeUpgradeCodeNGuidThe UpgradeCode GUID belonging to the products in this set.UpgradeVersionMaxYTextThe maximum ProductVersion of the products in this set. The set may or may not include products with this particular version.UpgradeVersionMinYTextThe minimum ProductVersion of the products in this set. The set may or may not include products with this particular version.VerbArgumentYFormattedOptional value for the command arguments.VerbCommandYFormattedThe command text.VerbExtension_NExtension1TextThe extension associated with the table row.VerbSequenceY032767Order within the verbs for a particular extension. Also used simply to specify the default verb.VerbVerbNTextThe verb for the command._ValidationCategoryY"Text";"Formatted";"Template";"Condition";"Guid";"Path";"Version";"Language";"Identifier";"Binary";"UpperCase";"LowerCase";"Filename";"Paths";"AnyPath";"WildCardFilename";"RegPath";"KeyFormatted";"CustomSource";"Property";"Cabinet";"Shortcut";"URL";"DefaultDir"String category_ValidationColumnNIdentifierName of column_ValidationDescriptionYTextDescription of column_ValidationKeyColumnY132Column to which foreign key connects_ValidationKeyTableYIdentifierFor foreign key, Name of table to which data must link_ValidationMaxValueY-21474836472147483647Maximum value allowed_ValidationMinValueY-21474836472147483647Minimum value allowed_ValidationNullableNY;N;@Whether the column is nullable_ValidationSetYTextSet of values that are permitted_ValidationTableNIdentifierName of table
+
diff --git a/dev-jkauttio/setup/sysdyn/Script Files/FeatureEvents.rul b/dev-jkauttio/setup/sysdyn/Script Files/FeatureEvents.rul new file mode 100644 index 00000000..457f517c --- /dev/null +++ b/dev-jkauttio/setup/sysdyn/Script Files/FeatureEvents.rul @@ -0,0 +1,46 @@ +//--------------------------------------------------------------------------- +// The Installed event is sent after the feature SysdynFeature +// is installed. +//--------------------------------------------------------------------------- +export prototype SysdynFeature_Installed(); +function SysdynFeature_Installed() + STRING szValue; + STRING szTitle; +begin + // This strips the file part from the input path. + // The last part is interpreted as file if it doesn't containt backslash. + // So this should set szValue to parent of workspace dir. + StrRemoveLastSlash(gszWorkspaceFolder); + ParsePath(szValue, gszWorkspaceFolder, PATH); + myCreateDirs(szValue); + if (AddFolderIcon(gszShortcutFolder, gszShortcutName, + gszShortcutCmd, + szValue, // Work dir. + gszShortcutIcon, // Icon path. + 0, // Icon ordinal. + "", // Shortcut key. + REPLACE) != 0) + then + szTitle = gszTitle; + SprintfBox(WARNING, gszTitle, "Failed to set %s shortcut.\n", gszShortcutFolder); + endif; + if (AddFolderIcon(DesktopFolder, gszShortcutName, + gszShortcutCmd, + szValue, // Work dir. + gszShortcutIcon, // Icon path. + 0, // Icon ordinal. + "", // Shortcut key. + REPLACE) != 0) + then + szTitle = gszTitle; + SprintfBox(WARNING, szTitle, "Failed to set desktop shortcut.\n"); + endif; +/* + if (myIsJava32JreInstalled() != 0) then + szValue = gszBinFolder ^ "jre_x" + gszArch + ".exe"; + if (LaunchAppAndWait(szValue, "/q", LAAW_OPTION_WAIT) < 0) then + MessageBox ("Unable to launch " + szValue + ".", SEVERE); + endif; + endif; +*/ +end; diff --git a/dev-jkauttio/setup/sysdyn/Script Files/Setup.Rul b/dev-jkauttio/setup/sysdyn/Script Files/Setup.Rul new file mode 100644 index 00000000..3605b92b --- /dev/null +++ b/dev-jkauttio/setup/sysdyn/Script Files/Setup.Rul @@ -0,0 +1,175 @@ +//=========================================================================== +// +// File Name: Setup.rul +// +// Description: Blank setup main script file +// +// Comments: Blank setup is an empty setup project. If you want to +// create a new project via. step-by step instructions use the +// Project Assistant. +// +//=========================================================================== + +// Included header files ---------------------------------------------------- +#include "ifx.h" +#include "my.rul" +// Note: In order to have your InstallScript function executed as a custom +// action by the Windows Installer, it must be prototyped as an +// entry-point function. + +// The keyword export identifies MyFunction() as an entry-point function. +// The argument it accepts must be a handle to the Installer database. + +/* export prototype MyFunction(HWND); */ + +//--------------------------------------------------------------------------- +// OnFirstUIBefore +// +// The OnFirstUIBefore event is called by the framework when the setup is +// running in first install mode. By default this event displays UI allowing +// the end user to specify installation parameters. +//--------------------------------------------------------------------------- +function OnFirstUIBefore() + NUMBER nResult, nSetupType, nvSize, nUser; + STRING szTitle, szMsg, szQuestion, szName, szCompany, szFile; + STRING szLicenseFile; + BOOL bCustom, bIgnore1, bIgnore2; + LIST listStartCopy; +begin + myInit(TRUE); + // TO DO: if you want to enable background, window title, and caption bar title + // SetTitle( @PRODUCT_NAME, 24, WHITE ); + // SetTitle( @PRODUCT_NAME, 0, BACKGROUNDCAPTION ); + // Enable( FULLWINDOWMODE ); + // Enable( BACKGROUND ); + // SetColor(BACKGROUND,RGB (0, 128, 128)); + //SdProductName("kraa"); + //Enable(STATUSBBRD); + + // Added in InstallShield 15 - Show an appropriate error message if + // -removeonly is specified and the product is not installed. + if( REMOVEONLY ) then + Disable( DIALOGCACHE ); + szMsg = SdLoadString( IDS_IFX_ERROR_PRODUCT_NOT_INSTALLED_UNINST ); + SdSubstituteProductInfo( szMsg ); + MessageBox( szMsg, SEVERE ); + abort; + endif; + + nSetupType = TYPICAL; + +Dlg_SdWelcome: + szTitle = gszTitle; + szMsg = ""; + nResult = SdWelcome(szTitle, szMsg); + if (nResult = BACK) goto Dlg_SdWelcome; +#ifdef obsolete +Dlg_SdRegisterUser: + szMsg = ""; + szTitle = gszTitle; + szCompany = ""; + szName = ""; + //Call the SdCustomerInformation dialog function, which will + //set the value of ALLUSERS based on the selection made by the end-user. + //If the user selects the first radio button (all users), ALLUSERS + //will be set to TRUE. If the user selects the second radio button + //(only me), ALLUSERS will be set to FALSE. + nResult = SdCustomerInformation (szTitle, szName, szCompany, nUser); + if (nResult = BACK) goto Dlg_SdWelcome; +#endif +Dlg_SetupType: + szTitle = gszTitle; + szMsg = ""; + nResult = SetupType2(szTitle, szMsg, "", nSetupType, 0); + if (nResult = BACK) then + goto Dlg_SdWelcome; + else + nSetupType = nResult; + if (nSetupType != CUSTOM) then + nvSize = 0; + FeatureCompareSizeRequired(MEDIA, gszTargetFolder, nvSize); + if (nvSize != 0) then + MessageBox(szSdStr_NotEnoughSpace, WARNING); + goto Dlg_SetupType; + endif; + bCustom = FALSE; + goto Dlg_SdStartCopy; + else + bCustom = TRUE; + endif; + endif; + +Dlg_SdAskDestPath: + szTitle = "Select Installation Folder\n" + + "Please select a installation folder."; + szMsg = "Setup will install application files to installation directory."; + nResult = myAskFolderPath(szTitle, szMsg, gszTargetFolder); + if (StrFind(gszTargetFolder, " ") > -1) then + MessageBox("Install path can not contain spaces.", WARNING); + goto Dlg_SdAskDestPath; + endif; + myInitDeps(); + if (nResult = BACK) goto Dlg_SetupType; + // SdAskDestPath does not change path if user chooses back. +#ifdef obsolete +Dlg_SdFeatureTree: + szTitle = gszTitle; + szMsg = ""; + nResult = SdFeatureTree(szTitle, szMsg, gszTargetFolder, "", 2); + if (nResult = BACK) goto Dlg_SdAskDestPath; +#endif +Dlg_SdSelectFolder: + szTitle = gszTitle; + szMsg = ""; + nResult = SdSelectFolder(szTitle, szMsg, gszShortcutFolder); + if (nResult = BACK) goto Dlg_SdAskDestPath; + +Dlg_WorkDirectory: + szTitle = "Select Workspace Folder\n" + + "Please select a workspace folder."; + szMsg = "Setup will configure selected folder to be used as the default\n" + + "workspace folder."; + nResult = myAskFolderPath(szTitle, szMsg, gszWorkspaceFolder); + myInitDeps(); + if (nResult = BACK) goto Dlg_SdSelectFolder; + // SdAskDestPath does not change path if user chooses back. + +Dlg_SdStartCopy: + // Create list of end user selections to be displayed by SdStartCopy. + listStartCopy = ListCreate(STRINGLIST); + nResult = myListSelectedFeatures(listStartCopy); + /* + if (0 = nResult) then + MessageBox("No features selected.", SEVERE); + goto Dlg_SdWelcome; + endif; + */ + szTitle = gszTitle; + szMsg = ""; + nResult = SdStartCopy(szTitle, szMsg, listStartCopy); + ListDestroy(listStartCopy); + if (nResult = BACK) then + if (bCustom) then + goto Dlg_WorkDirectory; + else + goto Dlg_SetupType; + endif; + endif; + if (myFiniBeforeCopy() != 0) then + if (bCustom) then + goto Dlg_WorkDirectory; + else + goto Dlg_SetupType; + endif; + endif; + + // Added in IS 2009 - Set appropriate StatusEx static text. + SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_FIRSTUI ) ); + + // setup default status + Enable(STATUSEX); + + return 0; +end; + +#include "FeatureEvents.rul" diff --git a/dev-jkauttio/setup/sysdyn/Script Files/my.rul b/dev-jkauttio/setup/sysdyn/Script Files/my.rul new file mode 100644 index 00000000..8038cd0b --- /dev/null +++ b/dev-jkauttio/setup/sysdyn/Script Files/my.rul @@ -0,0 +1,173 @@ +#define SIMANTICS "Simantics" + +#ifdef sysdyn +#define PRODUCT "Sysdyn" +#define NO_SPACE_IN_BIN_PATH 1 +#define SHORTCUT_ICON "puzzle_green.ico" +#endif + +#ifndef PRODUCT +#define PRODUCT "" +#define NO_SPACE_IN_BIN_PATH 0 +#define SHORTCUT_ICON "" +#endif + +// Global variables + +string gszArch; // 32 or 64 depending on configuration +string gszTargetFolder; // Folder for program files. +string gszShortcutFolder; // Folder for shortcuts. +string gszShortcutName; +string gszShortcutCmd; +string gszShortcutIcon; +string gszWorkspaceFolder; // Folder for default workspace. +string gszBinFolder; // Folder for binaries. +string gszPathPart; // Prefix/infix/postfix folder path. +string gszTitle; // Title for dialogs. + +// Return 0 if ok. +prototype number myCreateDirs(STRING); +function number myCreateDirs(szPath) + number nReturn; +begin + if (ExistsDir(szPath) == EXISTS) then + return 0; + endif; + nReturn = CreateDir(szPath); + if (nReturn < 0) then + SprintfBox(WARNING, "Unable to create directory %s.", szPath); + endif; + return nReturn; +end; +/* +prototype NUMBER myIsJava32JreInstalled(); +function myIsJava32JreInstalled() + NUMBER nReturn; + NUMBER nvType, nvSize; + STRING svValue; +begin + RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE); + if RegDBGetKeyValueEx("SOFTWARE\\JavaSoft\\Java Runtime Environment\\1.6", "JavaHome", nvType, svValue, nvSize) = 0 then + nReturn = 0; + else + nReturn = -1; + endif; + return nReturn; +end; +*/ +prototype number myAskFolderPath(STRING, STRING, byref STRING); +function number myAskFolderPath(szTitle, szMsg, svFolder) + number nResult; + string def; +begin + def = svFolder; + SetDialogTitle(DLG_ASK_PATH, szTitle); + nResult = AskPath(szMsg, def, svFolder); + return nResult; +end; + +prototype string myTargetFolder(STRING, STRING); +function string myTargetFolder(szBin32, szBin64) +begin + if (gszArch = "64") then + gszTargetFolder = szBin64; + else + gszTargetFolder = szBin32; + endif; + return gszTargetFolder; +end; + +prototype myInitDeps(); +function myInitDeps() + string szExe; +begin + gszBinFolder = gszTargetFolder; + if (SHORTCUT_ICON = "") then + gszShortcutIcon = ""; + else + gszShortcutIcon = gszBinFolder ^ SHORTCUT_ICON; + endif; + szExe = "\"" + gszBinFolder ^ SIMANTICS + "-" + PRODUCT + "\""; + gszShortcutCmd = szExe + " -defaultWorkspaceLocation \"" + gszWorkspaceFolder + "\""; + TARGETDIR = gszTargetFolder; + INSTALLDIR = gszTargetFolder; + SHELL_OBJECT_FOLDER = gszShortcutFolder; +end; + +prototype number myFiniBeforeCopy(); +function number myFiniBeforeCopy() +begin + if (0 != myCreateDirs(gszTargetFolder)) then + return 1; + endif; + if (0 != myCreateDirs(gszWorkspaceFolder)) then + return 1; + endif; + return 0; +end; + +prototype myInit(BOOL); +function myInit(bFirst) + string szProgramFolder, szProgram32Folder, szProgram64Folder; + string szIsData, szVersion, szBuild; +begin +#ifdef x64 + gszArch = "64"; +#else + gszArch = "32"; +#endif + if (Is(USER_ADMINISTRATOR , szIsData) = FALSE) then + if (bFirst) then + ALLUSERS = 0; + endif; + endif; + ParsePath(szVersion, IFX_PRODUCT_VERSION, FILENAME_ONLY); + ParsePath(szBuild, IFX_PRODUCT_VERSION, EXTENSION_ONLY); + gszShortcutName = SIMANTICS + "-" +szVersion + "-" + PRODUCT + "-" + gszArch; + gszTitle = gszShortcutName + "-Build-" + szBuild; + gszPathPart = SIMANTICS ^ gszShortcutName; + if (gszTargetFolder = "") then + if (NO_SPACE_IN_BIN_PATH) then + szProgramFolder = TARGETDISK ^ gszPathPart ^ "bin"; + gszTargetFolder = myTargetFolder(szProgramFolder, szProgramFolder); + elseif (ALLUSERS) then + szProgram32Folder = PROGRAMFILES ^ gszPathPart; + szProgram64Folder = PROGRAMFILES64 ^ gszPathPart; + gszTargetFolder = myTargetFolder(szProgram32Folder, szProgram64Folder); + else + szProgramFolder = FOLDER_APPDATA ^ gszPathPart; + gszTargetFolder = myTargetFolder(szProgramFolder, szProgramFolder); + endif; + endif; + if (gszShortcutFolder = "") then + gszShortcutFolder = gszPathPart; + endif; + if (gszWorkspaceFolder = "") then + gszWorkspaceFolder = TARGETDISK ^ gszPathPart ^ "workspace"; + endif; + myInitDeps(); +end; + +prototype number myListSelectedFeatures(LIST); +function myListSelectedFeatures(listStartCopy) + string svFeatureSource, svFeature, svComponent, svFile; + STRING szMsg; + NUMBER nvResult; +begin + szMsg = "Installing files to " + gszTargetFolder + "."; + ListAddString (listStartCopy, szMsg, AFTER); + szMsg = "Adding shortcuts to " + gszShortcutFolder + "."; + ListAddString (listStartCopy, szMsg, AFTER); + szMsg = "Default workspace set to " + gszWorkspaceFolder + "."; + ListAddString (listStartCopy, szMsg, AFTER); + return 1; +/* + nvResult = 0; + ListAddString (listStartCopy, "Installing following components:", AFTER); + if (FeatureIsItemSelected (MEDIA, LICENSE_COMPONENT) = TRUE) then + ListAddString (listStartCopy, LICENSE_COMPONENT, AFTER); + nvResult += 1; + endif; + return nvResult; +*/ +end; diff --git a/dev-jkauttio/setup/sysdyn/String1033.txt b/dev-jkauttio/setup/sysdyn/String1033.txt new file mode 100644 index 00000000..7fc2fb31 Binary files /dev/null and b/dev-jkauttio/setup/sysdyn/String1033.txt differ diff --git a/dev-jkauttio/sysdyn_ontologies/.hgignore b/dev-jkauttio/sysdyn_ontologies/.hgignore new file mode 100644 index 00000000..93c8bfa6 --- /dev/null +++ b/dev-jkauttio/sysdyn_ontologies/.hgignore @@ -0,0 +1,9 @@ +syntax: regexp +^org/ +^c_sharp/ +^layer0c.bin +^layer0c.txt +^directories.log + +syntax: glob +*.svn/* \ No newline at end of file diff --git a/dev-jkauttio/sysdyn_ontologies/.project b/dev-jkauttio/sysdyn_ontologies/.project new file mode 100644 index 00000000..56d3ddcb --- /dev/null +++ b/dev-jkauttio/sysdyn_ontologies/.project @@ -0,0 +1,11 @@ + + + sysdyn_ontologies + + + + + + + + diff --git a/dev-jkauttio/sysdyn_ontologies/dependencies.txt b/dev-jkauttio/sysdyn_ontologies/dependencies.txt new file mode 100644 index 00000000..37576309 --- /dev/null +++ b/dev-jkauttio/sysdyn_ontologies/dependencies.txt @@ -0,0 +1,3 @@ +../foundation_ontologies +../2d_ontologies +../modeling_ontologies diff --git a/dev-jkauttio/sysdyn_ontologies/generate_sysdyn.bat b/dev-jkauttio/sysdyn_ontologies/generate_sysdyn.bat new file mode 100644 index 00000000..a4127347 --- /dev/null +++ b/dev-jkauttio/sysdyn_ontologies/generate_sysdyn.bat @@ -0,0 +1,13 @@ +@rem *************************************************************************** +@rem Copyright (c) 2007, 2010 Association for Decentralized Information Management +@rem in Industry THTH ry. +@rem All rights reserved. This program and the accompanying materials +@rem are made available under the terms of the Eclipse Public License v1.0 +@rem which accompanies this distribution, and is available at +@rem http://www.eclipse.org/legal/epl-v10.html +@rem +@rem Contributors: +@rem VTT Technical Research Centre of Finland - initial API and implementation +@rem *************************************************************************** +@echo off +call "%~dp0..\org.simantics.db.build\build" "%~dp0" ..\foundation_ontologies\foundation.graph ..\sysdyn_ontologies\sysdyn.graph ..\modeling_ontologies\modeling.graph ..\modeling_ontologies\devs.graph ..\webmon_ontologies\webmon.graph ..\modeling_ontologies\spreadsheet.graph \ No newline at end of file diff --git a/dev-jkauttio/sysdyn_ontologies/install.map b/dev-jkauttio/sysdyn_ontologies/install.map new file mode 100644 index 00000000..a3fbef17 --- /dev/null +++ b/dev-jkauttio/sysdyn_ontologies/install.map @@ -0,0 +1 @@ +copy=org/simantics/sysdyn=../org.simantics.sysdyn/src diff --git a/dev-jkauttio/sysdyn_ontologies/sysdyn.graph b/dev-jkauttio/sysdyn_ontologies/sysdyn.graph new file mode 100644 index 00000000..e4492db7 --- /dev/null +++ b/dev-jkauttio/sysdyn_ontologies/sysdyn.graph @@ -0,0 +1,1733 @@ +%import "layer0.graph" L0 +%import "diagram2.graph" DIA +%import "g2d.graph" G2D +%import "structural2.graph" ST +%import "modeling.graph" MOD +%import "project.graph" PROJ +%import "simulation.graph" SIMU +%import "workbench.graph" WORKBENCH + +%deflib L0.Type Sysdyn +%deflib L0.Relation Sysdyn +%deflib DIA.ElementClass Symbols + +%define assert($pred,$obj) + $subject + L0.Asserts _ : L0.Assertion + L0.HasPredicate $pred + L0.HasObject $obj + +%define tag($pred) + $subject + $pred $subject + +%define symmetric() + $subject + $layer0.InverseOf $subject + +%define defSymbol($label, $componentType) + $subject